From a8620d65d8ef80e77c30933c0598f972e6cf34c5 Mon Sep 17 00:00:00 2001 From: Bram Borggreve Date: Mon, 11 Mar 2024 06:37:12 +0000 Subject: [PATCH 01/12] feat: add shared data service in api crud generator --- .../data-access/src/lib/dto/paging.input.ts | 5 + .../api-crud-generator.spec.ts.snap | 79 ++++++++--- .../api-feature-generator.spec.ts.snap | 132 ++++++++++++------ .../api-feature/api-feature-generator.spec.ts | 1 + ...data-__actorFileName__.service.ts.template | 21 ++- ...__modelFileName__-data.service.ts.template | 37 +++++ .../src/lib/api-crud/generate-api-crud.ts | 29 +++- 7 files changed, 229 insertions(+), 75 deletions(-) create mode 100644 libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data.service.ts.template diff --git a/libs/api/core/data-access/src/lib/dto/paging.input.ts b/libs/api/core/data-access/src/lib/dto/paging.input.ts index df1dc24..23a8ab4 100644 --- a/libs/api/core/data-access/src/lib/dto/paging.input.ts +++ b/libs/api/core/data-access/src/lib/dto/paging.input.ts @@ -11,3 +11,8 @@ export function PagingInput() { return PagingInputClass } + +export interface PagingInputFields { + page?: number + limit?: number +} diff --git a/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap b/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap index fc41f5d..d389fd1 100644 --- a/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap +++ b/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap @@ -207,39 +207,77 @@ exports[`api-crud generator should run successfully 1`] = ` "test-company-data-admin.service.ts": { "content": [ "import { Injectable } from '@nestjs/common';", - "import { TestCoreService } from '@proj/test-core-data-access';", "import { AdminCreateCompanyInput } from './dto/admin-create-company.input';", "import { AdminFindManyCompanyInput } from './dto/admin-find-many-company.input';", "import { AdminUpdateCompanyInput } from './dto/admin-update-company.input';", "import { CompanyPaging } from './entity/company.entity';", "import { getCompanyWhereAdminInput } from './helpers/get-company-where-admin.input';", + "import { TestCompanyDataService } from './test-company-data.service';", "@Injectable()", "export class TestCompanyDataAdminService {", - "constructor(private readonly core: TestCoreService) {}", + "constructor(private readonly data: TestCompanyDataService) {}", "async createCompany(input: AdminCreateCompanyInput) {", - "return this.core.data.company.create({ data: input });", + "return this.data.create(input);", "}", "async deleteCompany(companyId: string) {", - "const deleted = await this.core.data.company.delete({", - "where: { id: companyId },", - "});", - "return !!deleted;", + "return this.data.delete(companyId);", "}", "async findManyCompany(", "input: AdminFindManyCompanyInput", "): Promise {", - "return this.core.data.company", - ".paginate({", + "return this.data.findMany({", "orderBy: { createdAt: 'desc' },", "where: getCompanyWhereAdminInput(input),", - "})", - ".withPages({ limit: input.limit, page: input.page })", - ".then(([data, meta]) => ({ data, meta }));", + "limit: input.limit,", + "page: input.page,", + "});", "}", "async findOneCompany(companyId: string) {", - "return this.core.data.company.findUnique({ where: { id: companyId } });", + "return this.data.findOne(companyId);", "}", "async updateCompany(companyId: string, input: AdminUpdateCompanyInput) {", + "return this.data.update(companyId, input);", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/test-company-data-admin.service.ts", + }, + "test-company-data.service.ts": { + "content": [ + "import { Injectable } from '@nestjs/common';", + "import { Prisma } from '@prisma/client';", + "import {", + "TestCoreService,", + "type PagingInputFields,", + "} from '@proj/test-core-data-access';", + "import { CompanyPaging } from './entity/company.entity';", + "@Injectable()", + "export class TestCompanyDataService {", + "constructor(private readonly core: TestCoreService) {}", + "async create(input: Prisma.CompanyCreateInput) {", + "return this.core.data.company.create({ data: input });", + "}", + "async delete(companyId: string) {", + "const deleted = await this.core.data.company.delete({", + "where: { id: companyId },", + "});", + "return !!deleted;", + "}", + "async findMany({", + "limit = 10,", + "page = 1,", + "...input", + "}: Prisma.CompanyFindManyArgs & PagingInputFields): Promise {", + "return this.core.data.company", + ".paginate(input)", + ".withPages({ limit, page })", + ".then(([data, meta]) => ({ data, meta }));", + "}", + "async findOne(companyId: string) {", + "return this.core.data.company.findUnique({ where: { id: companyId } });", + "}", + "async update(companyId: string, input: Prisma.CompanyUpdateInput) {", "return this.core.data.company.update({", "where: { id: companyId },", "data: input,", @@ -248,17 +286,22 @@ exports[`api-crud generator should run successfully 1`] = ` "}", ], "isBinary": false, - "path": "libs/test/company/data-access/src/lib/test-company-data-admin.service.ts", + "path": "libs/test/company/data-access/src/lib/test-company-data.service.ts", }, "test-company.data-access.module.ts": { "content": [ "import { Module } from '@nestjs/common';", "import { TestCoreDataAccessModule } from '@proj/test-core-data-access';", "import { TestCompanyService } from './test-company.service';", + "import { TestCompanyDataService } from './test-company-data.service';", "import { TestCompanyDataAdminService } from './test-company-data-admin.service';", "@Module({", "imports: [TestCoreDataAccessModule],", - "providers: [TestCompanyService, TestCompanyDataAdminService],", + "providers: [", + "TestCompanyService,", + "TestCompanyDataService,", + "TestCompanyDataAdminService,", + "],", "exports: [TestCompanyService],", "})", "export class TestCompanyDataAccessModule {}", @@ -269,10 +312,14 @@ exports[`api-crud generator should run successfully 1`] = ` "test-company.service.ts": { "content": [ "import { Injectable } from '@nestjs/common';", + "import { TestCompanyDataService } from './test-company-data.service';", "import { TestCompanyDataAdminService } from './test-company-data-admin.service';", "@Injectable()", "export class TestCompanyService {", - "constructor(readonly admin: TestCompanyDataAdminService) {}", + "constructor(", + "readonly data: TestCompanyDataService,", + "readonly admin: TestCompanyDataAdminService", + ") {}", "}", ], "isBinary": false, diff --git a/libs/tools/src/generators/api-feature/__snapshots__/api-feature-generator.spec.ts.snap b/libs/tools/src/generators/api-feature/__snapshots__/api-feature-generator.spec.ts.snap index d0bba75..b8bb512 100644 --- a/libs/tools/src/generators/api-feature/__snapshots__/api-feature-generator.spec.ts.snap +++ b/libs/tools/src/generators/api-feature/__snapshots__/api-feature-generator.spec.ts.snap @@ -15,42 +15,40 @@ export * from './lib/dto/user-update-test.input'; exports[`api-feature generator should generate the feature libraries with crud for admin and user 4`] = ` "import { Injectable } from '@nestjs/common'; -import { ApiCoreService } from '@proj/api-core-data-access'; import { AdminCreateTestInput } from './dto/admin-create-test.input'; import { AdminFindManyTestInput } from './dto/admin-find-many-test.input'; import { AdminUpdateTestInput } from './dto/admin-update-test.input'; import { TestPaging } from './entity/test.entity'; import { getTestWhereAdminInput } from './helpers/get-test-where-admin.input'; +import { ApiTestDataService } from './api-test-data.service'; @Injectable() export class ApiTestDataAdminService { - constructor(private readonly core: ApiCoreService) {} + constructor(private readonly data: ApiTestDataService) {} async createTest(input: AdminCreateTestInput) { - return this.core.data.test.create({ data: input }); + return this.data.create(input); } async deleteTest(testId: string) { - const deleted = await this.core.data.test.delete({ where: { id: testId } }); - return !!deleted; + return this.data.delete(testId); } async findManyTest(input: AdminFindManyTestInput): Promise { - return this.core.data.test - .paginate({ - orderBy: { createdAt: 'desc' }, - where: getTestWhereAdminInput(input), - }) - .withPages({ limit: input.limit, page: input.page }) - .then(([data, meta]) => ({ data, meta })); + return this.data.findMany({ + orderBy: { createdAt: 'desc' }, + where: getTestWhereAdminInput(input), + limit: input.limit, + page: input.page, + }); } async findOneTest(testId: string) { - return this.core.data.test.findUnique({ where: { id: testId } }); + return this.data.findOne(testId); } async updateTest(testId: string, input: AdminUpdateTestInput) { - return this.core.data.test.update({ where: { id: testId }, data: input }); + return this.data.update(testId, input); } } " @@ -58,71 +56,121 @@ export class ApiTestDataAdminService { exports[`api-feature generator should generate the feature libraries with crud for admin and user 5`] = ` "import { Injectable } from '@nestjs/common'; -import { ApiCoreService } from '@proj/api-core-data-access'; import { UserCreateTestInput } from './dto/user-create-test.input'; import { UserFindManyTestInput } from './dto/user-find-many-test.input'; import { UserUpdateTestInput } from './dto/user-update-test.input'; import { TestPaging } from './entity/test.entity'; import { getTestWhereUserInput } from './helpers/get-test-where-user.input'; +import { ApiTestDataService } from './api-test-data.service'; @Injectable() export class ApiTestDataUserService { - constructor(private readonly core: ApiCoreService) {} + constructor(private readonly data: ApiTestDataService) {} async createTest(input: UserCreateTestInput) { - return this.core.data.test.create({ data: input }); + return this.data.create(input); } async deleteTest(testId: string) { + return this.data.delete(testId); + } + + async findManyTest(input: UserFindManyTestInput): Promise { + return this.data.findMany({ + orderBy: { createdAt: 'desc' }, + where: getTestWhereUserInput(input), + limit: input.limit, + page: input.page, + }); + } + + async findOneTest(testId: string) { + return this.data.findOne(testId); + } + + async updateTest(testId: string, input: UserUpdateTestInput) { + return this.data.update(testId, input); + } +} +" +`; + +exports[`api-feature generator should generate the feature libraries with crud for admin and user 6`] = ` +"import { Injectable } from '@nestjs/common'; +import { Prisma } from '@prisma/client'; +import { + ApiCoreService, + type PagingInputFields, +} from '@proj/api-core-data-access'; +import { TestPaging } from './entity/test.entity'; + +@Injectable() +export class ApiTestDataService { + constructor(private readonly core: ApiCoreService) {} + + async create(input: Prisma.TestCreateInput) { + return this.core.data.test.create({ data: input }); + } + + async delete(testId: string) { const deleted = await this.core.data.test.delete({ where: { id: testId } }); return !!deleted; } - async findManyTest(input: UserFindManyTestInput): Promise { + async findMany({ + limit = 10, + page = 1, + ...input + }: Prisma.TestFindManyArgs & PagingInputFields): Promise { return this.core.data.test - .paginate({ - orderBy: { createdAt: 'desc' }, - where: getTestWhereUserInput(input), - }) - .withPages({ limit: input.limit, page: input.page }) + .paginate(input) + .withPages({ limit, page }) .then(([data, meta]) => ({ data, meta })); } - async findOneTest(testId: string) { + async findOne(testId: string) { return this.core.data.test.findUnique({ where: { id: testId } }); } - async updateTest(testId: string, input: UserUpdateTestInput) { + async update(testId: string, input: Prisma.TestUpdateInput) { return this.core.data.test.update({ where: { id: testId }, data: input }); } } " `; -exports[`api-feature generator should generate the feature libraries with crud for admin and user 6`] = ` +exports[`api-feature generator should generate the feature libraries with crud for admin and user 7`] = ` "import { Module } from '@nestjs/common'; import { ApiCoreDataAccessModule } from '@proj/api-core-data-access'; import { ApiTestService } from './api-test.service'; +import { ApiTestDataService } from './api-test-data.service'; import { ApiTestDataAdminService } from './api-test-data-admin.service'; import { ApiTestDataUserService } from './api-test-data-user.service'; @Module({ imports: [ApiCoreDataAccessModule], - providers: [ApiTestService, ApiTestDataAdminService, ApiTestDataUserService], + providers: [ + ApiTestService, + ApiTestDataService, + ApiTestDataAdminService, + ApiTestDataUserService, + ], exports: [ApiTestService], }) export class ApiTestDataAccessModule {} " `; -exports[`api-feature generator should generate the feature libraries with crud for admin and user 7`] = ` +exports[`api-feature generator should generate the feature libraries with crud for admin and user 8`] = ` "import { Injectable } from '@nestjs/common'; +import { ApiTestDataService } from './api-test-data.service'; import { ApiTestDataAdminService } from './api-test-data-admin.service'; import { ApiTestDataUserService } from './api-test-data-user.service'; @Injectable() export class ApiTestService { constructor( + readonly data: ApiTestDataService, readonly admin: ApiTestDataAdminService, readonly user: ApiTestDataUserService ) {} @@ -130,7 +178,7 @@ export class ApiTestService { " `; -exports[`api-feature generator should generate the feature libraries with crud for admin and user 8`] = ` +exports[`api-feature generator should generate the feature libraries with crud for admin and user 9`] = ` "import { Field, InputType } from '@nestjs/graphql'; @InputType() @@ -141,7 +189,7 @@ export class AdminCreateTestInput { " `; -exports[`api-feature generator should generate the feature libraries with crud for admin and user 9`] = ` +exports[`api-feature generator should generate the feature libraries with crud for admin and user 10`] = ` "import { Field, InputType } from '@nestjs/graphql'; import { PagingInput } from '@proj/api-core-data-access'; @@ -153,7 +201,7 @@ export class AdminFindManyTestInput extends PagingInput() { " `; -exports[`api-feature generator should generate the feature libraries with crud for admin and user 10`] = ` +exports[`api-feature generator should generate the feature libraries with crud for admin and user 11`] = ` "import { Field, InputType } from '@nestjs/graphql'; @InputType() @@ -164,7 +212,7 @@ export class AdminUpdateTestInput { " `; -exports[`api-feature generator should generate the feature libraries with crud for admin and user 11`] = ` +exports[`api-feature generator should generate the feature libraries with crud for admin and user 12`] = ` "import { Field, InputType } from '@nestjs/graphql'; @InputType() @@ -175,7 +223,7 @@ export class UserCreateTestInput { " `; -exports[`api-feature generator should generate the feature libraries with crud for admin and user 12`] = ` +exports[`api-feature generator should generate the feature libraries with crud for admin and user 13`] = ` "import { Field, InputType } from '@nestjs/graphql'; import { PagingInput } from '@proj/api-core-data-access'; @@ -187,7 +235,7 @@ export class UserFindManyTestInput extends PagingInput() { " `; -exports[`api-feature generator should generate the feature libraries with crud for admin and user 13`] = ` +exports[`api-feature generator should generate the feature libraries with crud for admin and user 14`] = ` "import { Field, InputType } from '@nestjs/graphql'; @InputType() @@ -198,7 +246,7 @@ export class UserUpdateTestInput { " `; -exports[`api-feature generator should generate the feature libraries with crud for admin and user 14`] = ` +exports[`api-feature generator should generate the feature libraries with crud for admin and user 15`] = ` "import { Field, ObjectType } from '@nestjs/graphql'; import { PagingResponse } from '@proj/api-core-data-access'; @@ -220,7 +268,7 @@ export class TestPaging extends PagingResponse(Test) {} " `; -exports[`api-feature generator should generate the feature libraries with crud for admin and user 15`] = ` +exports[`api-feature generator should generate the feature libraries with crud for admin and user 16`] = ` "import { Prisma } from '@prisma/client'; import { AdminFindManyTestInput } from '../dto/admin-find-many-test.input'; @@ -241,7 +289,7 @@ export function getTestWhereAdminInput( " `; -exports[`api-feature generator should generate the feature libraries with crud for admin and user 16`] = ` +exports[`api-feature generator should generate the feature libraries with crud for admin and user 17`] = ` "import { Prisma } from '@prisma/client'; import { UserFindManyTestInput } from '../dto/user-find-many-test.input'; @@ -262,12 +310,12 @@ export function getTestWhereUserInput( " `; -exports[`api-feature generator should generate the feature libraries with crud for admin and user 17`] = ` +exports[`api-feature generator should generate the feature libraries with crud for admin and user 18`] = ` "export * from './lib/api-test.feature.module'; " `; -exports[`api-feature generator should generate the feature libraries with crud for admin and user 18`] = ` +exports[`api-feature generator should generate the feature libraries with crud for admin and user 19`] = ` "import { Resolver } from '@nestjs/graphql'; import { ApiTestService } from '@proj/api-test-data-access'; import { ApiAuthGraphQLAdminGuard } from '@proj/api-auth-data-access'; @@ -317,7 +365,7 @@ export class ApiTestAdminResolver { " `; -exports[`api-feature generator should generate the feature libraries with crud for admin and user 19`] = ` +exports[`api-feature generator should generate the feature libraries with crud for admin and user 20`] = ` "import { Resolver } from '@nestjs/graphql'; import { ApiTestService } from '@proj/api-test-data-access'; import { ApiAuthGraphQLUserGuard } from '@proj/api-auth-data-access'; @@ -367,7 +415,7 @@ export class ApiTestUserResolver { " `; -exports[`api-feature generator should generate the feature libraries with crud for admin and user 20`] = ` +exports[`api-feature generator should generate the feature libraries with crud for admin and user 21`] = ` "import { Module } from '@nestjs/common'; import { ApiTestDataAccessModule } from '@proj/api-test-data-access'; import { ApiTestResolver } from './api-test.resolver'; @@ -382,7 +430,7 @@ export class ApiTestFeatureModule {} " `; -exports[`api-feature generator should generate the feature libraries with crud for admin and user 21`] = ` +exports[`api-feature generator should generate the feature libraries with crud for admin and user 22`] = ` "import { Resolver } from '@nestjs/graphql'; import { ApiTestService } from '@proj/api-test-data-access'; import { Test } from '@proj/api-test-data-access'; diff --git a/libs/tools/src/generators/api-feature/api-feature-generator.spec.ts b/libs/tools/src/generators/api-feature/api-feature-generator.spec.ts index 2e1fb00..0b91582 100644 --- a/libs/tools/src/generators/api-feature/api-feature-generator.spec.ts +++ b/libs/tools/src/generators/api-feature/api-feature-generator.spec.ts @@ -79,6 +79,7 @@ describe('api-feature generator', () => { "libs/api/test/data-access/src/index.ts", "libs/api/test/data-access/src/lib/api-test-data-admin.service.ts", "libs/api/test/data-access/src/lib/api-test-data-user.service.ts", + "libs/api/test/data-access/src/lib/api-test-data.service.ts", "libs/api/test/data-access/src/lib/api-test.data-access.module.ts", "libs/api/test/data-access/src/lib/api-test.service.ts", "libs/api/test/data-access/src/lib/dto/admin-create-test.input.ts", diff --git a/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data-__actorFileName__.service.ts.template b/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data-__actorFileName__.service.ts.template index 1e0bfa5..af52c11 100644 --- a/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data-__actorFileName__.service.ts.template +++ b/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data-__actorFileName__.service.ts.template @@ -1,39 +1,38 @@ import { Injectable } from '@nestjs/common' -import { <%= app.className %>CoreService } from '@<%= npmScope %>/<%= app.fileName %>-core-data-access' import { <%= actor.className %>Create<%= model.className %>Input } from './dto/<%= actor.fileName %>-create-<%= model.fileName %>.input' import { <%= actor.className %>FindMany<%= model.className %>Input } from './dto/<%= actor.fileName %>-find-many-<%= model.fileName %>.input' import { <%= actor.className %>Update<%= model.className %>Input } from './dto/<%= actor.fileName %>-update-<%= model.fileName %>.input' import { <%= model.className %>Paging } from './entity/<%= model.fileName %>.entity' import { get<%= model.className %>Where<%= actor.className %>Input } from './helpers/get-<%= model.fileName %>-where-<%= actor.fileName %>.input' +import { <%= app.className %><%= model.className %>DataService } from './<%= app.fileName %>-<%= model.fileName %>-data.service' + @Injectable() export class <%= app.className %><%= model.className %>Data<%= actor.className %>Service { - constructor(private readonly core: <%= app.className %>CoreService) {} + constructor(private readonly data: <%= app.className %><%= model.className %>DataService) {} async create<%= model.className %>(input: <%= actor.className %>Create<%= model.className %>Input) { - return this.core.data.<%= model.propertyName %>.create({ data: input }) + return this.data.create(input) } async delete<%= model.className %>(<%= model.propertyName %>Id: string) { - const deleted = await this.core.data.<%= model.propertyName %>.delete({ where: { id: <%= model.propertyName %>Id } }) - return !!deleted + return this.data.delete(<%= model.propertyName %>Id) } async findMany<%= model.className %>(input: <%= actor.className %>FindMany<%= model.className %>Input): Promise<<%= model.className %>Paging> { - return this.core.data.<%= model.propertyName %> - .paginate({ + return this.data.findMany({ orderBy: { createdAt: 'desc' }, where: get<%= model.className %>Where<%= actor.className %>Input(input), + limit: input.limit, + page: input.page }) - .withPages({ limit: input.limit, page: input.page }) - .then(([data, meta]) => ({ data, meta })) } async findOne<%= model.className %>(<%= model.propertyName %>Id: string) { - return this.core.data.<%= model.propertyName %>.findUnique({ where: { id: <%= model.propertyName %>Id } }) + return this.data.findOne(<%= model.propertyName %>Id) } async update<%= model.className %>(<%= model.propertyName %>Id: string, input: <%= actor.className %>Update<%= model.className %>Input) { - return this.core.data.<%= model.propertyName %>.update({ where: { id: <%= model.propertyName %>Id }, data: input }) + return this.data.update(<%= model.propertyName %>Id, input) } } diff --git a/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data.service.ts.template b/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data.service.ts.template new file mode 100644 index 0000000..537ccdc --- /dev/null +++ b/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data.service.ts.template @@ -0,0 +1,37 @@ +import { Injectable } from '@nestjs/common' +import { Prisma } from '@prisma/client' +import { <%= app.className %>CoreService, type PagingInputFields } from '@<%= npmScope %>/<%= app.fileName %>-core-data-access' +import { <%= model.className %>Paging } from './entity/<%= model.fileName %>.entity' + +@Injectable() +export class <%= app.className %><%= model.className %>DataService { + constructor(private readonly core: <%= app.className %>CoreService) {} + + async create(input: Prisma.<%= model.className %>CreateInput) { + return this.core.data.<%= model.propertyName %>.create({ data: input }) + } + + async delete(<%= model.propertyName %>Id: string) { + const deleted = await this.core.data.<%= model.propertyName %>.delete({ where: { id: <%= model.propertyName %>Id } }) + return !!deleted + } + + async findMany({ + limit = 10, + page = 1, + ...input + }: Prisma.<%= model.className %>FindManyArgs & PagingInputFields): Promise<<%= model.className %>Paging> { + return this.core.data.<%= model.propertyName %> + .paginate(input) + .withPages({ limit, page }) + .then(([data, meta]) => ({ data, meta })) + } + + async findOne(<%= model.propertyName %>Id: string) { + return this.core.data.<%= model.propertyName %>.findUnique({ where: { id: <%= model.propertyName %>Id } }) + } + + async update(<%= model.propertyName %>Id: string, input: Prisma.<%= model.className %>UpdateInput) { + return this.core.data.<%= model.propertyName %>.update({ where: { id: <%= model.propertyName %>Id }, data: input }) + } +} diff --git a/libs/tools/src/lib/api-crud/generate-api-crud.ts b/libs/tools/src/lib/api-crud/generate-api-crud.ts index 2926fcc..3fd8da6 100644 --- a/libs/tools/src/lib/api-crud/generate-api-crud.ts +++ b/libs/tools/src/lib/api-crud/generate-api-crud.ts @@ -14,8 +14,10 @@ export function generateApiCrud(tree: Tree, options: NormalizedApiCrudSchema) { ].map((project) => ensureNxProjectExists(tree, project)) const vars = getApiCrudSubstitutions(options) - const serviceName = `${vars.app.className}${vars.model.className}Data${vars.actor.className}Service` - const serviceFileName = `${vars.appFileName}-${vars.modelFileName}-data-${vars.actorFileName}.service.ts` + const serviceName = `${vars.app.className}${vars.model.className}DataService` + const serviceFileName = `${vars.appFileName}-${vars.modelFileName}-data.service.ts` + const serviceActorName = `${vars.app.className}${vars.model.className}Data${vars.actor.className}Service` + const serviceActorFileName = `${vars.appFileName}-${vars.modelFileName}-data-${vars.actorFileName}.service.ts` const resolverName = `${vars.app.className}${vars.model.className}${vars.actor.className}Resolver` const resolverFileName = `${vars.appFileName}-${vars.modelFileName}-${vars.actorFileName}.resolver.ts` @@ -49,17 +51,32 @@ export function generateApiCrud(tree: Tree, options: NormalizedApiCrudSchema) { // Generate the data access library generateFiles(tree, `${__dirname}/files/data-access`, dataAccess.sourceRoot, { ...vars }) - // Add the crud service to the service constructor + const currentFile = tree.read(dataAccessServicePath).toString() + // Add the crud services to the service constructor + console.log('serviceName', serviceName, currentFile, currentFile.includes(serviceName)) + if (!currentFile.includes(serviceName)) { + addServiceToClassConstructor( + tree, + dataAccessServicePath, + `${vars.app.className}${vars.model.className}Service`, + 'data', + serviceName, + serviceFileName, + ) + // Add the crud service to the module providers + addServiceToModuleDecorator(tree, dataAccessModulePath, serviceName, serviceFileName) + } + addServiceToClassConstructor( tree, dataAccessServicePath, `${vars.app.className}${vars.model.className}Service`, vars.actor.propertyName, - serviceName, - serviceFileName, + serviceActorName, + serviceActorFileName, ) // Add the crud service to the module providers - addServiceToModuleDecorator(tree, dataAccessModulePath, serviceName, serviceFileName) + addServiceToModuleDecorator(tree, dataAccessModulePath, serviceActorName, serviceActorFileName) // Add the crud service to the module resolvers addServiceToModuleDecorator(tree, featureModulePath, resolverName, resolverFileName) From 20a7e31bd6a912f234d150b6ab944cd5d186989f Mon Sep 17 00:00:00 2001 From: Bram Borggreve Date: Mon, 11 Mar 2024 07:03:11 +0000 Subject: [PATCH 02/12] feat: add script to sync schemas --- .../api-crud/api-crud-schema-normalized.d.ts | 5 + .../generators/api-crud/api-crud-schema.d.ts | 25 +- .../generators/api-crud/api-crud-schema.json | 2 +- .../api-feature/api-feature-schema.d.ts | 46 +++- .../api-feature/api-feature-schema.json | 2 +- .../prisma-model/prisma-model-schema.d.ts | 21 +- .../prisma-model/prisma-model-schema.json | 8 +- .../prisma-sync/prisma-sync-schema.d.ts | 18 +- .../prisma-sync/prisma-sync-schema.json | 2 +- .../src/generators/rename/rename-schema.d.ts | 23 +- .../src/generators/rename/rename-schema.json | 2 +- .../src/generators/setup/setup-schema.d.ts | 8 + .../src/generators/setup/setup-schema.json | 2 +- .../generators/web-crud/web-crud-schema.d.ts | 25 +- .../generators/web-crud/web-crud-schema.json | 2 +- .../web-feature/web-feature-generator.spec.ts | 3 +- .../web-feature/web-feature-schema.d.ts | 45 +++- .../web-feature/web-feature-schema.json | 6 +- .../src/lib/api-crud/generate-api-crud.ts | 8 +- .../api-crud/get-api-crud-substitutions.ts | 3 +- .../lib/api-crud/normalize-api-crud-schema.ts | 3 +- .../api-crud/normalized-api-crud.schema.d.ts | 7 + .../tools/src/lib/api/generate-api-feature.ts | 3 +- .../lib/api/generate-api-lib-data-access.ts | 3 +- .../src/lib/api/generate-api-lib-feature.ts | 3 +- libs/tools/src/lib/api/generate-api-lib.ts | 3 +- .../lib/api/get-api-feature-module-info.ts | 2 +- .../src/lib/api/get-api-substitutions.ts | 2 +- .../lib/api/normalize-api-feature-schema.ts | 3 +- .../lib/api/normalized-api-feature-schema.ts | 12 + libs/tools/src/lib/prisma/get-prisma-enums.ts | 2 +- .../tools/src/lib/prisma/get-prisma-models.ts | 5 +- .../src/lib/web-crud/generate-web-crud.ts | 3 +- .../web-crud/get-web-crud-substitutions.ts | 3 +- .../lib/web-crud/normalize-web-crud-schema.ts | 5 +- .../normalized-web-crud-generator-schema.ts | 8 + .../tools/src/lib/web/generate-web-feature.ts | 2 +- libs/tools/src/lib/web/generate-web-lib.ts | 3 +- .../lib/web/normalize-web-feature-schema.ts | 3 +- .../lib/web/normalized-web-feature-schema.ts | 10 + package.json | 3 + pnpm-lock.yaml | 215 +++++++++++++++++- tools/scripts/sync-schemas.ts | 105 +++++++++ 43 files changed, 588 insertions(+), 76 deletions(-) create mode 100644 libs/tools/src/generators/api-crud/api-crud-schema-normalized.d.ts create mode 100644 libs/tools/src/generators/setup/setup-schema.d.ts create mode 100644 libs/tools/src/lib/api-crud/normalized-api-crud.schema.d.ts create mode 100644 libs/tools/src/lib/api/normalized-api-feature-schema.ts create mode 100644 libs/tools/src/lib/web-crud/normalized-web-crud-generator-schema.ts create mode 100644 libs/tools/src/lib/web/normalized-web-feature-schema.ts create mode 100644 tools/scripts/sync-schemas.ts diff --git a/libs/tools/src/generators/api-crud/api-crud-schema-normalized.d.ts b/libs/tools/src/generators/api-crud/api-crud-schema-normalized.d.ts new file mode 100644 index 0000000..414e28c --- /dev/null +++ b/libs/tools/src/generators/api-crud/api-crud-schema-normalized.d.ts @@ -0,0 +1,5 @@ +export interface NormalizedApiCrudSchema extends ApiCrudGeneratorSchema { + label: string + npmScope: string + fields?: PrismaModelField[] +} diff --git a/libs/tools/src/generators/api-crud/api-crud-schema.d.ts b/libs/tools/src/generators/api-crud/api-crud-schema.d.ts index 39b90bf..a364b59 100644 --- a/libs/tools/src/generators/api-crud/api-crud-schema.d.ts +++ b/libs/tools/src/generators/api-crud/api-crud-schema.d.ts @@ -1,12 +1,25 @@ +/* eslint-disable */ +/** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + export interface ApiCrudGeneratorSchema { + /** + * The name of the application you are adding the feature to. + */ app: string + /** + * The name of the actor you are adding the feature to. + */ actor: string + /** + * The label field for the model. Generally 'name' or 'title'. + */ label?: string + /** + * The name of the model for this feature. + */ model: string } - -export interface NormalizedApiCrudSchema extends ApiCrudGeneratorSchema { - label: string - npmScope: string - fields?: PrismaModelField[] -} diff --git a/libs/tools/src/generators/api-crud/api-crud-schema.json b/libs/tools/src/generators/api-crud/api-crud-schema.json index 83a4ba1..2b12532 100644 --- a/libs/tools/src/generators/api-crud/api-crud-schema.json +++ b/libs/tools/src/generators/api-crud/api-crud-schema.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/schema", - "$id": "ApiCrudSchema", + "$id": "ApiCrudGeneratorSchema", "title": "", "type": "object", "properties": { diff --git a/libs/tools/src/generators/api-feature/api-feature-schema.d.ts b/libs/tools/src/generators/api-feature/api-feature-schema.d.ts index d9c8b10..06b0fc4 100644 --- a/libs/tools/src/generators/api-feature/api-feature-schema.d.ts +++ b/libs/tools/src/generators/api-feature/api-feature-schema.d.ts @@ -1,15 +1,37 @@ -export type ApiFeatureGeneratorSchema = Partial> & { - crud?: string - model: string -} +/* eslint-disable */ +/** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ -export interface NormalizedApiFeatureSchema { - app: string - crud: string[] - label: string +export interface ApiFeatureGeneratorSchema { + /** + * The name of the model for this feature. + */ model: string - npmScope: string - skipDataAccess: boolean - skipFeature: boolean - skipUtil: boolean + /** + * The name of the application you are adding the feature to. + */ + app?: string + /** + * The label field for the model. Generally 'name' or 'title'. + */ + label?: string + /** + * Command separated list of actors to create CRUD for. + */ + crud?: string + /** + * Do not create a data access library for this feature. + */ + skipDataAccess?: boolean + /** + * Do not create a feature library for this feature. + */ + skipFeature?: boolean + /** + * Do not create a util library for this feature. + */ + skipUtil?: boolean } diff --git a/libs/tools/src/generators/api-feature/api-feature-schema.json b/libs/tools/src/generators/api-feature/api-feature-schema.json index f47600b..7a4b6fa 100644 --- a/libs/tools/src/generators/api-feature/api-feature-schema.json +++ b/libs/tools/src/generators/api-feature/api-feature-schema.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/schema", - "$id": "ApiFeature", + "$id": "ApiFeatureGeneratorSchema", "title": "", "type": "object", "properties": { diff --git a/libs/tools/src/generators/prisma-model/prisma-model-schema.d.ts b/libs/tools/src/generators/prisma-model/prisma-model-schema.d.ts index 0ba856c..57c4dbe 100644 --- a/libs/tools/src/generators/prisma-model/prisma-model-schema.d.ts +++ b/libs/tools/src/generators/prisma-model/prisma-model-schema.d.ts @@ -1,6 +1,25 @@ +/* eslint-disable */ +/** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + export interface PrismaModelGeneratorSchema { + /** + * Name of the model to create. + */ name: string - fields?: string[] + /** + * The label field for the model. Generally 'name' or 'title'. + */ label?: string + /** + * The path to the schema file to add the model to. Defaults to 'prisma/schema.prisma'. + */ schemaFile?: string + /** + * The field to add to the model, in the format 'name:type'. Use this flag multiple times to add multiple fields. + */ + fields?: string[] } diff --git a/libs/tools/src/generators/prisma-model/prisma-model-schema.json b/libs/tools/src/generators/prisma-model/prisma-model-schema.json index ce95193..8344028 100644 --- a/libs/tools/src/generators/prisma-model/prisma-model-schema.json +++ b/libs/tools/src/generators/prisma-model/prisma-model-schema.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/schema", - "$id": "PrismaModel", + "$id": "PrismaModelGeneratorSchema", "title": "", "type": "object", "properties": { @@ -18,7 +18,11 @@ "description": "The label field for the model. Generally 'name' or 'title'.", "default": "name" }, - "field": { + "schemaFile": { + "type": "string", + "description": "The path to the schema file to add the model to. Defaults to 'prisma/schema.prisma'." + }, + "fields": { "type": "array", "description": "The field to add to the model, in the format 'name:type'. Use this flag multiple times to add multiple fields.", "items": { diff --git a/libs/tools/src/generators/prisma-sync/prisma-sync-schema.d.ts b/libs/tools/src/generators/prisma-sync/prisma-sync-schema.d.ts index beefb8a..89c4de2 100644 --- a/libs/tools/src/generators/prisma-sync/prisma-sync-schema.d.ts +++ b/libs/tools/src/generators/prisma-sync/prisma-sync-schema.d.ts @@ -1,5 +1,21 @@ +/* eslint-disable */ +/** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + export interface PrismaSyncGeneratorSchema { - app: string + /** + * The name of the application to sync + */ + app?: string + /** + * The path to the schema file to sync + */ schemaFile?: string + /** + * Print more output + */ verbose?: boolean } diff --git a/libs/tools/src/generators/prisma-sync/prisma-sync-schema.json b/libs/tools/src/generators/prisma-sync/prisma-sync-schema.json index e9fb3a3..f719b94 100644 --- a/libs/tools/src/generators/prisma-sync/prisma-sync-schema.json +++ b/libs/tools/src/generators/prisma-sync/prisma-sync-schema.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/schema", - "$id": "PrismaSyncSchema", + "$id": "PrismaSyncGeneratorSchema", "title": "", "type": "object", "properties": { diff --git a/libs/tools/src/generators/rename/rename-schema.d.ts b/libs/tools/src/generators/rename/rename-schema.d.ts index 879a62b..88985f1 100644 --- a/libs/tools/src/generators/rename/rename-schema.d.ts +++ b/libs/tools/src/generators/rename/rename-schema.d.ts @@ -1,6 +1,25 @@ +/* eslint-disable */ +/** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + export interface RenameGeneratorSchema { - dryRun: boolean - quiet: boolean + /** + * Don't actually rename files, just print what would be done + */ + dryRun?: boolean + /** + * Don't prompt for confirmation + */ + quiet?: boolean + /** + * Search for this text + */ search: string + /** + * Replace with this text + */ replace?: string } diff --git a/libs/tools/src/generators/rename/rename-schema.json b/libs/tools/src/generators/rename/rename-schema.json index cfc98dd..48515bf 100644 --- a/libs/tools/src/generators/rename/rename-schema.json +++ b/libs/tools/src/generators/rename/rename-schema.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/schema", - "$id": "Rename", + "$id": "RenameGeneratorSchema", "title": "", "type": "object", "properties": { diff --git a/libs/tools/src/generators/setup/setup-schema.d.ts b/libs/tools/src/generators/setup/setup-schema.d.ts new file mode 100644 index 0000000..aef980b --- /dev/null +++ b/libs/tools/src/generators/setup/setup-schema.d.ts @@ -0,0 +1,8 @@ +/* eslint-disable */ +/** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + +export interface SetupGeneratorSchema {} diff --git a/libs/tools/src/generators/setup/setup-schema.json b/libs/tools/src/generators/setup/setup-schema.json index fc666a1..472b4a7 100644 --- a/libs/tools/src/generators/setup/setup-schema.json +++ b/libs/tools/src/generators/setup/setup-schema.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/schema", - "$id": "Setup", + "$id": "SetupGeneratorSchema", "title": "", "type": "object", "properties": {}, diff --git a/libs/tools/src/generators/web-crud/web-crud-schema.d.ts b/libs/tools/src/generators/web-crud/web-crud-schema.d.ts index c5ae695..bef035d 100644 --- a/libs/tools/src/generators/web-crud/web-crud-schema.d.ts +++ b/libs/tools/src/generators/web-crud/web-crud-schema.d.ts @@ -1,12 +1,25 @@ +/* eslint-disable */ +/** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + export interface WebCrudGeneratorSchema { + /** + * The name of the application you are adding the feature to. + */ app: string + /** + * The name of the actor you are adding the feature to. + */ actor: string + /** + * The label field for the model. Generally 'name' or 'title'. + */ label?: string + /** + * The name of the model for this feature. + */ model: string } - -export interface NormalizedWebCrudSchema extends WebCrudGeneratorSchema { - label: string - npmScope: string - fields?: PrismaModelField[] -} diff --git a/libs/tools/src/generators/web-crud/web-crud-schema.json b/libs/tools/src/generators/web-crud/web-crud-schema.json index 7a237ec..7eb0bc2 100644 --- a/libs/tools/src/generators/web-crud/web-crud-schema.json +++ b/libs/tools/src/generators/web-crud/web-crud-schema.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/schema", - "$id": "WebCrudSchema", + "$id": "WebCrudGeneratorSchema", "title": "", "type": "object", "properties": { diff --git a/libs/tools/src/generators/web-feature/web-feature-generator.spec.ts b/libs/tools/src/generators/web-feature/web-feature-generator.spec.ts index 8a8a49c..0e05f40 100644 --- a/libs/tools/src/generators/web-feature/web-feature-generator.spec.ts +++ b/libs/tools/src/generators/web-feature/web-feature-generator.spec.ts @@ -4,10 +4,11 @@ import { createMockApiApp } from '../../lib/api/create-mock-api-app' import { getRecursiveFileNames } from '../../lib/utils/get-recursive-file-names' import { createMockWebApp, normalizeWebFeatureSchema } from '../../lib/web' +import { NormalizedWebFeatureSchema } from '../../lib/web/normalized-web-feature-schema' import apiFeatureGenerator from '../api-feature/api-feature-generator' import { webFeatureGenerator } from './web-feature-generator' -import { type NormalizedWebFeatureSchema, WebFeatureGeneratorSchema } from './web-feature-schema' +import { WebFeatureGeneratorSchema } from './web-feature-schema' describe('web-feature generator', () => { let tree: Tree diff --git a/libs/tools/src/generators/web-feature/web-feature-schema.d.ts b/libs/tools/src/generators/web-feature/web-feature-schema.d.ts index a31b0f3..dc8464a 100644 --- a/libs/tools/src/generators/web-feature/web-feature-schema.d.ts +++ b/libs/tools/src/generators/web-feature/web-feature-schema.d.ts @@ -1,14 +1,37 @@ -export type WebFeatureGeneratorSchema = Partial> & { - crud?: string -} +/* eslint-disable */ +/** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ -export interface NormalizedWebFeatureSchema { - app: string - crud: string[] - label: string +export interface WebFeatureGeneratorSchema { + /** + * The name of the model for this feature. + */ model: string - npmScope: string - skipDataAccess: boolean - skipFeature: boolean - skipUi: boolean + /** + * The name of the application you are adding the feature to. + */ + app?: string + /** + * The label field for the model. Generally 'name' or 'title'. + */ + label?: string + /** + * Command separated list of actors to create CRUD for. + */ + crud?: string + /** + * Do not create a data access library for this feature. + */ + skipDataAccess?: boolean + /** + * Do not create a feature library for this feature. + */ + skipFeature?: boolean + /** + * Do not create a ui library for this feature. + */ + skipUi?: boolean } diff --git a/libs/tools/src/generators/web-feature/web-feature-schema.json b/libs/tools/src/generators/web-feature/web-feature-schema.json index 356b73c..72b4e02 100644 --- a/libs/tools/src/generators/web-feature/web-feature-schema.json +++ b/libs/tools/src/generators/web-feature/web-feature-schema.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/schema", - "$id": "WebFeature", + "$id": "WebFeatureGeneratorSchema", "title": "", "type": "object", "properties": { @@ -37,9 +37,9 @@ "description": "Do not create a feature library for this feature.", "default": false }, - "skipUtil": { + "skipUi": { "type": "boolean", - "description": "Do not create a util library for this feature.", + "description": "Do not create a ui library for this feature.", "default": true } }, diff --git a/libs/tools/src/lib/api-crud/generate-api-crud.ts b/libs/tools/src/lib/api-crud/generate-api-crud.ts index 3fd8da6..e93ce1a 100644 --- a/libs/tools/src/lib/api-crud/generate-api-crud.ts +++ b/libs/tools/src/lib/api-crud/generate-api-crud.ts @@ -1,5 +1,4 @@ import { generateFiles, getProjects, type ProjectConfiguration, Tree } from '@nx/devkit' -import type { NormalizedApiCrudSchema } from '../../generators/api-crud/api-crud-schema' import { addExports } from '../utils/add-export' import { ensureNxProjectExists } from '../utils/ensure-nx-project-exists' import { addServiceToClassConstructor } from './add-service-to-class-constructor' @@ -7,6 +6,8 @@ import { addServiceToModuleDecorator } from './add-service-to-module-decorator' import { generateSdkFile } from './generate-sdk-file' import { getApiCrudSubstitutions } from './get-api-crud-substitutions' +import { NormalizedApiCrudSchema } from './normalized-api-crud.schema' + export function generateApiCrud(tree: Tree, options: NormalizedApiCrudSchema) { const [dataAccess, feature]: ProjectConfiguration[] = [ `${options.app}-${options.model}-data-access`, @@ -51,9 +52,9 @@ export function generateApiCrud(tree: Tree, options: NormalizedApiCrudSchema) { // Generate the data access library generateFiles(tree, `${__dirname}/files/data-access`, dataAccess.sourceRoot, { ...vars }) + // Add the services to the service constructor + const currentFile = tree.read(dataAccessServicePath).toString() - // Add the crud services to the service constructor - console.log('serviceName', serviceName, currentFile, currentFile.includes(serviceName)) if (!currentFile.includes(serviceName)) { addServiceToClassConstructor( tree, @@ -63,7 +64,6 @@ export function generateApiCrud(tree: Tree, options: NormalizedApiCrudSchema) { serviceName, serviceFileName, ) - // Add the crud service to the module providers addServiceToModuleDecorator(tree, dataAccessModulePath, serviceName, serviceFileName) } diff --git a/libs/tools/src/lib/api-crud/get-api-crud-substitutions.ts b/libs/tools/src/lib/api-crud/get-api-crud-substitutions.ts index 3e6531b..e9c6b97 100644 --- a/libs/tools/src/lib/api-crud/get-api-crud-substitutions.ts +++ b/libs/tools/src/lib/api-crud/get-api-crud-substitutions.ts @@ -1,6 +1,7 @@ import { names } from '@nx/devkit' import * as pluralize from 'pluralize' -import type { NormalizedApiCrudSchema } from '../../generators/api-crud/api-crud-schema' + +import { NormalizedApiCrudSchema } from './normalized-api-crud.schema' export function getApiCrudSubstitutions(options: NormalizedApiCrudSchema) { const actor = names(options.actor) diff --git a/libs/tools/src/lib/api-crud/normalize-api-crud-schema.ts b/libs/tools/src/lib/api-crud/normalize-api-crud-schema.ts index 77fdac5..a0c728f 100644 --- a/libs/tools/src/lib/api-crud/normalize-api-crud-schema.ts +++ b/libs/tools/src/lib/api-crud/normalize-api-crud-schema.ts @@ -1,7 +1,8 @@ import { Tree } from '@nx/devkit' import { getNpmScope } from '@nx/js/src/utils/package-json/get-npm-scope' -import type { ApiCrudGeneratorSchema, NormalizedApiCrudSchema } from '../../generators/api-crud/api-crud-schema' +import { ApiCrudGeneratorSchema } from '../../generators/api-crud/api-crud-schema' import { getPrismaModelFields } from '../prisma/get-prisma-models' +import { NormalizedApiCrudSchema } from './normalized-api-crud.schema' export function normalizeApiCrudSchema(tree: Tree, schema: ApiCrudGeneratorSchema): NormalizedApiCrudSchema { const npmScope = getNpmScope(tree) diff --git a/libs/tools/src/lib/api-crud/normalized-api-crud.schema.d.ts b/libs/tools/src/lib/api-crud/normalized-api-crud.schema.d.ts new file mode 100644 index 0000000..6f77aed --- /dev/null +++ b/libs/tools/src/lib/api-crud/normalized-api-crud.schema.d.ts @@ -0,0 +1,7 @@ +import { ApiCrudGeneratorSchema } from '../../generators/api-crud/api-crud-schema' + +export interface NormalizedApiCrudSchema extends ApiCrudGeneratorSchema { + label: string + npmScope: string + fields?: PrismaModelField[] +} diff --git a/libs/tools/src/lib/api/generate-api-feature.ts b/libs/tools/src/lib/api/generate-api-feature.ts index 7da17dc..c7f8392 100644 --- a/libs/tools/src/lib/api/generate-api-feature.ts +++ b/libs/tools/src/lib/api/generate-api-feature.ts @@ -1,7 +1,8 @@ import { getProjects, Tree } from '@nx/devkit' import apiCrudGenerator from '../../generators/api-crud/api-crud-generator' -import { NormalizedApiFeatureSchema } from '../../generators/api-feature/api-feature-schema' + import { generateApiLib } from './generate-api-lib' +import { NormalizedApiFeatureSchema } from './normalized-api-feature-schema' export async function generateApiFeature(tree: Tree, options: NormalizedApiFeatureSchema) { const projects = getProjects(tree) diff --git a/libs/tools/src/lib/api/generate-api-lib-data-access.ts b/libs/tools/src/lib/api/generate-api-lib-data-access.ts index 3b188c0..0114127 100644 --- a/libs/tools/src/lib/api/generate-api-lib-data-access.ts +++ b/libs/tools/src/lib/api/generate-api-lib-data-access.ts @@ -1,8 +1,9 @@ import { generateFiles, Tree } from '@nx/devkit' -import { NormalizedApiFeatureSchema } from '../../generators/api-feature/api-feature-schema' + import { replaceExports } from '../utils/add-export' import { ensureNxProjectExists } from '../utils/ensure-nx-project-exists' import { getApiSubstitutions } from './get-api-substitutions' +import { NormalizedApiFeatureSchema } from './normalized-api-feature-schema' export async function generateApiLibDataAccess(tree: Tree, options: NormalizedApiFeatureSchema) { const substitutions = getApiSubstitutions(options) diff --git a/libs/tools/src/lib/api/generate-api-lib-feature.ts b/libs/tools/src/lib/api/generate-api-lib-feature.ts index 148ed02..1824f76 100644 --- a/libs/tools/src/lib/api/generate-api-lib-feature.ts +++ b/libs/tools/src/lib/api/generate-api-lib-feature.ts @@ -1,10 +1,11 @@ import { generateFiles, Tree } from '@nx/devkit' -import { NormalizedApiFeatureSchema } from '../../generators/api-feature/api-feature-schema' + import { replaceExports } from '../utils/add-export' import { apiUpdateCoreFeatureModule } from './api-update-core-feature-module' import { getApiCoreFeatureInfo } from './get-api-core-feature-info' import { getApiFeatureModuleInfo } from './get-api-feature-module-info' import { getApiSubstitutions } from './get-api-substitutions' +import { NormalizedApiFeatureSchema } from './normalized-api-feature-schema' export async function generateApiLibFeature(tree: Tree, options: NormalizedApiFeatureSchema) { const substitutions = getApiSubstitutions(options) diff --git a/libs/tools/src/lib/api/generate-api-lib.ts b/libs/tools/src/lib/api/generate-api-lib.ts index e8ee9dd..4da8b26 100644 --- a/libs/tools/src/lib/api/generate-api-lib.ts +++ b/libs/tools/src/lib/api/generate-api-lib.ts @@ -1,9 +1,10 @@ import { Tree } from '@nx/devkit' import { libraryGenerator } from '@nx/nest' -import { NormalizedApiFeatureSchema } from '../../generators/api-feature/api-feature-schema' + import { ApiLibType } from '../types/api-feature' import { generateApiLibDataAccess } from './generate-api-lib-data-access' import { generateApiLibFeature } from './generate-api-lib-feature' +import { NormalizedApiFeatureSchema } from './normalized-api-feature-schema' export async function generateApiLib(tree: Tree, type: ApiLibType, options: NormalizedApiFeatureSchema) { const generated = await libraryGenerator(tree, { diff --git a/libs/tools/src/lib/api/get-api-feature-module-info.ts b/libs/tools/src/lib/api/get-api-feature-module-info.ts index 3a47b2e..43e3246 100644 --- a/libs/tools/src/lib/api/get-api-feature-module-info.ts +++ b/libs/tools/src/lib/api/get-api-feature-module-info.ts @@ -1,6 +1,6 @@ import { names, readProjectConfiguration, Tree } from '@nx/devkit' -import { NormalizedApiFeatureSchema } from '../../generators/api-feature/api-feature-schema' import { getImportPath } from '../utils/get-import-path' +import { NormalizedApiFeatureSchema } from './normalized-api-feature-schema' export function getApiFeatureModuleInfo(tree: Tree, options: NormalizedApiFeatureSchema) { const project = readProjectConfiguration(tree, `${options.app}-${options.model}-feature`) diff --git a/libs/tools/src/lib/api/get-api-substitutions.ts b/libs/tools/src/lib/api/get-api-substitutions.ts index 2ce72a0..efceef4 100644 --- a/libs/tools/src/lib/api/get-api-substitutions.ts +++ b/libs/tools/src/lib/api/get-api-substitutions.ts @@ -1,6 +1,6 @@ import { names } from '@nx/devkit' import * as pluralize from 'pluralize' -import { NormalizedApiFeatureSchema } from '../../generators/api-feature/api-feature-schema' +import { NormalizedApiFeatureSchema } from './normalized-api-feature-schema' export function getApiSubstitutions(options: NormalizedApiFeatureSchema) { const app = names(options.app) diff --git a/libs/tools/src/lib/api/normalize-api-feature-schema.ts b/libs/tools/src/lib/api/normalize-api-feature-schema.ts index d2ac3e2..eee6b08 100644 --- a/libs/tools/src/lib/api/normalize-api-feature-schema.ts +++ b/libs/tools/src/lib/api/normalize-api-feature-schema.ts @@ -1,6 +1,7 @@ import { Tree } from '@nx/devkit' import { getNpmScope } from '@nx/js/src/utils/package-json/get-npm-scope' -import { ApiFeatureGeneratorSchema, NormalizedApiFeatureSchema } from '../../generators/api-feature/api-feature-schema' +import { ApiFeatureGeneratorSchema } from '../../generators/api-feature/api-feature-schema' +import { NormalizedApiFeatureSchema } from './normalized-api-feature-schema' export function normalizeApiFeatureSchema(tree: Tree, schema: ApiFeatureGeneratorSchema): NormalizedApiFeatureSchema { const model = schema.model diff --git a/libs/tools/src/lib/api/normalized-api-feature-schema.ts b/libs/tools/src/lib/api/normalized-api-feature-schema.ts new file mode 100644 index 0000000..c7a9c2d --- /dev/null +++ b/libs/tools/src/lib/api/normalized-api-feature-schema.ts @@ -0,0 +1,12 @@ +import type { ApiFeatureGeneratorSchema } from '../../generators/api-feature/api-feature-schema' + +export interface NormalizedApiFeatureSchema extends Omit { + app: string + crud: string[] + label: string + model: string + npmScope: string + skipDataAccess: boolean + skipFeature: boolean + skipUtil: boolean +} diff --git a/libs/tools/src/lib/prisma/get-prisma-enums.ts b/libs/tools/src/lib/prisma/get-prisma-enums.ts index 05c4d8a..2cd8857 100644 --- a/libs/tools/src/lib/prisma/get-prisma-enums.ts +++ b/libs/tools/src/lib/prisma/get-prisma-enums.ts @@ -1,4 +1,4 @@ -import type { Enum } from '@mrleebo/prisma-ast' +import { Enum } from '@mrleebo/prisma-ast' import { Tree } from '@nx/devkit' import { getPrismaSchema } from './get-prisma-schema' diff --git a/libs/tools/src/lib/prisma/get-prisma-models.ts b/libs/tools/src/lib/prisma/get-prisma-models.ts index 86f5942..e76eb3d 100644 --- a/libs/tools/src/lib/prisma/get-prisma-models.ts +++ b/libs/tools/src/lib/prisma/get-prisma-models.ts @@ -1,5 +1,4 @@ -import type { Field } from '@mrleebo/prisma-ast' -import { Model } from '@mrleebo/prisma-ast' +import { Field, Model } from '@mrleebo/prisma-ast' import { Tree } from '@nx/devkit' import { getPrismaSchema } from './get-prisma-schema' @@ -9,7 +8,7 @@ export function getPrismaModels(tree: Tree, schemaPath = 'prisma/schema.prisma') return schema.list.filter((item) => item.type === 'model') as Model[] } -interface PrismaModelField { +export interface PrismaModelField { name: string type: string optional: boolean diff --git a/libs/tools/src/lib/web-crud/generate-web-crud.ts b/libs/tools/src/lib/web-crud/generate-web-crud.ts index b54f167..cac556c 100644 --- a/libs/tools/src/lib/web-crud/generate-web-crud.ts +++ b/libs/tools/src/lib/web-crud/generate-web-crud.ts @@ -1,5 +1,6 @@ import { generateFiles, type ProjectConfiguration, Tree } from '@nx/devkit' -import type { NormalizedApiCrudSchema } from '../../generators/api-crud/api-crud-schema' + +import { NormalizedApiCrudSchema } from '../api-crud/normalized-api-crud.schema' import { addArrayItem } from '../utils/add-array-item' import { addExports } from '../utils/add-export' import { addNamedImport } from '../utils/add-named-import' diff --git a/libs/tools/src/lib/web-crud/get-web-crud-substitutions.ts b/libs/tools/src/lib/web-crud/get-web-crud-substitutions.ts index 1e5cfd7..08972bb 100644 --- a/libs/tools/src/lib/web-crud/get-web-crud-substitutions.ts +++ b/libs/tools/src/lib/web-crud/get-web-crud-substitutions.ts @@ -1,6 +1,7 @@ import { names } from '@nx/devkit' import * as pluralize from 'pluralize' -import type { NormalizedApiCrudSchema } from '../../generators/api-crud/api-crud-schema' + +import { NormalizedApiCrudSchema } from '../api-crud/normalized-api-crud.schema' export function getWebCrudSubstitutions(options: NormalizedApiCrudSchema) { const actor = names(options.actor) diff --git a/libs/tools/src/lib/web-crud/normalize-web-crud-schema.ts b/libs/tools/src/lib/web-crud/normalize-web-crud-schema.ts index 981ef0b..6984fe0 100644 --- a/libs/tools/src/lib/web-crud/normalize-web-crud-schema.ts +++ b/libs/tools/src/lib/web-crud/normalize-web-crud-schema.ts @@ -1,9 +1,10 @@ import { Tree } from '@nx/devkit' import { getNpmScope } from '@nx/js/src/utils/package-json/get-npm-scope' -import type { NormalizedWebCrudSchema, WebCrudGeneratorSchema } from '../../generators/web-crud/web-crud-schema' +import { WebCrudGeneratorSchema } from '../../generators/web-crud/web-crud-schema' import { getPrismaModelFields } from '../prisma/get-prisma-models' +import { NormalizedWebCrudGeneratorSchema } from './normalized-web-crud-generator-schema' -export function normalizeWebCrudSchema(tree: Tree, schema: WebCrudGeneratorSchema): NormalizedWebCrudSchema { +export function normalizeWebCrudSchema(tree: Tree, schema: WebCrudGeneratorSchema): NormalizedWebCrudGeneratorSchema { const npmScope = getNpmScope(tree) const fields = getPrismaModelFields(tree, schema.model) ?? [{ name: 'name', type: 'string', optional: false }] diff --git a/libs/tools/src/lib/web-crud/normalized-web-crud-generator-schema.ts b/libs/tools/src/lib/web-crud/normalized-web-crud-generator-schema.ts new file mode 100644 index 0000000..248e602 --- /dev/null +++ b/libs/tools/src/lib/web-crud/normalized-web-crud-generator-schema.ts @@ -0,0 +1,8 @@ +import { WebCrudGeneratorSchema } from '../../generators/web-crud/web-crud-schema' +import { PrismaModelField } from '../prisma/get-prisma-models' + +export interface NormalizedWebCrudGeneratorSchema extends WebCrudGeneratorSchema { + label: string + npmScope: string + fields?: PrismaModelField[] +} diff --git a/libs/tools/src/lib/web/generate-web-feature.ts b/libs/tools/src/lib/web/generate-web-feature.ts index 02ea686..b26e037 100644 --- a/libs/tools/src/lib/web/generate-web-feature.ts +++ b/libs/tools/src/lib/web/generate-web-feature.ts @@ -1,7 +1,7 @@ import { getProjects, Tree } from '@nx/devkit' import webCrudGenerator from '../../generators/web-crud/web-crud-generator' -import { NormalizedWebFeatureSchema } from '../../generators/web-feature/web-feature-schema' import { generateWebLib } from './generate-web-lib' +import { NormalizedWebFeatureSchema } from './normalized-web-feature-schema' export async function generateWebFeature(tree: Tree, options: NormalizedWebFeatureSchema) { const projects = getProjects(tree) diff --git a/libs/tools/src/lib/web/generate-web-lib.ts b/libs/tools/src/lib/web/generate-web-lib.ts index a19468d..8e3b02f 100644 --- a/libs/tools/src/lib/web/generate-web-lib.ts +++ b/libs/tools/src/lib/web/generate-web-lib.ts @@ -2,8 +2,9 @@ import { Tree } from '@nx/devkit' import { Linter } from '@nx/eslint' import { getNpmScope } from '@nx/js/src/utils/package-json/get-npm-scope' import { libraryGenerator } from '@nx/react' -import { NormalizedWebFeatureSchema } from '../../generators/web-feature/web-feature-schema' + import { WebLibType } from '../types/web-feature' +import { NormalizedWebFeatureSchema } from './normalized-web-feature-schema' export async function generateWebLib(tree: Tree, type: WebLibType, options: NormalizedWebFeatureSchema) { const generated = await libraryGenerator(tree, { diff --git a/libs/tools/src/lib/web/normalize-web-feature-schema.ts b/libs/tools/src/lib/web/normalize-web-feature-schema.ts index 0a92d69..4a1898f 100644 --- a/libs/tools/src/lib/web/normalize-web-feature-schema.ts +++ b/libs/tools/src/lib/web/normalize-web-feature-schema.ts @@ -1,6 +1,7 @@ import { Tree } from '@nx/devkit' import { getNpmScope } from '@nx/js/src/utils/package-json/get-npm-scope' -import { NormalizedWebFeatureSchema, WebFeatureGeneratorSchema } from '../../generators/web-feature/web-feature-schema' +import { WebFeatureGeneratorSchema } from '../../generators/web-feature/web-feature-schema' +import { NormalizedWebFeatureSchema } from './normalized-web-feature-schema' export function normalizeWebFeatureSchema(tree: Tree, schema: WebFeatureGeneratorSchema): NormalizedWebFeatureSchema { const model = schema.model diff --git a/libs/tools/src/lib/web/normalized-web-feature-schema.ts b/libs/tools/src/lib/web/normalized-web-feature-schema.ts new file mode 100644 index 0000000..46e49c4 --- /dev/null +++ b/libs/tools/src/lib/web/normalized-web-feature-schema.ts @@ -0,0 +1,10 @@ +export interface NormalizedWebFeatureSchema { + app: string + crud: string[] + label: string + model: string + npmScope: string + skipDataAccess: boolean + skipFeature: boolean + skipUi: boolean +} diff --git a/package.json b/package.json index 1b9d14f..020ae9e 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "prestart": "pnpm prisma db push", "setup": "pnpm nx generate setup", "start": "NODE_ENV=production node dist/apps/api/main.js", + "sync-schemas": "ts-node ./tools/scripts/sync-schemas.ts", "test:all": "nx run-many --target=test --all" }, "private": true, @@ -147,6 +148,7 @@ "@typescript-eslint/eslint-plugin": "6.18.1", "@typescript-eslint/parser": "6.18.1", "babel-jest": "^29.7.0", + "commander": "^12.0.0", "core-js": "^3.35.0", "cypress": "^13.6.2", "dayjs": "^1.11.10", @@ -164,6 +166,7 @@ "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", "jest-environment-node": "^29.7.0", + "json-schema-to-typescript": "^13.1.2", "lint-staged": "^15.2.0", "nx": "17.2.8", "pg": "^8.11.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 738e69b..01e2223 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -355,6 +355,9 @@ devDependencies: babel-jest: specifier: ^29.7.0 version: 29.7.0(@babel/core@7.23.7) + commander: + specifier: ^12.0.0 + version: 12.0.0 core-js: specifier: ^3.35.0 version: 3.35.0 @@ -406,6 +409,9 @@ devDependencies: jest-environment-node: specifier: ^29.7.0 version: 29.7.0 + json-schema-to-typescript: + specifier: ^13.1.2 + version: 13.1.2 lint-staged: specifier: ^15.2.0 version: 15.2.0 @@ -2220,6 +2226,16 @@ packages: '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 + /@bcherny/json-schema-ref-parser@10.0.5-fork: + resolution: {integrity: sha512-E/jKbPoca1tfUPj3iSbitDZTGnq6FUFjkH6L8U2oDwSuwK1WhnnVtCG7oFOTg/DDnyoXbQYUiUiGOibHqaGVnw==} + engines: {node: '>= 16'} + dependencies: + '@jsdevtools/ono': 7.1.3 + '@types/json-schema': 7.0.15 + call-me-maybe: 1.0.2 + js-yaml: 4.1.0 + dev: true + /@bcoe/v8-coverage@0.2.3: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} @@ -3471,6 +3487,10 @@ packages: '@jridgewell/resolve-uri': 3.1.1 '@jridgewell/sourcemap-codec': 1.4.15 + /@jsdevtools/ono@7.1.3: + resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} + dev: true + /@leichtgewicht/ip-codec@2.0.4: resolution: {integrity: sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==} dev: true @@ -7000,6 +7020,10 @@ packages: '@types/node': 20.10.8 dev: true + /@types/lodash@4.14.202: + resolution: {integrity: sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==} + dev: true + /@types/long@4.0.2: resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==} dev: false @@ -7118,6 +7142,10 @@ packages: resolution: {integrity: sha512-JOqsl+ZoCpP4e8TDke9W79FDcSgPAR0l6pixx2JHkhnRjvShyYiAYw2LVsnA7K08Y6DeOnaU6ujmENO4os/cYg==} dev: true + /@types/prettier@2.7.3: + resolution: {integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==} + dev: true + /@types/prop-types@15.7.11: resolution: {integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==} @@ -7856,6 +7884,10 @@ packages: engines: {node: '>=12'} dev: true + /any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + dev: true + /anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} @@ -8665,6 +8697,10 @@ packages: get-intrinsic: 1.2.2 set-function-length: 1.1.1 + /call-me-maybe@1.0.2: + resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==} + dev: true + /caller-callsite@2.0.0: resolution: {integrity: sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==} engines: {node: '>=4'} @@ -8858,6 +8894,17 @@ packages: engines: {node: '>=6'} dev: true + /cli-color@2.0.4: + resolution: {integrity: sha512-zlnpg0jNcibNrO7GG9IeHH7maWFeCz+Ja1wx/7tZNU5ASSSSZ+/qZciM0/LHCYxSdqv5h2sdbQ/PXYdOuetXvA==} + engines: {node: '>=0.10'} + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-iterator: 2.0.3 + memoizee: 0.4.15 + timers-ext: 0.1.7 + dev: true + /cli-cursor@3.1.0: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} @@ -9017,6 +9064,11 @@ packages: engines: {node: '>=16'} dev: true + /commander@12.0.0: + resolution: {integrity: sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==} + engines: {node: '>=18'} + dev: true + /commander@2.13.0: resolution: {integrity: sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==} dev: false @@ -9652,6 +9704,14 @@ packages: yauzl: 2.10.0 dev: true + /d@1.0.2: + resolution: {integrity: sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==} + engines: {node: '>=0.12'} + dependencies: + es5-ext: 0.10.64 + type: 2.7.2 + dev: true + /damerau-levenshtein@1.0.8: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} dev: true @@ -10252,6 +10312,25 @@ packages: is-symbol: 1.0.4 dev: true + /es5-ext@0.10.64: + resolution: {integrity: sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==} + engines: {node: '>=0.10'} + requiresBuild: true + dependencies: + es6-iterator: 2.0.3 + es6-symbol: 3.1.4 + esniff: 2.0.1 + next-tick: 1.1.0 + dev: true + + /es6-iterator@2.0.3: + resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-symbol: 3.1.4 + dev: true + /es6-promise@4.2.8: resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} dev: false @@ -10262,6 +10341,23 @@ packages: es6-promise: 4.2.8 dev: false + /es6-symbol@3.1.4: + resolution: {integrity: sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==} + engines: {node: '>=0.12'} + dependencies: + d: 1.0.2 + ext: 1.7.0 + dev: true + + /es6-weak-map@2.0.3: + resolution: {integrity: sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==} + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-iterator: 2.0.3 + es6-symbol: 3.1.4 + dev: true + /escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} @@ -10513,6 +10609,16 @@ packages: transitivePeerDependencies: - supports-color + /esniff@2.0.1: + resolution: {integrity: sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==} + engines: {node: '>=0.10'} + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + event-emitter: 0.3.5 + type: 2.7.2 + dev: true + /espree@9.6.1: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -10566,6 +10672,13 @@ packages: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} + /event-emitter@0.3.5: + resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + dev: true + /event-target-shim@5.0.1: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} @@ -10745,6 +10858,12 @@ packages: sort-keys-length: 1.0.1 dev: true + /ext@1.7.0: + resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} + dependencies: + type: 2.7.2 + dev: true + /extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} dev: true @@ -11266,6 +11385,11 @@ packages: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} engines: {node: '>=8.0.0'} + /get-stdin@8.0.0: + resolution: {integrity: sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==} + engines: {node: '>=10'} + dev: true + /get-stream@3.0.0: resolution: {integrity: sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==} engines: {node: '>=4'} @@ -11319,6 +11443,16 @@ packages: dependencies: is-glob: 4.0.3 + /glob-promise@4.2.2(glob@7.2.3): + resolution: {integrity: sha512-xcUzJ8NWN5bktoTIX7eOclO1Npxd/dyVqUJxlLIDasT4C7KZyqlPIwkdJ0Ypiy3p2ZKahTjK4M9uC3sNSfNMzw==} + engines: {node: '>=12'} + peerDependencies: + glob: ^7.1.6 + dependencies: + '@types/glob': 7.2.0 + glob: 7.2.3 + dev: true + /glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} @@ -12203,6 +12337,10 @@ packages: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} dev: true + /is-promise@2.2.2: + resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} + dev: true + /is-reference@1.2.1: resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} dependencies: @@ -13055,6 +13193,27 @@ packages: /json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + /json-schema-to-typescript@13.1.2: + resolution: {integrity: sha512-17G+mjx4nunvOpkPvcz7fdwUwYCEwyH8vR3Ym3rFiQ8uzAL3go+c1306Kk7iGRk8HuXBXqy+JJJmpYl0cvOllw==} + engines: {node: '>=12.0.0'} + hasBin: true + dependencies: + '@bcherny/json-schema-ref-parser': 10.0.5-fork + '@types/json-schema': 7.0.15 + '@types/lodash': 4.14.202 + '@types/prettier': 2.7.3 + cli-color: 2.0.4 + get-stdin: 8.0.0 + glob: 7.2.3 + glob-promise: 4.2.2(glob@7.2.3) + is-glob: 4.0.3 + lodash: 4.17.21 + minimist: 1.2.8 + mkdirp: 1.0.4 + mz: 2.7.0 + prettier: 2.8.8 + dev: true + /json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} @@ -13581,6 +13740,12 @@ packages: engines: {node: '>=12'} dev: false + /lru-queue@0.1.0: + resolution: {integrity: sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==} + dependencies: + es5-ext: 0.10.64 + dev: true + /luxon@3.4.4: resolution: {integrity: sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==} engines: {node: '>=12'} @@ -13681,6 +13846,19 @@ packages: resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==} dev: false + /memoizee@0.4.15: + resolution: {integrity: sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==} + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-weak-map: 2.0.3 + event-emitter: 0.3.5 + is-promise: 2.2.2 + lru-queue: 0.1.0 + next-tick: 1.1.0 + timers-ext: 0.1.7 + dev: true + /merge-descriptors@1.0.1: resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} @@ -14149,7 +14327,6 @@ packages: resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} engines: {node: '>=10'} hasBin: true - dev: false /mkdirp@3.0.1: resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} @@ -14189,6 +14366,14 @@ packages: resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} dev: true + /mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + dev: true + /nanoid@3.3.7: resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -14219,6 +14404,10 @@ packages: /neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + /next-tick@1.1.0: + resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} + dev: true + /no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} dependencies: @@ -17751,6 +17940,19 @@ packages: /text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + /thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + dependencies: + thenify: 3.3.1 + dev: true + + /thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + dependencies: + any-promise: 1.3.0 + dev: true + /throat@5.0.0: resolution: {integrity: sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==} dev: false @@ -17786,6 +17988,13 @@ packages: resolution: {integrity: sha512-a7wPxPdVlQL7lqvitHGGRsofhdwtkoSXPGATFuSOA2i1ZNQEPLrGnj68vOp2sOJTCFAQVXPeNMX/GctBaO9L2w==} dev: false + /timers-ext@0.1.7: + resolution: {integrity: sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==} + dependencies: + es5-ext: 0.10.64 + next-tick: 1.1.0 + dev: true + /title-case@3.0.3: resolution: {integrity: sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==} dependencies: @@ -18107,6 +18316,10 @@ packages: media-typer: 0.3.0 mime-types: 2.1.35 + /type@2.7.2: + resolution: {integrity: sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==} + dev: true + /typed-array-buffer@1.0.0: resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} engines: {node: '>= 0.4'} diff --git a/tools/scripts/sync-schemas.ts b/tools/scripts/sync-schemas.ts new file mode 100644 index 0000000..c4bd01f --- /dev/null +++ b/tools/scripts/sync-schemas.ts @@ -0,0 +1,105 @@ +import { program } from 'commander' +import * as fs from 'fs' +import { compileFromFile } from 'json-schema-to-typescript' +import { join } from 'path' + +const GENERATOR_FILE = 'generators.json' + +function findGenerators(root: string) { + const packages = fs.readdirSync(root) + return packages + .map((pkg: string) => { + const generatorPath = join(root, pkg, GENERATOR_FILE) + if (fs.existsSync(generatorPath)) { + return { pkg, generatorPath } + } + }) + .filter(Boolean) +} + +async function main() { + const result = program + .name('sync-schemas') + .option('--dry-run', 'Dry run (default: false)', false) + .option('--check', 'Check if schemas are up to date, exit with code 1 if not (default: false)', false) + .parse(process.argv) + .opts() + + const packagesRoot = join(__dirname, '../../libs') + const generators = findGenerators(packagesRoot) ?? [] + const changes: { file: string; schema: string }[] = [] + + for (const generator of generators) { + if (!generator) { + continue + } + const generatorJson = JSON.parse(fs.readFileSync(generator.generatorPath).toString()) + const generators = Object.keys(generatorJson.generators) + const schemas = generators.map((generatorName) => { + const generator = generatorJson.generators[generatorName] + const schemaPath = join(generator.schema) + return { generatorName, schemaPath } + }) + + for (const schema of schemas) { + const schemaPath = join(packagesRoot, generator.pkg, schema.schemaPath) + if (!fs.existsSync(schemaPath)) { + console.log( + `Schema not found for ${generator.pkg} (${schemaPath.replace( + process.cwd(), + '', + )}). Check the reference in ${join( + packagesRoot.replace(process.cwd(), ''), + generator.pkg, + 'generators.json', + )}`, + ) + continue + } + const schemaPathDts = schemaPath.replace('schema.json', 'schema.d.ts') + const schemaPathDtsBefore = fs.readFileSync(schemaPathDts).toString() + + await compileFromFile(schemaPath, { + additionalProperties: false, + format: true, + style: { + singleQuote: true, + printWidth: 120, + semi: false, + trailingComma: 'all', + arrowParens: 'always', + }, + }).then((schema) => { + if (JSON.stringify(schemaPathDtsBefore) !== JSON.stringify(schema)) { + changes.push({ file: schemaPathDts, schema }) + } + }) + } + } + + if (result.check && changes.length > 0) { + console.log( + `❌ Some schemas are not up to date:\n - ${changes + .map((change) => change.file.replace(packagesRoot, 'packages')) + .join('\n - ')}`, + ) + console.log(`Run 'pnpm sync-schemas' to update them.`) + process.exit(1) + } + + if (changes.length === 0) { + console.log(`✔ All schemas are up to date`) + return + } + + for (const change of changes) { + if (result.dryRun) { + console.log(`Would update ${change.file.replace(packagesRoot, 'packages')} (dry run)`) + continue + } + fs.writeFileSync(change.file, change.schema) + console.log(`Updated ${change.file.replace(packagesRoot, 'packages')}`) + } +} + +main() From 6830e0669bf8193fa32d4018bba33a2648fac87e Mon Sep 17 00:00:00 2001 From: Bram Borggreve Date: Tue, 12 Mar 2024 04:16:03 +0000 Subject: [PATCH 03/12] feat: add support for parentId to api generator --- .../api-crud-generator.spec.ts.snap | 1311 ++++++++++++++++- .../api-crud/api-crud-generator.spec.ts | 11 + .../api-crud/api-crud-schema-normalized.d.ts | 5 - .../generators/api-crud/api-crud-schema.d.ts | 8 + .../generators/api-crud/api-crud-schema.json | 8 + .../api-feature-generator.spec.ts.snap | 3 +- .../api-feature/api-feature-schema.d.ts | 8 + .../api-feature/api-feature-schema.json | 8 + ...data-__actorFileName__.service.ts.template | 10 +- ...__modelFileName__-data.service.ts.template | 2 +- ...create-__modelFileName__.input.ts.template | 5 + ...d-many-__modelFileName__.input.ts.template | 4 + ...-where-__actorFileName__.input.ts.template | 2 +- .../__modelFileName__.entity.ts.template | 7 + ...e__-__actorFileName__.resolver.ts.template | 26 +- .../src/lib/api-crud/generate-api-crud.ts | 15 +- .../api-crud/get-api-crud-substitutions.ts | 3 + .../lib/api-crud/normalize-api-crud-schema.ts | 7 +- .../lib/api/generate-api-lib-data-access.ts | 1 - .../src/lib/api/get-api-substitutions.ts | 3 + .../lib/api/normalize-api-feature-schema.ts | 2 + .../tools/src/lib/prisma/get-prisma-models.ts | 2 +- 22 files changed, 1417 insertions(+), 34 deletions(-) delete mode 100644 libs/tools/src/generators/api-crud/api-crud-schema-normalized.d.ts diff --git a/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap b/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap index d389fd1..a85febf 100644 --- a/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap +++ b/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap @@ -1,5 +1,1314 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`api-crud generator should create crud with parent ID 1`] = ` +{ + "company": { + "children": { + "data-access": { + "children": { + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-company-data-access", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-company-data-access\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/company/data-access/README.md", + }, + "jest.config.ts": { + "content": [ + "/* eslint-disable */", + "export default {", + "displayName: 'test-company-data-access',", + "preset: '../../../../jest.preset.js',", + "testEnvironment: 'node',", + "transform: {", + "'^.+\\\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }],", + "},", + "moduleFileExtensions: ['ts', 'js', 'html'],", + "coverageDirectory: '../../../../coverage/libs/test/company/data-access',", + "};", + ], + "isBinary": false, + "path": "libs/test/company/data-access/jest.config.ts", + }, + "project.json": { + "content": [ + "{", + ""name": "test-company-data-access",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/company/data-access/src",", + ""projectType": "library",", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "},", + ""test": {", + ""executor": "@nx/jest:jest",", + ""outputs": ["{workspaceRoot}/coverage/{projectRoot}"],", + ""options": {", + ""jestConfig": "libs/test/company/data-access/jest.config.ts"", + "}", + "}", + "},", + ""tags": ["app:test", "type:data-access"]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [ + "export * from './lib/test-company.data-access.module';", + "export * from './lib/test-company.service';", + "export * from './lib/entity/company.entity';", + "export * from './lib/dto/admin-create-company.input';", + "export * from './lib/dto/admin-find-many-company.input';", + "export * from './lib/dto/admin-update-company.input';", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/index.ts", + }, + "lib": { + "children": { + "dto": { + "children": { + "admin-create-company.input.ts": { + "content": [ + "import { Field, InputType } from '@nestjs/graphql';", + "@InputType()", + "export class AdminCreateCompanyInput {", + "@Field()", + "name!: string;", + "@Field()", + "location!: string;", + "@Field({ nullable: true })", + "phone?: string;", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/dto/admin-create-company.input.ts", + }, + "admin-find-many-company.input.ts": { + "content": [ + "import { Field, InputType } from '@nestjs/graphql';", + "import { PagingInput } from '@proj/test-core-data-access';", + "@InputType()", + "export class AdminFindManyCompanyInput extends PagingInput() {", + "@Field(() => String)", + "ownerId!: string;", + "@Field({ nullable: true })", + "search?: string;", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/dto/admin-find-many-company.input.ts", + }, + "admin-update-company.input.ts": { + "content": [ + "import { Field, InputType } from '@nestjs/graphql';", + "@InputType()", + "export class AdminUpdateCompanyInput {", + "@Field({ nullable: true })", + "name?: string;", + "@Field({ nullable: true })", + "location?: string;", + "@Field({ nullable: true })", + "phone?: string;", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/dto/admin-update-company.input.ts", + }, + }, + "path": "libs/test/company/data-access/src/lib/dto", + }, + "entity": { + "children": { + "company.entity.ts": { + "content": [ + "import { Field, ObjectType } from '@nestjs/graphql';", + "import { PagingResponse } from '@proj/test-core-data-access';", + "import { User } from '@proj/test-user-data-access';", + "@ObjectType()", + "export class Company {", + "@Field()", + "id!: string;", + "@Field({ nullable: true })", + "createdAt?: Date;", + "@Field({ nullable: true })", + "updatedAt?: Date;", + "@Field()", + "name!: string;", + "@Field()", + "location!: string;", + "@Field({ nullable: true })", + "phone?: string;", + "@Field(() => String)", + "ownerId!: string;", + "@Field(() => () => User, { nullable: true })", + "owner?: User;", + "}", + "@ObjectType()", + "export class CompanyPaging extends PagingResponse(Company) {}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/entity/company.entity.ts", + }, + }, + "path": "libs/test/company/data-access/src/lib/entity", + }, + "helpers": { + "children": { + "get-company-where-admin.input.ts": { + "content": [ + "import { Prisma } from '@prisma/client';", + "import { AdminFindManyCompanyInput } from '../dto/admin-find-many-company.input';", + "export function getCompanyWhereAdminInput(", + "input: AdminFindManyCompanyInput", + "): Prisma.CompanyWhereInput {", + "const where: Prisma.CompanyWhereInput = { ownerId: input.ownerId };", + "if (input.search) {", + "where.OR = [", + "{ id: { contains: input.search, mode: 'insensitive' } },", + "{ name: { contains: input.search, mode: 'insensitive' } },", + "];", + "}", + "return where;", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/helpers/get-company-where-admin.input.ts", + }, + }, + "path": "libs/test/company/data-access/src/lib/helpers", + }, + "test-company-data-admin.service.ts": { + "content": [ + "import { Injectable } from '@nestjs/common';", + "import { AdminCreateCompanyInput } from './dto/admin-create-company.input';", + "import { AdminFindManyCompanyInput } from './dto/admin-find-many-company.input';", + "import { AdminUpdateCompanyInput } from './dto/admin-update-company.input';", + "import { CompanyPaging } from './entity/company.entity';", + "import { getCompanyWhereAdminInput } from './helpers/get-company-where-admin.input';", + "import { TestCompanyDataService } from './test-company-data.service';", + "@Injectable()", + "export class TestCompanyDataAdminService {", + "constructor(private readonly data: TestCompanyDataService) {}", + "async createCompany(ownerId: string, input: AdminCreateCompanyInput) {", + "return this.data.create(input);", + "}", + "async deleteCompany(ownerId: string, companyId: string) {", + "return this.data.delete(companyId);", + "}", + "async findManyCompany(", + "input: AdminFindManyCompanyInput", + "): Promise {", + "return this.data.findMany({", + "orderBy: { createdAt: 'desc' },", + "where: getCompanyWhereAdminInput(input),", + "limit: input.limit,", + "page: input.page,", + "});", + "}", + "async findOneCompany(ownerId: string, companyId: string) {", + "return this.data.findOne(companyId);", + "}", + "async updateCompany(", + "ownerId: string,", + "companyId: string,", + "input: AdminUpdateCompanyInput", + ") {", + "return this.data.update(companyId, input);", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/test-company-data-admin.service.ts", + }, + "test-company-data.service.ts": { + "content": [ + "import { Injectable } from '@nestjs/common';", + "import { Prisma } from '@prisma/client';", + "import {", + "TestCoreService,", + "type PagingInputFields,", + "} from '@proj/test-core-data-access';", + "import { CompanyPaging } from './entity/company.entity';", + "@Injectable()", + "export class TestCompanyDataService {", + "constructor(private readonly core: TestCoreService) {}", + "async create(input: Prisma.CompanyUncheckedCreateInput) {", + "return this.core.data.company.create({ data: input });", + "}", + "async delete(companyId: string) {", + "const deleted = await this.core.data.company.delete({", + "where: { id: companyId },", + "});", + "return !!deleted;", + "}", + "async findMany({", + "limit = 10,", + "page = 1,", + "...input", + "}: Prisma.CompanyFindManyArgs & PagingInputFields): Promise {", + "return this.core.data.company", + ".paginate(input)", + ".withPages({ limit, page })", + ".then(([data, meta]) => ({ data, meta }));", + "}", + "async findOne(companyId: string) {", + "return this.core.data.company.findUnique({ where: { id: companyId } });", + "}", + "async update(companyId: string, input: Prisma.CompanyUpdateInput) {", + "return this.core.data.company.update({", + "where: { id: companyId },", + "data: input,", + "});", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/test-company-data.service.ts", + }, + "test-company.data-access.module.ts": { + "content": [ + "import { Module } from '@nestjs/common';", + "import { TestCoreDataAccessModule } from '@proj/test-core-data-access';", + "import { TestCompanyService } from './test-company.service';", + "import { TestCompanyDataService } from './test-company-data.service';", + "import { TestCompanyDataAdminService } from './test-company-data-admin.service';", + "@Module({", + "imports: [TestCoreDataAccessModule],", + "providers: [", + "TestCompanyService,", + "TestCompanyDataService,", + "TestCompanyDataAdminService,", + "],", + "exports: [TestCompanyService],", + "})", + "export class TestCompanyDataAccessModule {}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/test-company.data-access.module.ts", + }, + "test-company.service.ts": { + "content": [ + "import { Injectable } from '@nestjs/common';", + "import { TestCompanyDataService } from './test-company-data.service';", + "import { TestCompanyDataAdminService } from './test-company-data-admin.service';", + "@Injectable()", + "export class TestCompanyService {", + "constructor(", + "readonly data: TestCompanyDataService,", + "readonly admin: TestCompanyDataAdminService", + ") {}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/test-company.service.ts", + }, + }, + "path": "libs/test/company/data-access/src/lib", + }, + }, + "path": "libs/test/company/data-access/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""extends": "../../../../tsconfig.base.json",", + ""compilerOptions": {", + ""module": "commonjs",", + ""forceConsistentCasingInFileNames": true,", + ""strict": true,", + ""noImplicitOverride": true,", + ""noPropertyAccessFromIndexSignature": true,", + ""noImplicitReturns": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "},", + "{", + ""path": "./tsconfig.spec.json"", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""declaration": true,", + ""types": ["node"],", + ""target": "es6",", + ""strictNullChecks": true,", + ""noImplicitAny": true,", + ""strictBindCallApply": true,", + ""forceConsistentCasingInFileNames": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""include": ["src/**/*.ts"],", + ""exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/tsconfig.lib.json", + }, + "tsconfig.spec.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""module": "commonjs",", + ""types": ["jest", "node"]", + "},", + ""include": [", + ""jest.config.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.d.ts"", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/tsconfig.spec.json", + }, + }, + "path": "libs/test/company/data-access", + }, + "feature": { + "children": { + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-company-feature", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-company-feature\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/company/feature/README.md", + }, + "jest.config.ts": { + "content": [ + "/* eslint-disable */", + "export default {", + "displayName: 'test-company-feature',", + "preset: '../../../../jest.preset.js',", + "testEnvironment: 'node',", + "transform: {", + "'^.+\\\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }],", + "},", + "moduleFileExtensions: ['ts', 'js', 'html'],", + "coverageDirectory: '../../../../coverage/libs/test/company/feature',", + "};", + ], + "isBinary": false, + "path": "libs/test/company/feature/jest.config.ts", + }, + "project.json": { + "content": [ + "{", + ""name": "test-company-feature",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/company/feature/src",", + ""projectType": "library",", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "},", + ""test": {", + ""executor": "@nx/jest:jest",", + ""outputs": ["{workspaceRoot}/coverage/{projectRoot}"],", + ""options": {", + ""jestConfig": "libs/test/company/feature/jest.config.ts"", + "}", + "}", + "},", + ""tags": ["app:test", "type:feature"]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [ + "export * from './lib/test-company.feature.module';", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/index.ts", + }, + "lib": { + "children": { + "test-company-admin.resolver.ts": { + "content": [ + "import { Resolver } from '@nestjs/graphql';", + "import { TestCompanyService } from '@proj/test-company-data-access';", + "import {", + "TestAuthGraphQLAdminGuard,", + "CtxUserId,", + "} from '@proj/test-auth-data-access';", + "import { Mutation, Query, Args } from '@nestjs/graphql';", + "import { UseGuards } from '@nestjs/common';", + "import {", + "AdminCreateCompanyInput,", + "AdminFindManyCompanyInput,", + "Company,", + "CompanyPaging,", + "AdminUpdateCompanyInput,", + "} from '@proj/test-company-data-access';", + "@Resolver()", + "@UseGuards(TestAuthGraphQLAdminGuard)", + "export class TestCompanyAdminResolver {", + "constructor(private readonly service: TestCompanyService) {}", + "@Mutation(() => Company, { nullable: true })", + "adminCreateCompany(", + "@CtxUserId() ownerId: string,", + "@Args('input') input: AdminCreateCompanyInput", + ") {", + "return this.service.admin.createCompany(ownerId, input);", + "}", + "@Mutation(() => Boolean, { nullable: true })", + "adminDeleteCompany(", + "@CtxUserId() ownerId: string,", + "@Args('companyId') companyId: string", + ") {", + "return this.service.admin.deleteCompany(ownerId, companyId);", + "}", + "@Query(() => CompanyPaging)", + "adminFindManyCompany(@Args('input') input: AdminFindManyCompanyInput) {", + "return this.service.admin.findManyCompany(input);", + "}", + "@Query(() => Company, { nullable: true })", + "adminFindOneCompany(", + "@CtxUserId() ownerId: string,", + "@Args('companyId') companyId: string", + ") {", + "return this.service.admin.findOneCompany(ownerId, companyId);", + "}", + "@Mutation(() => Company, { nullable: true })", + "adminUpdateCompany(", + "@CtxUserId() ownerId: string,", + "@Args('companyId') companyId: string,", + "@Args('input') input: AdminUpdateCompanyInput", + ") {", + "return this.service.admin.updateCompany(ownerId, companyId, input);", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/test-company-admin.resolver.ts", + }, + "test-company.feature.module.ts": { + "content": [ + "import { Module } from '@nestjs/common';", + "import { TestCompanyDataAccessModule } from '@proj/test-company-data-access';", + "import { TestCompanyResolver } from './test-company.resolver';", + "import { TestCompanyAdminResolver } from './test-company-admin.resolver';", + "@Module({", + "imports: [TestCompanyDataAccessModule],", + "providers: [TestCompanyResolver, TestCompanyAdminResolver],", + "})", + "export class TestCompanyFeatureModule {}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/test-company.feature.module.ts", + }, + "test-company.resolver.ts": { + "content": [ + "import { Resolver } from '@nestjs/graphql';", + "import { TestCompanyService } from '@proj/test-company-data-access';", + "import { Company } from '@proj/test-company-data-access';", + "@Resolver(() => Company)", + "export class TestCompanyResolver {", + "constructor(private readonly service: TestCompanyService) {}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/test-company.resolver.ts", + }, + }, + "path": "libs/test/company/feature/src/lib", + }, + }, + "path": "libs/test/company/feature/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""extends": "../../../../tsconfig.base.json",", + ""compilerOptions": {", + ""module": "commonjs",", + ""forceConsistentCasingInFileNames": true,", + ""strict": true,", + ""noImplicitOverride": true,", + ""noPropertyAccessFromIndexSignature": true,", + ""noImplicitReturns": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "},", + "{", + ""path": "./tsconfig.spec.json"", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""declaration": true,", + ""types": ["node"],", + ""target": "es6",", + ""strictNullChecks": true,", + ""noImplicitAny": true,", + ""strictBindCallApply": true,", + ""forceConsistentCasingInFileNames": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""include": ["src/**/*.ts"],", + ""exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/tsconfig.lib.json", + }, + "tsconfig.spec.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""module": "commonjs",", + ""types": ["jest", "node"]", + "},", + ""include": [", + ""jest.config.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.d.ts"", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/tsconfig.spec.json", + }, + }, + "path": "libs/test/company/feature", + }, + }, + "path": "libs/test/company", + }, + "core": { + "children": { + "data-access": { + "children": { + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-core-data-access", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-core-data-access\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/core/data-access/README.md", + }, + "jest.config.ts": { + "content": [ + "/* eslint-disable */", + "export default {", + "displayName: 'test-core-data-access',", + "preset: '../../../../jest.preset.js',", + "testEnvironment: 'node',", + "transform: {", + "'^.+\\\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }],", + "},", + "moduleFileExtensions: ['ts', 'js', 'html'],", + "coverageDirectory: '../../../../coverage/libs/test/core/data-access',", + "};", + ], + "isBinary": false, + "path": "libs/test/core/data-access/jest.config.ts", + }, + "project.json": { + "content": [ + "{", + ""name": "test-core-data-access",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/core/data-access/src",", + ""projectType": "library",", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "},", + ""test": {", + ""executor": "@nx/jest:jest",", + ""outputs": ["{workspaceRoot}/coverage/{projectRoot}"],", + ""options": {", + ""jestConfig": "libs/test/core/data-access/jest.config.ts"", + "}", + "}", + "},", + ""tags": []", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [ + "export * from './lib/test-core-data-access.module';", + ], + "isBinary": false, + "path": "libs/test/core/data-access/src/index.ts", + }, + "lib": { + "children": { + "test-core-data-access.module.ts": { + "content": [ + "import { Module } from '@nestjs/common';", + "import { TestCoreService } from './test-core.service';", + "@Module({", + "controllers: [],", + "providers: [TestCoreService],", + "exports: [],", + "})", + "export class TestCoreDataAccessModule {}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/src/lib/test-core-data-access.module.ts", + }, + "test-core.service.spec.ts": { + "content": [ + "import { Test, TestingModule } from '@nestjs/testing';", + "import { TestCoreService } from './test-core.service';", + "describe('TestCoreService', () => {", + "let service: TestCoreService;", + "beforeEach(async () => {", + "const module: TestingModule = await Test.createTestingModule({", + "providers: [TestCoreService],", + "}).compile();", + "service = module.get(TestCoreService);", + "});", + "it('should be defined', () => {", + "expect(service).toBeDefined();", + "});", + "});", + ], + "isBinary": false, + "path": "libs/test/core/data-access/src/lib/test-core.service.spec.ts", + }, + "test-core.service.ts": { + "content": [ + "import { Injectable } from '@nestjs/common';", + "@Injectable()", + "export class TestCoreService {}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/src/lib/test-core.service.ts", + }, + }, + "path": "libs/test/core/data-access/src/lib", + }, + }, + "path": "libs/test/core/data-access/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""extends": "../../../../tsconfig.base.json",", + ""compilerOptions": {", + ""module": "commonjs",", + ""forceConsistentCasingInFileNames": true,", + ""strict": true,", + ""noImplicitOverride": true,", + ""noPropertyAccessFromIndexSignature": true,", + ""noImplicitReturns": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "},", + "{", + ""path": "./tsconfig.spec.json"", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""declaration": true,", + ""types": ["node"],", + ""target": "es6",", + ""strictNullChecks": true,", + ""noImplicitAny": true,", + ""strictBindCallApply": true,", + ""forceConsistentCasingInFileNames": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""include": ["src/**/*.ts"],", + ""exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/tsconfig.lib.json", + }, + "tsconfig.spec.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""module": "commonjs",", + ""types": ["jest", "node"]", + "},", + ""include": [", + ""jest.config.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.d.ts"", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/tsconfig.spec.json", + }, + }, + "path": "libs/test/core/data-access", + }, + "feature": { + "children": { + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-core-feature", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-core-feature\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/core/feature/README.md", + }, + "jest.config.ts": { + "content": [ + "/* eslint-disable */", + "export default {", + "displayName: 'test-core-feature',", + "preset: '../../../../jest.preset.js',", + "testEnvironment: 'node',", + "transform: {", + "'^.+\\\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }],", + "},", + "moduleFileExtensions: ['ts', 'js', 'html'],", + "coverageDirectory: '../../../../coverage/libs/test/core/feature',", + "};", + ], + "isBinary": false, + "path": "libs/test/core/feature/jest.config.ts", + }, + "project.json": { + "content": [ + "{", + ""name": "test-core-feature",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/core/feature/src",", + ""projectType": "library",", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "},", + ""test": {", + ""executor": "@nx/jest:jest",", + ""outputs": ["{workspaceRoot}/coverage/{projectRoot}"],", + ""options": {", + ""jestConfig": "libs/test/core/feature/jest.config.ts"", + "}", + "}", + "},", + ""tags": []", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [ + "export * from './lib/test-core-feature.module';", + ], + "isBinary": false, + "path": "libs/test/core/feature/src/index.ts", + }, + "lib": { + "children": { + "test-core-feature.module.ts": { + "content": [ + "import { Module } from '@nestjs/common';", + "import { TestCompanyFeatureModule } from '@proj/test-company-feature';", + "@Module({", + "controllers: [],", + "providers: [],", + "exports: [],", + "})", + "export class TestCoreFeatureModule {}", + ], + "isBinary": false, + "path": "libs/test/core/feature/src/lib/test-core-feature.module.ts", + }, + }, + "path": "libs/test/core/feature/src/lib", + }, + }, + "path": "libs/test/core/feature/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""extends": "../../../../tsconfig.base.json",", + ""compilerOptions": {", + ""module": "commonjs",", + ""forceConsistentCasingInFileNames": true,", + ""strict": true,", + ""noImplicitOverride": true,", + ""noPropertyAccessFromIndexSignature": true,", + ""noImplicitReturns": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "},", + "{", + ""path": "./tsconfig.spec.json"", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""declaration": true,", + ""types": ["node"],", + ""target": "es6",", + ""strictNullChecks": true,", + ""noImplicitAny": true,", + ""strictBindCallApply": true,", + ""forceConsistentCasingInFileNames": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""include": ["src/**/*.ts"],", + ""exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/tsconfig.lib.json", + }, + "tsconfig.spec.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""module": "commonjs",", + ""types": ["jest", "node"]", + "},", + ""include": [", + ""jest.config.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.d.ts"", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/tsconfig.spec.json", + }, + }, + "path": "libs/test/core/feature", + }, + }, + "path": "libs/test/core", + }, + "sdk": { + "children": { + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/sdk/.eslintrc.json", + }, + "README.md": { + "content": [ + "# sdk", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test sdk\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/sdk/README.md", + }, + "jest.config.ts": { + "content": [ + "/* eslint-disable */", + "export default {", + "displayName: 'sdk',", + "preset: '../../../jest.preset.js',", + "testEnvironment: 'node',", + "transform: {", + "'^.+\\\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }],", + "},", + "moduleFileExtensions: ['ts', 'js', 'html'],", + "coverageDirectory: '../../../coverage/libs/test/sdk',", + "};", + ], + "isBinary": false, + "path": "libs/test/sdk/jest.config.ts", + }, + "project.json": { + "content": [ + "{", + ""name": "sdk",", + ""$schema": "../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/sdk/src",", + ""projectType": "library",", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "},", + ""test": {", + ""executor": "@nx/jest:jest",", + ""outputs": ["{workspaceRoot}/coverage/{projectRoot}"],", + ""options": {", + ""jestConfig": "libs/test/sdk/jest.config.ts"", + "}", + "}", + "},", + ""tags": []", + "}", + ], + "isBinary": false, + "path": "libs/test/sdk/project.json", + }, + "src": { + "children": { + "graphql": { + "children": { + "feature-company.graphql": { + "content": [ + "fragment CompanyDetails on Company {", + "createdAt", + "id", + "name", + "location", + "phone", + "updatedAt", + "}", + "query adminFindManyCompany($input: AdminFindManyCompanyInput!) {", + "paging: adminFindManyCompany(input: $input) {", + "data {", + "...CompanyDetails", + "}", + "meta {", + "...PagingMetaDetails", + "}", + "}", + "}", + "query adminFindOneCompany($companyId: String!) {", + "item: adminFindOneCompany(companyId: $companyId) {", + "...CompanyDetails", + "}", + "}", + "mutation adminCreateCompany($input: AdminCreateCompanyInput!) {", + "created: adminCreateCompany(input: $input) {", + "...CompanyDetails", + "}", + "}", + "mutation adminUpdateCompany(", + "$companyId: String!", + "$input: AdminUpdateCompanyInput!", + ") {", + "updated: adminUpdateCompany(companyId: $companyId, input: $input) {", + "...CompanyDetails", + "}", + "}", + "mutation adminDeleteCompany($companyId: String!) {", + "deleted: adminDeleteCompany(companyId: $companyId)", + "}", + ], + "isBinary": false, + "path": "libs/test/sdk/src/graphql/feature-company.graphql", + }, + }, + "path": "libs/test/sdk/src/graphql", + }, + "index.ts": { + "content": [ + "export * from './lib/sdk.module';", + ], + "isBinary": false, + "path": "libs/test/sdk/src/index.ts", + }, + "lib": { + "children": { + "sdk.module.ts": { + "content": [ + "import { Module } from '@nestjs/common';", + "@Module({", + "controllers: [],", + "providers: [],", + "exports: [],", + "})", + "export class SdkModule {}", + ], + "isBinary": false, + "path": "libs/test/sdk/src/lib/sdk.module.ts", + }, + }, + "path": "libs/test/sdk/src/lib", + }, + }, + "path": "libs/test/sdk/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""extends": "../../../tsconfig.base.json",", + ""compilerOptions": {", + ""module": "commonjs",", + ""forceConsistentCasingInFileNames": true,", + ""strict": true,", + ""noImplicitOverride": true,", + ""noPropertyAccessFromIndexSignature": true,", + ""noImplicitReturns": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "},", + "{", + ""path": "./tsconfig.spec.json"", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/sdk/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../dist/out-tsc",", + ""declaration": true,", + ""types": ["node"],", + ""target": "es6",", + ""strictNullChecks": true,", + ""noImplicitAny": true,", + ""strictBindCallApply": true,", + ""forceConsistentCasingInFileNames": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""include": ["src/**/*.ts"],", + ""exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]", + "}", + ], + "isBinary": false, + "path": "libs/test/sdk/tsconfig.lib.json", + }, + "tsconfig.spec.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../dist/out-tsc",", + ""module": "commonjs",", + ""types": ["jest", "node"]", + "},", + ""include": [", + ""jest.config.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.d.ts"", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/sdk/tsconfig.spec.json", + }, + }, + "path": "libs/test/sdk", + }, +} +`; + exports[`api-crud generator should run successfully 1`] = ` { "company": { @@ -255,7 +1564,7 @@ exports[`api-crud generator should run successfully 1`] = ` "@Injectable()", "export class TestCompanyDataService {", "constructor(private readonly core: TestCoreService) {}", - "async create(input: Prisma.CompanyCreateInput) {", + "async create(input: Prisma.CompanyUncheckedCreateInput) {", "return this.core.data.company.create({ data: input });", "}", "async delete(companyId: string) {", diff --git a/libs/tools/src/generators/api-crud/api-crud-generator.spec.ts b/libs/tools/src/generators/api-crud/api-crud-generator.spec.ts index b184ef0..bcfd3dd 100644 --- a/libs/tools/src/generators/api-crud/api-crud-generator.spec.ts +++ b/libs/tools/src/generators/api-crud/api-crud-generator.spec.ts @@ -21,6 +21,17 @@ describe('api-crud generator', () => { const config = readProjectConfiguration(tree, 'test') expect(config).toBeDefined() + const contents = getRecursiveFileContents({ + tree, + path: 'libs/test', + }) + expect(contents).toMatchSnapshot() + }) + it('should create crud with parent ID', async () => { + await apiCrudGenerator(tree, { ...options, modelParent: 'User', modelParentId: 'ownerId' }) + const config = readProjectConfiguration(tree, 'test') + expect(config).toBeDefined() + const contents = getRecursiveFileContents({ tree, path: 'libs/test', diff --git a/libs/tools/src/generators/api-crud/api-crud-schema-normalized.d.ts b/libs/tools/src/generators/api-crud/api-crud-schema-normalized.d.ts deleted file mode 100644 index 414e28c..0000000 --- a/libs/tools/src/generators/api-crud/api-crud-schema-normalized.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface NormalizedApiCrudSchema extends ApiCrudGeneratorSchema { - label: string - npmScope: string - fields?: PrismaModelField[] -} diff --git a/libs/tools/src/generators/api-crud/api-crud-schema.d.ts b/libs/tools/src/generators/api-crud/api-crud-schema.d.ts index a364b59..184507e 100644 --- a/libs/tools/src/generators/api-crud/api-crud-schema.d.ts +++ b/libs/tools/src/generators/api-crud/api-crud-schema.d.ts @@ -22,4 +22,12 @@ export interface ApiCrudGeneratorSchema { * The name of the model for this feature. */ model: string + /** + * The id field of the model owner. Generally 'userId' or 'ownerId'. + */ + modelParentId?: string + /** + * The name of the model owner. Generally 'User'. + */ + modelParent?: string } diff --git a/libs/tools/src/generators/api-crud/api-crud-schema.json b/libs/tools/src/generators/api-crud/api-crud-schema.json index 2b12532..0834cbd 100644 --- a/libs/tools/src/generators/api-crud/api-crud-schema.json +++ b/libs/tools/src/generators/api-crud/api-crud-schema.json @@ -25,6 +25,14 @@ "type": "string", "description": "The name of the model for this feature.", "x-prompt": "What is the name of the model for this feature?" + }, + "modelParentId": { + "type": "string", + "description": "The id field of the model owner. Generally 'userId' or 'ownerId'." + }, + "modelParent": { + "type": "string", + "description": "The name of the model owner. Generally 'User'." } }, "required": ["app", "actor", "model"] diff --git a/libs/tools/src/generators/api-feature/__snapshots__/api-feature-generator.spec.ts.snap b/libs/tools/src/generators/api-feature/__snapshots__/api-feature-generator.spec.ts.snap index b8bb512..9a3d158 100644 --- a/libs/tools/src/generators/api-feature/__snapshots__/api-feature-generator.spec.ts.snap +++ b/libs/tools/src/generators/api-feature/__snapshots__/api-feature-generator.spec.ts.snap @@ -108,7 +108,7 @@ import { TestPaging } from './entity/test.entity'; export class ApiTestDataService { constructor(private readonly core: ApiCoreService) {} - async create(input: Prisma.TestCreateInput) { + async create(input: Prisma.TestUncheckedCreateInput) { return this.core.data.test.create({ data: input }); } @@ -445,7 +445,6 @@ export class ApiTestResolver { exports[`api-feature generator should generate the minimal feature libraries 3`] = ` "export * from './lib/api-test.data-access.module'; export * from './lib/api-test.service'; -export * from './lib/entity/test.entity'; " `; diff --git a/libs/tools/src/generators/api-feature/api-feature-schema.d.ts b/libs/tools/src/generators/api-feature/api-feature-schema.d.ts index 06b0fc4..9ff1adf 100644 --- a/libs/tools/src/generators/api-feature/api-feature-schema.d.ts +++ b/libs/tools/src/generators/api-feature/api-feature-schema.d.ts @@ -10,6 +10,14 @@ export interface ApiFeatureGeneratorSchema { * The name of the model for this feature. */ model: string + /** + * The id field of the model owner. Generally 'userId' or 'ownerId'. + */ + modelParentId?: string + /** + * The name of the model owner. Generally 'User'. + */ + modelParent?: string /** * The name of the application you are adding the feature to. */ diff --git a/libs/tools/src/generators/api-feature/api-feature-schema.json b/libs/tools/src/generators/api-feature/api-feature-schema.json index 7a4b6fa..5f0c31b 100644 --- a/libs/tools/src/generators/api-feature/api-feature-schema.json +++ b/libs/tools/src/generators/api-feature/api-feature-schema.json @@ -13,6 +13,14 @@ "index": 0 } }, + "modelParentId": { + "type": "string", + "description": "The id field of the model owner. Generally 'userId' or 'ownerId'." + }, + "modelParent": { + "type": "string", + "description": "The name of the model owner. Generally 'User'." + }, "app": { "type": "string", "description": "The name of the application you are adding the feature to.", diff --git a/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data-__actorFileName__.service.ts.template b/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data-__actorFileName__.service.ts.template index af52c11..bf96a43 100644 --- a/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data-__actorFileName__.service.ts.template +++ b/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data-__actorFileName__.service.ts.template @@ -11,11 +11,11 @@ import { <%= app.className %><%= model.className %>DataService } from './<%= app export class <%= app.className %><%= model.className %>Data<%= actor.className %>Service { constructor(private readonly data: <%= app.className %><%= model.className %>DataService) {} - async create<%= model.className %>(input: <%= actor.className %>Create<%= model.className %>Input) { - return this.data.create(input) + async create<%= model.className %>(<% if(parent){ %><%= parentId %>: string, <% } %>input: <%= actor.className %>Create<%= model.className %>Input) { + return this.data.create(<% if(parent && parent.className !== 'User'){ %>{...input, <%= parentId %> }<% } else { %>input<% } %>) } - async delete<%= model.className %>(<%= model.propertyName %>Id: string) { + async delete<%= model.className %>(<% if(parent){ %><%= parentId %>: string, <% } %><%= model.propertyName %>Id: string) { return this.data.delete(<%= model.propertyName %>Id) } @@ -28,11 +28,11 @@ export class <%= app.className %><%= model.className %>Data<%= actor.className % }) } - async findOne<%= model.className %>(<%= model.propertyName %>Id: string) { + async findOne<%= model.className %>(<% if(parent){ %><%= parentId %>: string, <% } %><%= model.propertyName %>Id: string) { return this.data.findOne(<%= model.propertyName %>Id) } - async update<%= model.className %>(<%= model.propertyName %>Id: string, input: <%= actor.className %>Update<%= model.className %>Input) { + async update<%= model.className %>(<% if(parent){ %><%= parentId %>: string, <% } %><%= model.propertyName %>Id: string, input: <%= actor.className %>Update<%= model.className %>Input) { return this.data.update(<%= model.propertyName %>Id, input) } } diff --git a/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data.service.ts.template b/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data.service.ts.template index 537ccdc..d87adb3 100644 --- a/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data.service.ts.template +++ b/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data.service.ts.template @@ -7,7 +7,7 @@ import { <%= model.className %>Paging } from './entity/<%= model.fileName %>.ent export class <%= app.className %><%= model.className %>DataService { constructor(private readonly core: <%= app.className %>CoreService) {} - async create(input: Prisma.<%= model.className %>CreateInput) { + async create(input: Prisma.<%= model.className %>UncheckedCreateInput) { return this.core.data.<%= model.propertyName %>.create({ data: input }) } diff --git a/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__actorFileName__-create-__modelFileName__.input.ts.template b/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__actorFileName__-create-__modelFileName__.input.ts.template index 403e404..5d11e25 100644 --- a/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__actorFileName__-create-__modelFileName__.input.ts.template +++ b/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__actorFileName__-create-__modelFileName__.input.ts.template @@ -1,4 +1,5 @@ import { Field, InputType } from '@nestjs/graphql' +<% if(parent && parent.className !== 'User'){ %> import { <%= parent.className %> } from '@<%= npmScope %>/<%= app.fileName %>-<%= parent.fileName %>-data-access' <% } %> @InputType() export class <%= actor.className %>Create<%= model.className %>Input { @@ -6,4 +7,8 @@ export class <%= actor.className %>Create<%= model.className %>Input { @Field(<% if(field.optional){ %>{ nullable: true }<% } %>) <%= field.name %><% if(field.optional){ %>?<% } else { %>!<% } %>: <%= field.type %> <% } %> +<% if(parent && parent.className !== 'User'){ %> + @Field(() => String) + <%= parentId %>!: string +<% } %> } diff --git a/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__actorFileName__-find-many-__modelFileName__.input.ts.template b/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__actorFileName__-find-many-__modelFileName__.input.ts.template index f7e96aa..c35f77a 100644 --- a/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__actorFileName__-find-many-__modelFileName__.input.ts.template +++ b/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__actorFileName__-find-many-__modelFileName__.input.ts.template @@ -3,6 +3,10 @@ import { PagingInput } from '@<%= npmScope %>/<%= app.fileName %>-core-data-acce @InputType() export class <%= actor.className %>FindMany<%= model.className %>Input extends PagingInput() { +<% if(parent){ %> + @Field(() => String) + <%= parentId %>!: string +<% } %> @Field({ nullable: true }) search?: string } diff --git a/libs/tools/src/lib/api-crud/files/data-access/lib/helpers/get-__modelFileName__-where-__actorFileName__.input.ts.template b/libs/tools/src/lib/api-crud/files/data-access/lib/helpers/get-__modelFileName__-where-__actorFileName__.input.ts.template index fbf4f66..e017349 100644 --- a/libs/tools/src/lib/api-crud/files/data-access/lib/helpers/get-__modelFileName__-where-__actorFileName__.input.ts.template +++ b/libs/tools/src/lib/api-crud/files/data-access/lib/helpers/get-__modelFileName__-where-__actorFileName__.input.ts.template @@ -2,7 +2,7 @@ import { Prisma } from '@prisma/client' import { <%= actor.className %>FindMany<%= model.className %>Input } from '../dto/<%= actor.fileName %>-find-many-<%= model.fileName %>.input' export function get<%= model.className %>Where<%= actor.className %>Input(input: <%= actor.className %>FindMany<%= model.className %>Input): Prisma.<%= model.className %>WhereInput { - const where: Prisma.<%= model.className %>WhereInput = {} + const where: Prisma.<%= model.className %>WhereInput = {<% if(parent){ %><%= parentId %>: input.<%= parentId %><% } %>} if (input.search) { where.OR = [ diff --git a/libs/tools/src/lib/api-crud/files/entity/lib/entity/__modelFileName__.entity.ts.template b/libs/tools/src/lib/api-crud/files/entity/lib/entity/__modelFileName__.entity.ts.template index 4f77fda..6f1f54a 100644 --- a/libs/tools/src/lib/api-crud/files/entity/lib/entity/__modelFileName__.entity.ts.template +++ b/libs/tools/src/lib/api-crud/files/entity/lib/entity/__modelFileName__.entity.ts.template @@ -1,5 +1,6 @@ import { Field, ObjectType } from '@nestjs/graphql' import { PagingResponse } from '@<%= npmScope %>/<%= app.fileName %>-core-data-access' +<% if(parent){ %> import { <%= parent.className %> } from '@<%= npmScope %>/<%= app.fileName %>-<%= parent.fileName %>-data-access' <% } %> @ObjectType() export class <%= model.className %> { @@ -13,6 +14,12 @@ export class <%= model.className %> { @Field(<% if(field.optional){ %>{ nullable: true }<% } %>) <%= field.name %><% if(field.optional){ %>?<% } else { %>!<% } %>: <%= field.type %> <% } %> +<% if(parent){ %> + @Field(() => String) + <%= parentId %>!: string + @Field(() => () => <%= parent.className %>, { nullable: true }) + <%= parentPropertyId %>?: <%= parent.className %> +<% } %> } @ObjectType() diff --git a/libs/tools/src/lib/api-crud/files/feature/lib/__appFileName__-__modelFileName__-__actorFileName__.resolver.ts.template b/libs/tools/src/lib/api-crud/files/feature/lib/__appFileName__-__modelFileName__-__actorFileName__.resolver.ts.template index 45f5735..3e5cf72 100644 --- a/libs/tools/src/lib/api-crud/files/feature/lib/__appFileName__-__modelFileName__-__actorFileName__.resolver.ts.template +++ b/libs/tools/src/lib/api-crud/files/feature/lib/__appFileName__-__modelFileName__-__actorFileName__.resolver.ts.template @@ -1,6 +1,6 @@ import { Resolver } from '@nestjs/graphql' import { <%= app.className %><%= model.className %>Service } from '@<%= npmScope %>/<%= app.fileName %>-<%= model.fileName %>-data-access' -import { <%= app.className %>AuthGraphQL<%= actor.className %>Guard } from '@<%= npmScope %>/<%= app.fileName %>-auth-data-access' +import { <%= app.className %>AuthGraphQL<%= actor.className %>Guard<% if(parent){ %>, CtxUserId<% } %> } from '@<%= npmScope %>/<%= app.fileName %>-auth-data-access' import { Mutation, Query, Args } from '@nestjs/graphql' import { UseGuards } from '@nestjs/common' import { @@ -17,13 +17,17 @@ export class <%= app.className %><%= model.className %><%= actor.className %>Res constructor(private readonly service: <%= app.className %><%= model.className %>Service) {} @Mutation(() => <%= model.className %>, { nullable: true }) - <%= actor.propertyName %>Create<%= model.className %>(@Args('input') input: <%= actor.className %>Create<%= model.className %>Input) { - return this.service.<%= actor.propertyName %>.create<%= model.className %>(input) + <%= actor.propertyName %>Create<%= model.className %>( + <% if(parent){ %>@CtxUserId() <%= parentId %>: string,<% } %> + @Args('input') input: <%= actor.className %>Create<%= model.className %>Input) { + return this.service.<%= actor.propertyName %>.create<%= model.className %>(<% if(parent){ %><%= parentId %>, <% } %>input) } @Mutation(() => Boolean, { nullable: true }) - <%= actor.propertyName %>Delete<%= model.className %>(@Args('<%= model.propertyName %>Id') <%= model.propertyName %>Id: string) { - return this.service.<%= actor.propertyName %>.delete<%= model.className %>(<%= model.propertyName %>Id) + <%= actor.propertyName %>Delete<%= model.className %>( + <% if(parent){ %>@CtxUserId() <%= parentId %>: string,<% } %> + @Args('<%= model.propertyName %>Id') <%= model.propertyName %>Id: string) { + return this.service.<%= actor.propertyName %>.delete<%= model.className %>(<% if(parent){ %><%= parentId %>, <% } %><%= model.propertyName %>Id) } @Query(() => <%= model.className %>Paging) @@ -32,12 +36,16 @@ export class <%= app.className %><%= model.className %><%= actor.className %>Res } @Query(() => <%= model.className %>, { nullable: true }) - <%= actor.propertyName %>FindOne<%= model.className %>(@Args('<%= model.propertyName %>Id') <%= model.propertyName %>Id: string) { - return this.service.<%= actor.propertyName %>.findOne<%= model.className %>(<%= model.propertyName %>Id) + <%= actor.propertyName %>FindOne<%= model.className %>( + <% if(parent){ %>@CtxUserId() <%= parentId %>: string,<% } %> + @Args('<%= model.propertyName %>Id') <%= model.propertyName %>Id: string) { + return this.service.<%= actor.propertyName %>.findOne<%= model.className %>(<% if(parent){ %><%= parentId %>, <% } %><%= model.propertyName %>Id) } @Mutation(() => <%= model.className %>, { nullable: true }) - <%= actor.propertyName %>Update<%= model.className %>(@Args('<%= model.propertyName %>Id') <%= model.propertyName %>Id: string, @Args('input') input: <%= actor.className %>Update<%= model.className %>Input) { - return this.service.<%= actor.propertyName %>.update<%= model.className %>(<%= model.propertyName %>Id, input) + <%= actor.propertyName %>Update<%= model.className %>( + <% if(parent){ %>@CtxUserId() <%= parentId %>: string,<% } %> + @Args('<%= model.propertyName %>Id') <%= model.propertyName %>Id: string, @Args('input') input: <%= actor.className %>Update<%= model.className %>Input) { + return this.service.<%= actor.propertyName %>.update<%= model.className %>(<% if(parent){ %><%= parentId %>, <% } %><%= model.propertyName %>Id, input) } } diff --git a/libs/tools/src/lib/api-crud/generate-api-crud.ts b/libs/tools/src/lib/api-crud/generate-api-crud.ts index e93ce1a..fba92ab 100644 --- a/libs/tools/src/lib/api-crud/generate-api-crud.ts +++ b/libs/tools/src/lib/api-crud/generate-api-crud.ts @@ -42,13 +42,6 @@ export function generateApiCrud(tree: Tree, options: NormalizedApiCrudSchema) { const [dataAccessServicePath, dataAccessModulePath, featureModulePath] = requiredFields - const dataAccessExports: string[] = [ - // Add exports here - `./lib/dto/${vars.actorFileName}-create-${vars.modelFileName}.input`, - `./lib/dto/${vars.actorFileName}-find-many-${vars.modelFileName}.input`, - `./lib/dto/${vars.actorFileName}-update-${vars.modelFileName}.input`, - ] - // Generate the data access library generateFiles(tree, `${__dirname}/files/data-access`, dataAccess.sourceRoot, { ...vars }) @@ -80,6 +73,14 @@ export function generateApiCrud(tree: Tree, options: NormalizedApiCrudSchema) { // Add the crud service to the module resolvers addServiceToModuleDecorator(tree, featureModulePath, resolverName, resolverFileName) + const dataAccessExports: string[] = [ + // Add exports here + `./lib/entity/${vars.model.fileName}.entity`, + `./lib/dto/${vars.actorFileName}-create-${vars.modelFileName}.input`, + `./lib/dto/${vars.actorFileName}-find-many-${vars.modelFileName}.input`, + `./lib/dto/${vars.actorFileName}-update-${vars.modelFileName}.input`, + ] + // Add the exports to the barrel file addExports(tree, `${dataAccess.sourceRoot}/index.ts`, dataAccessExports) diff --git a/libs/tools/src/lib/api-crud/get-api-crud-substitutions.ts b/libs/tools/src/lib/api-crud/get-api-crud-substitutions.ts index e9c6b97..6815df8 100644 --- a/libs/tools/src/lib/api-crud/get-api-crud-substitutions.ts +++ b/libs/tools/src/lib/api-crud/get-api-crud-substitutions.ts @@ -18,6 +18,9 @@ export function getApiCrudSubstitutions(options: NormalizedApiCrudSchema) { model, modelFileName: model.fileName, modelPropertyNamePlural: names(pluralize.plural(options.model)).propertyName, + parent: options.modelParent ? names(options.modelParent) : undefined, + parentId: options.modelParentId, + parentPropertyId: options.modelParentId?.replace('Id', ''), npmScope: options.npmScope, } } diff --git a/libs/tools/src/lib/api-crud/normalize-api-crud-schema.ts b/libs/tools/src/lib/api-crud/normalize-api-crud-schema.ts index a0c728f..0ee8838 100644 --- a/libs/tools/src/lib/api-crud/normalize-api-crud-schema.ts +++ b/libs/tools/src/lib/api-crud/normalize-api-crud-schema.ts @@ -6,6 +6,9 @@ import { NormalizedApiCrudSchema } from './normalized-api-crud.schema' export function normalizeApiCrudSchema(tree: Tree, schema: ApiCrudGeneratorSchema): NormalizedApiCrudSchema { const npmScope = getNpmScope(tree) + const modelParent = schema.modelParent ?? undefined + const modelParentId = schema.modelParentId ?? undefined + const modelParentProperty = modelParentId?.replace('Id', '') const fields = getPrismaModelFields(tree, schema.model) ?? [{ name: 'name', type: 'string', optional: false }] return { @@ -13,7 +16,9 @@ export function normalizeApiCrudSchema(tree: Tree, schema: ApiCrudGeneratorSchem actor: schema.actor, label: schema.label ?? 'name', model: schema.model, + modelParent, + modelParentId, npmScope, - fields, + fields: fields.filter((f) => ![modelParentId, modelParentProperty].includes(f.name)), } } diff --git a/libs/tools/src/lib/api/generate-api-lib-data-access.ts b/libs/tools/src/lib/api/generate-api-lib-data-access.ts index 0114127..ca334de 100644 --- a/libs/tools/src/lib/api/generate-api-lib-data-access.ts +++ b/libs/tools/src/lib/api/generate-api-lib-data-access.ts @@ -21,6 +21,5 @@ export async function generateApiLibDataAccess(tree: Tree, options: NormalizedAp replaceExports(tree, `${dataAccess.sourceRoot}/index.ts`, [ `./lib/${options.app}-${options.model}.data-access.module`, `./lib/${options.app}-${options.model}.service`, - `./lib/entity/${substitutions.model.fileName}.entity`, ]) } diff --git a/libs/tools/src/lib/api/get-api-substitutions.ts b/libs/tools/src/lib/api/get-api-substitutions.ts index efceef4..3363ad7 100644 --- a/libs/tools/src/lib/api/get-api-substitutions.ts +++ b/libs/tools/src/lib/api/get-api-substitutions.ts @@ -12,6 +12,9 @@ export function getApiSubstitutions(options: NormalizedApiFeatureSchema) { appFileName: app.fileName, modelFileName: model.fileName, modelPropertyNamePlural: plural.propertyName, + parent: options.modelParent ? names(options.modelParent) : undefined, + parentId: options.modelParentId, + parentPropertyId: options.modelParentId?.replace('Id', ''), label: names(options.label), model, npmScope: options.npmScope, diff --git a/libs/tools/src/lib/api/normalize-api-feature-schema.ts b/libs/tools/src/lib/api/normalize-api-feature-schema.ts index eee6b08..01d594c 100644 --- a/libs/tools/src/lib/api/normalize-api-feature-schema.ts +++ b/libs/tools/src/lib/api/normalize-api-feature-schema.ts @@ -12,6 +12,8 @@ export function normalizeApiFeatureSchema(tree: Tree, schema: ApiFeatureGenerato label: schema.label ?? 'name', crud: schema.crud?.length ? schema.crud.split(',') : [], model, + modelParent: schema.modelParent ?? undefined, + modelParentId: schema.modelParentId ?? undefined, npmScope, skipDataAccess: schema.skipDataAccess ?? false, skipFeature: schema.skipFeature ?? false, diff --git a/libs/tools/src/lib/prisma/get-prisma-models.ts b/libs/tools/src/lib/prisma/get-prisma-models.ts index e76eb3d..d88e01b 100644 --- a/libs/tools/src/lib/prisma/get-prisma-models.ts +++ b/libs/tools/src/lib/prisma/get-prisma-models.ts @@ -25,7 +25,7 @@ function getField(type: string) { case 'DateTime': return 'Date' default: - return 'string' + return type } } From 275c95f821225ff59aa8e96883acf40686160b25 Mon Sep 17 00:00:00 2001 From: Bram Borggreve Date: Fri, 15 Mar 2024 05:05:13 +0000 Subject: [PATCH 04/12] feat: add support for ownerId to api generator --- .../api-crud-generator.spec.ts.snap | 2890 ++++++++++++++++- .../api-crud/api-crud-generator.spec.ts | 28 +- .../generators/api-crud/api-crud-schema.d.ts | 8 +- .../generators/api-crud/api-crud-schema.json | 8 +- .../api-feature-generator.spec.ts.snap | 8 +- .../api-feature/api-feature-schema.d.ts | 8 +- .../api-feature/api-feature-schema.json | 8 +- .../web-feature-generator.spec.ts.snap | 12 +- .../web-feature/web-feature-schema.json | 2 +- ...data-__actorFileName__.service.ts.template | 34 +- ...__modelFileName__-data.service.ts.template | 6 +- ...create-__modelFileName__.input.ts.template | 6 +- ...d-many-__modelFileName__.input.ts.template | 6 +- ...-where-__actorFileName__.input.ts.template | 8 +- .../__modelFileName__.entity.ts.template | 11 +- ...e__-__actorFileName__.resolver.ts.template | 24 +- .../api-crud/get-api-crud-substitutions.ts | 3 + .../lib/api-crud/normalize-api-crud-schema.ts | 9 +- ...ema.d.ts => normalized-api-crud.schema.ts} | 3 + .../src/lib/api/get-api-substitutions.ts | 3 + .../lib/api/normalize-api-feature-schema.ts | 2 + .../lib/api/normalized-api-feature-schema.ts | 1 + ...delFileName__-detail-info.tab.tsx.template | 2 +- ...odelFileName__-detail.feature.tsx.template | 3 +- .../__modelFileName__-ui-item.tsx.template | 2 +- 25 files changed, 3014 insertions(+), 81 deletions(-) rename libs/tools/src/lib/api-crud/{normalized-api-crud.schema.d.ts => normalized-api-crud.schema.ts} (66%) diff --git a/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap b/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap index a85febf..d62aadd 100644 --- a/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap +++ b/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`api-crud generator should create crud with parent ID 1`] = ` +exports[`api-crud generator should create crud with modelOwnerId 1`] = ` { "company": { "children": { @@ -123,7 +123,2828 @@ exports[`api-crud generator should create crud with parent ID 1`] = ` "import { PagingInput } from '@proj/test-core-data-access';", "@InputType()", "export class AdminFindManyCompanyInput extends PagingInput() {", - "@Field(() => String)", + "@Field({ nullable: true })", + "search?: string;", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/dto/admin-find-many-company.input.ts", + }, + "admin-update-company.input.ts": { + "content": [ + "import { Field, InputType } from '@nestjs/graphql';", + "@InputType()", + "export class AdminUpdateCompanyInput {", + "@Field({ nullable: true })", + "name?: string;", + "@Field({ nullable: true })", + "location?: string;", + "@Field({ nullable: true })", + "phone?: string;", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/dto/admin-update-company.input.ts", + }, + }, + "path": "libs/test/company/data-access/src/lib/dto", + }, + "entity": { + "children": { + "company.entity.ts": { + "content": [ + "import { Field, ObjectType } from '@nestjs/graphql';", + "import { PagingResponse } from '@proj/test-core-data-access';", + "import { User } from '@proj/test-user-data-access';", + "@ObjectType()", + "export class Company {", + "@Field()", + "id!: string;", + "@Field({ nullable: true })", + "createdAt?: Date;", + "@Field({ nullable: true })", + "updatedAt?: Date;", + "@Field()", + "name!: string;", + "@Field()", + "location!: string;", + "@Field({ nullable: true })", + "phone?: string;", + "@Field()", + "ownerId!: string;", + "@Field(() => User, { nullable: true })", + "owner?: User;", + "}", + "@ObjectType()", + "export class CompanyPaging extends PagingResponse(Company) {}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/entity/company.entity.ts", + }, + }, + "path": "libs/test/company/data-access/src/lib/entity", + }, + "helpers": { + "children": { + "get-company-where-admin.input.ts": { + "content": [ + "import { Prisma } from '@prisma/client';", + "import { AdminFindManyCompanyInput } from '../dto/admin-find-many-company.input';", + "export function getCompanyWhereAdminInput(", + "input: AdminFindManyCompanyInput", + "): Prisma.CompanyWhereInput {", + "const where: Prisma.CompanyWhereInput = {};", + "if (input.search) {", + "where.OR = [", + "{ id: { contains: input.search, mode: 'insensitive' } },", + "{ name: { contains: input.search, mode: 'insensitive' } },", + "];", + "}", + "return where;", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/helpers/get-company-where-admin.input.ts", + }, + }, + "path": "libs/test/company/data-access/src/lib/helpers", + }, + "test-company-data-admin.service.ts": { + "content": [ + "import { Injectable } from '@nestjs/common';", + "import { AdminCreateCompanyInput } from './dto/admin-create-company.input';", + "import { AdminFindManyCompanyInput } from './dto/admin-find-many-company.input';", + "import { AdminUpdateCompanyInput } from './dto/admin-update-company.input';", + "import { CompanyPaging } from './entity/company.entity';", + "import { getCompanyWhereAdminInput } from './helpers/get-company-where-admin.input';", + "import { TestCompanyDataService } from './test-company-data.service';", + "@Injectable()", + "export class TestCompanyDataAdminService {", + "constructor(private readonly data: TestCompanyDataService) {}", + "async createCompany(input: AdminCreateCompanyInput) {", + "return this.data.create({ ...input, ownerId });", + "}", + "async deleteCompany(companyId: string) {", + "return this.data.delete(companyId);", + "}", + "async findManyCompany(", + "input: AdminFindManyCompanyInput", + "): Promise {", + "return this.data.findMany({", + "orderBy: { createdAt: 'desc' },", + "where: getCompanyWhereAdminInput(input),", + "limit: input.limit,", + "page: input.page,", + "});", + "}", + "async findOneCompany(companyId: string) {", + "return this.data.findOne(companyId);", + "}", + "async updateCompany(companyId: string, input: AdminUpdateCompanyInput) {", + "return this.data.update(companyId, input);", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/test-company-data-admin.service.ts", + }, + "test-company-data.service.ts": { + "content": [ + "import { Injectable } from '@nestjs/common';", + "import { Prisma } from '@prisma/client';", + "import {", + "TestCoreService,", + "type PagingInputFields,", + "} from '@proj/test-core-data-access';", + "import { CompanyPaging } from './entity/company.entity';", + "@Injectable()", + "export class TestCompanyDataService {", + "constructor(private readonly core: TestCoreService) {}", + "async create(input: Prisma.CompanyUncheckedCreateInput) {", + "return this.core.data.company.create({ data: input });", + "}", + "async delete(companyId: string) {", + "const deleted = await this.core.data.company.delete({", + "where: { id: companyId },", + "});", + "return !!deleted;", + "}", + "async findMany({", + "limit = 10,", + "page = 1,", + "...input", + "}: Prisma.CompanyFindManyArgs & PagingInputFields): Promise {", + "return this.core.data.company", + ".paginate(input)", + ".withPages({ limit, page })", + ".then(([data, meta]) => ({ data, meta }));", + "}", + "async findOne(companyId: string) {", + "const found = await this.core.data.company.findUnique({", + "where: { id: companyId },", + "});", + "if (!found) {", + "throw new Error('Company not found');", + "}", + "return found;", + "}", + "async update(companyId: string, input: Prisma.CompanyUpdateInput) {", + "return this.core.data.company.update({", + "where: { id: companyId },", + "data: input,", + "});", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/test-company-data.service.ts", + }, + "test-company.data-access.module.ts": { + "content": [ + "import { Module } from '@nestjs/common';", + "import { TestCoreDataAccessModule } from '@proj/test-core-data-access';", + "import { TestCompanyService } from './test-company.service';", + "import { TestCompanyDataService } from './test-company-data.service';", + "import { TestCompanyDataAdminService } from './test-company-data-admin.service';", + "@Module({", + "imports: [TestCoreDataAccessModule],", + "providers: [", + "TestCompanyService,", + "TestCompanyDataService,", + "TestCompanyDataAdminService,", + "],", + "exports: [TestCompanyService],", + "})", + "export class TestCompanyDataAccessModule {}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/test-company.data-access.module.ts", + }, + "test-company.service.ts": { + "content": [ + "import { Injectable } from '@nestjs/common';", + "import { TestCompanyDataService } from './test-company-data.service';", + "import { TestCompanyDataAdminService } from './test-company-data-admin.service';", + "@Injectable()", + "export class TestCompanyService {", + "constructor(", + "readonly data: TestCompanyDataService,", + "readonly admin: TestCompanyDataAdminService", + ") {}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/test-company.service.ts", + }, + }, + "path": "libs/test/company/data-access/src/lib", + }, + }, + "path": "libs/test/company/data-access/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""extends": "../../../../tsconfig.base.json",", + ""compilerOptions": {", + ""module": "commonjs",", + ""forceConsistentCasingInFileNames": true,", + ""strict": true,", + ""noImplicitOverride": true,", + ""noPropertyAccessFromIndexSignature": true,", + ""noImplicitReturns": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "},", + "{", + ""path": "./tsconfig.spec.json"", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""declaration": true,", + ""types": ["node"],", + ""target": "es6",", + ""strictNullChecks": true,", + ""noImplicitAny": true,", + ""strictBindCallApply": true,", + ""forceConsistentCasingInFileNames": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""include": ["src/**/*.ts"],", + ""exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/tsconfig.lib.json", + }, + "tsconfig.spec.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""module": "commonjs",", + ""types": ["jest", "node"]", + "},", + ""include": [", + ""jest.config.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.d.ts"", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/tsconfig.spec.json", + }, + }, + "path": "libs/test/company/data-access", + }, + "feature": { + "children": { + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-company-feature", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-company-feature\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/company/feature/README.md", + }, + "jest.config.ts": { + "content": [ + "/* eslint-disable */", + "export default {", + "displayName: 'test-company-feature',", + "preset: '../../../../jest.preset.js',", + "testEnvironment: 'node',", + "transform: {", + "'^.+\\\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }],", + "},", + "moduleFileExtensions: ['ts', 'js', 'html'],", + "coverageDirectory: '../../../../coverage/libs/test/company/feature',", + "};", + ], + "isBinary": false, + "path": "libs/test/company/feature/jest.config.ts", + }, + "project.json": { + "content": [ + "{", + ""name": "test-company-feature",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/company/feature/src",", + ""projectType": "library",", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "},", + ""test": {", + ""executor": "@nx/jest:jest",", + ""outputs": ["{workspaceRoot}/coverage/{projectRoot}"],", + ""options": {", + ""jestConfig": "libs/test/company/feature/jest.config.ts"", + "}", + "}", + "},", + ""tags": ["app:test", "type:feature"]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [ + "export * from './lib/test-company.feature.module';", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/index.ts", + }, + "lib": { + "children": { + "test-company-admin.resolver.ts": { + "content": [ + "import { Resolver } from '@nestjs/graphql';", + "import { TestCompanyService } from '@proj/test-company-data-access';", + "import { TestAuthGraphQLAdminGuard } from '@proj/test-auth-data-access';", + "import { Mutation, Query, Args } from '@nestjs/graphql';", + "import { UseGuards } from '@nestjs/common';", + "import {", + "AdminCreateCompanyInput,", + "AdminFindManyCompanyInput,", + "Company,", + "CompanyPaging,", + "AdminUpdateCompanyInput,", + "} from '@proj/test-company-data-access';", + "@Resolver()", + "@UseGuards(TestAuthGraphQLAdminGuard)", + "export class TestCompanyAdminResolver {", + "constructor(private readonly service: TestCompanyService) {}", + "@Mutation(() => Company, { nullable: true })", + "adminCreateCompany(@Args('input') input: AdminCreateCompanyInput) {", + "return this.service.admin.createCompany(input);", + "}", + "@Mutation(() => Boolean, { nullable: true })", + "adminDeleteCompany(@Args('companyId') companyId: string) {", + "return this.service.admin.deleteCompany(companyId);", + "}", + "@Query(() => CompanyPaging)", + "adminFindManyCompany(@Args('input') input: AdminFindManyCompanyInput) {", + "return this.service.admin.findManyCompany(input);", + "}", + "@Query(() => Company, { nullable: true })", + "adminFindOneCompany(@Args('companyId') companyId: string) {", + "return this.service.admin.findOneCompany(companyId);", + "}", + "@Mutation(() => Company, { nullable: true })", + "adminUpdateCompany(", + "@Args('companyId') companyId: string,", + "@Args('input') input: AdminUpdateCompanyInput", + ") {", + "return this.service.admin.updateCompany(companyId, input);", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/test-company-admin.resolver.ts", + }, + "test-company.feature.module.ts": { + "content": [ + "import { Module } from '@nestjs/common';", + "import { TestCompanyDataAccessModule } from '@proj/test-company-data-access';", + "import { TestCompanyResolver } from './test-company.resolver';", + "import { TestCompanyAdminResolver } from './test-company-admin.resolver';", + "@Module({", + "imports: [TestCompanyDataAccessModule],", + "providers: [TestCompanyResolver, TestCompanyAdminResolver],", + "})", + "export class TestCompanyFeatureModule {}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/test-company.feature.module.ts", + }, + "test-company.resolver.ts": { + "content": [ + "import { Resolver } from '@nestjs/graphql';", + "import { TestCompanyService } from '@proj/test-company-data-access';", + "import { Company } from '@proj/test-company-data-access';", + "@Resolver(() => Company)", + "export class TestCompanyResolver {", + "constructor(private readonly service: TestCompanyService) {}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/test-company.resolver.ts", + }, + }, + "path": "libs/test/company/feature/src/lib", + }, + }, + "path": "libs/test/company/feature/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""extends": "../../../../tsconfig.base.json",", + ""compilerOptions": {", + ""module": "commonjs",", + ""forceConsistentCasingInFileNames": true,", + ""strict": true,", + ""noImplicitOverride": true,", + ""noPropertyAccessFromIndexSignature": true,", + ""noImplicitReturns": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "},", + "{", + ""path": "./tsconfig.spec.json"", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""declaration": true,", + ""types": ["node"],", + ""target": "es6",", + ""strictNullChecks": true,", + ""noImplicitAny": true,", + ""strictBindCallApply": true,", + ""forceConsistentCasingInFileNames": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""include": ["src/**/*.ts"],", + ""exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/tsconfig.lib.json", + }, + "tsconfig.spec.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""module": "commonjs",", + ""types": ["jest", "node"]", + "},", + ""include": [", + ""jest.config.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.d.ts"", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/tsconfig.spec.json", + }, + }, + "path": "libs/test/company/feature", + }, + }, + "path": "libs/test/company", + }, + "core": { + "children": { + "data-access": { + "children": { + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-core-data-access", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-core-data-access\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/core/data-access/README.md", + }, + "jest.config.ts": { + "content": [ + "/* eslint-disable */", + "export default {", + "displayName: 'test-core-data-access',", + "preset: '../../../../jest.preset.js',", + "testEnvironment: 'node',", + "transform: {", + "'^.+\\\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }],", + "},", + "moduleFileExtensions: ['ts', 'js', 'html'],", + "coverageDirectory: '../../../../coverage/libs/test/core/data-access',", + "};", + ], + "isBinary": false, + "path": "libs/test/core/data-access/jest.config.ts", + }, + "project.json": { + "content": [ + "{", + ""name": "test-core-data-access",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/core/data-access/src",", + ""projectType": "library",", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "},", + ""test": {", + ""executor": "@nx/jest:jest",", + ""outputs": ["{workspaceRoot}/coverage/{projectRoot}"],", + ""options": {", + ""jestConfig": "libs/test/core/data-access/jest.config.ts"", + "}", + "}", + "},", + ""tags": []", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [ + "export * from './lib/test-core-data-access.module';", + ], + "isBinary": false, + "path": "libs/test/core/data-access/src/index.ts", + }, + "lib": { + "children": { + "test-core-data-access.module.ts": { + "content": [ + "import { Module } from '@nestjs/common';", + "import { TestCoreService } from './test-core.service';", + "@Module({", + "controllers: [],", + "providers: [TestCoreService],", + "exports: [],", + "})", + "export class TestCoreDataAccessModule {}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/src/lib/test-core-data-access.module.ts", + }, + "test-core.service.spec.ts": { + "content": [ + "import { Test, TestingModule } from '@nestjs/testing';", + "import { TestCoreService } from './test-core.service';", + "describe('TestCoreService', () => {", + "let service: TestCoreService;", + "beforeEach(async () => {", + "const module: TestingModule = await Test.createTestingModule({", + "providers: [TestCoreService],", + "}).compile();", + "service = module.get(TestCoreService);", + "});", + "it('should be defined', () => {", + "expect(service).toBeDefined();", + "});", + "});", + ], + "isBinary": false, + "path": "libs/test/core/data-access/src/lib/test-core.service.spec.ts", + }, + "test-core.service.ts": { + "content": [ + "import { Injectable } from '@nestjs/common';", + "@Injectable()", + "export class TestCoreService {}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/src/lib/test-core.service.ts", + }, + }, + "path": "libs/test/core/data-access/src/lib", + }, + }, + "path": "libs/test/core/data-access/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""extends": "../../../../tsconfig.base.json",", + ""compilerOptions": {", + ""module": "commonjs",", + ""forceConsistentCasingInFileNames": true,", + ""strict": true,", + ""noImplicitOverride": true,", + ""noPropertyAccessFromIndexSignature": true,", + ""noImplicitReturns": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "},", + "{", + ""path": "./tsconfig.spec.json"", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""declaration": true,", + ""types": ["node"],", + ""target": "es6",", + ""strictNullChecks": true,", + ""noImplicitAny": true,", + ""strictBindCallApply": true,", + ""forceConsistentCasingInFileNames": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""include": ["src/**/*.ts"],", + ""exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/tsconfig.lib.json", + }, + "tsconfig.spec.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""module": "commonjs",", + ""types": ["jest", "node"]", + "},", + ""include": [", + ""jest.config.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.d.ts"", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/tsconfig.spec.json", + }, + }, + "path": "libs/test/core/data-access", + }, + "feature": { + "children": { + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-core-feature", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-core-feature\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/core/feature/README.md", + }, + "jest.config.ts": { + "content": [ + "/* eslint-disable */", + "export default {", + "displayName: 'test-core-feature',", + "preset: '../../../../jest.preset.js',", + "testEnvironment: 'node',", + "transform: {", + "'^.+\\\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }],", + "},", + "moduleFileExtensions: ['ts', 'js', 'html'],", + "coverageDirectory: '../../../../coverage/libs/test/core/feature',", + "};", + ], + "isBinary": false, + "path": "libs/test/core/feature/jest.config.ts", + }, + "project.json": { + "content": [ + "{", + ""name": "test-core-feature",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/core/feature/src",", + ""projectType": "library",", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "},", + ""test": {", + ""executor": "@nx/jest:jest",", + ""outputs": ["{workspaceRoot}/coverage/{projectRoot}"],", + ""options": {", + ""jestConfig": "libs/test/core/feature/jest.config.ts"", + "}", + "}", + "},", + ""tags": []", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [ + "export * from './lib/test-core-feature.module';", + ], + "isBinary": false, + "path": "libs/test/core/feature/src/index.ts", + }, + "lib": { + "children": { + "test-core-feature.module.ts": { + "content": [ + "import { Module } from '@nestjs/common';", + "import { TestCompanyFeatureModule } from '@proj/test-company-feature';", + "@Module({", + "controllers: [],", + "providers: [],", + "exports: [],", + "})", + "export class TestCoreFeatureModule {}", + ], + "isBinary": false, + "path": "libs/test/core/feature/src/lib/test-core-feature.module.ts", + }, + }, + "path": "libs/test/core/feature/src/lib", + }, + }, + "path": "libs/test/core/feature/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""extends": "../../../../tsconfig.base.json",", + ""compilerOptions": {", + ""module": "commonjs",", + ""forceConsistentCasingInFileNames": true,", + ""strict": true,", + ""noImplicitOverride": true,", + ""noPropertyAccessFromIndexSignature": true,", + ""noImplicitReturns": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "},", + "{", + ""path": "./tsconfig.spec.json"", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""declaration": true,", + ""types": ["node"],", + ""target": "es6",", + ""strictNullChecks": true,", + ""noImplicitAny": true,", + ""strictBindCallApply": true,", + ""forceConsistentCasingInFileNames": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""include": ["src/**/*.ts"],", + ""exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/tsconfig.lib.json", + }, + "tsconfig.spec.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""module": "commonjs",", + ""types": ["jest", "node"]", + "},", + ""include": [", + ""jest.config.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.d.ts"", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/tsconfig.spec.json", + }, + }, + "path": "libs/test/core/feature", + }, + }, + "path": "libs/test/core", + }, + "sdk": { + "children": { + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/sdk/.eslintrc.json", + }, + "README.md": { + "content": [ + "# sdk", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test sdk\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/sdk/README.md", + }, + "jest.config.ts": { + "content": [ + "/* eslint-disable */", + "export default {", + "displayName: 'sdk',", + "preset: '../../../jest.preset.js',", + "testEnvironment: 'node',", + "transform: {", + "'^.+\\\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }],", + "},", + "moduleFileExtensions: ['ts', 'js', 'html'],", + "coverageDirectory: '../../../coverage/libs/test/sdk',", + "};", + ], + "isBinary": false, + "path": "libs/test/sdk/jest.config.ts", + }, + "project.json": { + "content": [ + "{", + ""name": "sdk",", + ""$schema": "../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/sdk/src",", + ""projectType": "library",", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "},", + ""test": {", + ""executor": "@nx/jest:jest",", + ""outputs": ["{workspaceRoot}/coverage/{projectRoot}"],", + ""options": {", + ""jestConfig": "libs/test/sdk/jest.config.ts"", + "}", + "}", + "},", + ""tags": []", + "}", + ], + "isBinary": false, + "path": "libs/test/sdk/project.json", + }, + "src": { + "children": { + "graphql": { + "children": { + "feature-company.graphql": { + "content": [ + "fragment CompanyDetails on Company {", + "createdAt", + "id", + "name", + "location", + "phone", + "updatedAt", + "}", + "query adminFindManyCompany($input: AdminFindManyCompanyInput!) {", + "paging: adminFindManyCompany(input: $input) {", + "data {", + "...CompanyDetails", + "}", + "meta {", + "...PagingMetaDetails", + "}", + "}", + "}", + "query adminFindOneCompany($companyId: String!) {", + "item: adminFindOneCompany(companyId: $companyId) {", + "...CompanyDetails", + "}", + "}", + "mutation adminCreateCompany($input: AdminCreateCompanyInput!) {", + "created: adminCreateCompany(input: $input) {", + "...CompanyDetails", + "}", + "}", + "mutation adminUpdateCompany(", + "$companyId: String!", + "$input: AdminUpdateCompanyInput!", + ") {", + "updated: adminUpdateCompany(companyId: $companyId, input: $input) {", + "...CompanyDetails", + "}", + "}", + "mutation adminDeleteCompany($companyId: String!) {", + "deleted: adminDeleteCompany(companyId: $companyId)", + "}", + ], + "isBinary": false, + "path": "libs/test/sdk/src/graphql/feature-company.graphql", + }, + }, + "path": "libs/test/sdk/src/graphql", + }, + "index.ts": { + "content": [ + "export * from './lib/sdk.module';", + ], + "isBinary": false, + "path": "libs/test/sdk/src/index.ts", + }, + "lib": { + "children": { + "sdk.module.ts": { + "content": [ + "import { Module } from '@nestjs/common';", + "@Module({", + "controllers: [],", + "providers: [],", + "exports: [],", + "})", + "export class SdkModule {}", + ], + "isBinary": false, + "path": "libs/test/sdk/src/lib/sdk.module.ts", + }, + }, + "path": "libs/test/sdk/src/lib", + }, + }, + "path": "libs/test/sdk/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""extends": "../../../tsconfig.base.json",", + ""compilerOptions": {", + ""module": "commonjs",", + ""forceConsistentCasingInFileNames": true,", + ""strict": true,", + ""noImplicitOverride": true,", + ""noPropertyAccessFromIndexSignature": true,", + ""noImplicitReturns": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "},", + "{", + ""path": "./tsconfig.spec.json"", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/sdk/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../dist/out-tsc",", + ""declaration": true,", + ""types": ["node"],", + ""target": "es6",", + ""strictNullChecks": true,", + ""noImplicitAny": true,", + ""strictBindCallApply": true,", + ""forceConsistentCasingInFileNames": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""include": ["src/**/*.ts"],", + ""exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]", + "}", + ], + "isBinary": false, + "path": "libs/test/sdk/tsconfig.lib.json", + }, + "tsconfig.spec.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../dist/out-tsc",", + ""module": "commonjs",", + ""types": ["jest", "node"]", + "},", + ""include": [", + ""jest.config.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.d.ts"", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/sdk/tsconfig.spec.json", + }, + }, + "path": "libs/test/sdk", + }, +} +`; + +exports[`api-crud generator should create crud with modelOwnerId for admin and user 1`] = ` +{ + "company": { + "children": { + "data-access": { + "children": { + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-company-data-access", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-company-data-access\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/company/data-access/README.md", + }, + "jest.config.ts": { + "content": [ + "/* eslint-disable */", + "export default {", + "displayName: 'test-company-data-access',", + "preset: '../../../../jest.preset.js',", + "testEnvironment: 'node',", + "transform: {", + "'^.+\\\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }],", + "},", + "moduleFileExtensions: ['ts', 'js', 'html'],", + "coverageDirectory: '../../../../coverage/libs/test/company/data-access',", + "};", + ], + "isBinary": false, + "path": "libs/test/company/data-access/jest.config.ts", + }, + "project.json": { + "content": [ + "{", + ""name": "test-company-data-access",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/company/data-access/src",", + ""projectType": "library",", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "},", + ""test": {", + ""executor": "@nx/jest:jest",", + ""outputs": ["{workspaceRoot}/coverage/{projectRoot}"],", + ""options": {", + ""jestConfig": "libs/test/company/data-access/jest.config.ts"", + "}", + "}", + "},", + ""tags": ["app:test", "type:data-access"]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [ + "export * from './lib/test-company.data-access.module';", + "export * from './lib/test-company.service';", + "export * from './lib/entity/company.entity';", + "export * from './lib/dto/user-create-company.input';", + "export * from './lib/dto/user-find-many-company.input';", + "export * from './lib/dto/user-update-company.input';", + "export * from './lib/dto/admin-create-company.input';", + "export * from './lib/dto/admin-find-many-company.input';", + "export * from './lib/dto/admin-update-company.input';", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/index.ts", + }, + "lib": { + "children": { + "dto": { + "children": { + "admin-create-company.input.ts": { + "content": [ + "import { Field, InputType } from '@nestjs/graphql';", + "@InputType()", + "export class AdminCreateCompanyInput {", + "@Field()", + "name!: string;", + "@Field()", + "location!: string;", + "@Field({ nullable: true })", + "phone?: string;", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/dto/admin-create-company.input.ts", + }, + "admin-find-many-company.input.ts": { + "content": [ + "import { Field, InputType } from '@nestjs/graphql';", + "import { PagingInput } from '@proj/test-core-data-access';", + "@InputType()", + "export class AdminFindManyCompanyInput extends PagingInput() {", + "@Field({ nullable: true })", + "search?: string;", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/dto/admin-find-many-company.input.ts", + }, + "admin-update-company.input.ts": { + "content": [ + "import { Field, InputType } from '@nestjs/graphql';", + "@InputType()", + "export class AdminUpdateCompanyInput {", + "@Field({ nullable: true })", + "name?: string;", + "@Field({ nullable: true })", + "location?: string;", + "@Field({ nullable: true })", + "phone?: string;", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/dto/admin-update-company.input.ts", + }, + "user-create-company.input.ts": { + "content": [ + "import { Field, InputType } from '@nestjs/graphql';", + "@InputType()", + "export class UserCreateCompanyInput {", + "@Field()", + "name!: string;", + "@Field()", + "location!: string;", + "@Field({ nullable: true })", + "phone?: string;", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/dto/user-create-company.input.ts", + }, + "user-find-many-company.input.ts": { + "content": [ + "import { Field, InputType } from '@nestjs/graphql';", + "import { PagingInput } from '@proj/test-core-data-access';", + "@InputType()", + "export class UserFindManyCompanyInput extends PagingInput() {", + "@Field({ nullable: true })", + "search?: string;", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/dto/user-find-many-company.input.ts", + }, + "user-update-company.input.ts": { + "content": [ + "import { Field, InputType } from '@nestjs/graphql';", + "@InputType()", + "export class UserUpdateCompanyInput {", + "@Field({ nullable: true })", + "name?: string;", + "@Field({ nullable: true })", + "location?: string;", + "@Field({ nullable: true })", + "phone?: string;", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/dto/user-update-company.input.ts", + }, + }, + "path": "libs/test/company/data-access/src/lib/dto", + }, + "entity": { + "children": { + "company.entity.ts": { + "content": [ + "import { Field, ObjectType } from '@nestjs/graphql';", + "import { PagingResponse } from '@proj/test-core-data-access';", + "import { User } from '@proj/test-user-data-access';", + "@ObjectType()", + "export class Company {", + "@Field()", + "id!: string;", + "@Field({ nullable: true })", + "createdAt?: Date;", + "@Field({ nullable: true })", + "updatedAt?: Date;", + "@Field()", + "name!: string;", + "@Field()", + "location!: string;", + "@Field({ nullable: true })", + "phone?: string;", + "@Field()", + "ownerId!: string;", + "@Field(() => User, { nullable: true })", + "owner?: User;", + "}", + "@ObjectType()", + "export class CompanyPaging extends PagingResponse(Company) {}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/entity/company.entity.ts", + }, + }, + "path": "libs/test/company/data-access/src/lib/entity", + }, + "helpers": { + "children": { + "get-company-where-admin.input.ts": { + "content": [ + "import { Prisma } from '@prisma/client';", + "import { AdminFindManyCompanyInput } from '../dto/admin-find-many-company.input';", + "export function getCompanyWhereAdminInput(", + "input: AdminFindManyCompanyInput", + "): Prisma.CompanyWhereInput {", + "const where: Prisma.CompanyWhereInput = {};", + "if (input.search) {", + "where.OR = [", + "{ id: { contains: input.search, mode: 'insensitive' } },", + "{ name: { contains: input.search, mode: 'insensitive' } },", + "];", + "}", + "return where;", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/helpers/get-company-where-admin.input.ts", + }, + "get-company-where-user.input.ts": { + "content": [ + "import { Prisma } from '@prisma/client';", + "import { UserFindManyCompanyInput } from '../dto/user-find-many-company.input';", + "export function getCompanyWhereUserInput(", + "ownerId: string,", + "input: UserFindManyCompanyInput", + "): Prisma.CompanyWhereInput {", + "const where: Prisma.CompanyWhereInput = {", + "ownerId: ownerId,", + "};", + "if (input.search) {", + "where.OR = [", + "{ id: { contains: input.search, mode: 'insensitive' } },", + "{ name: { contains: input.search, mode: 'insensitive' } },", + "];", + "}", + "return where;", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/helpers/get-company-where-user.input.ts", + }, + }, + "path": "libs/test/company/data-access/src/lib/helpers", + }, + "test-company-data-admin.service.ts": { + "content": [ + "import { Injectable } from '@nestjs/common';", + "import { AdminCreateCompanyInput } from './dto/admin-create-company.input';", + "import { AdminFindManyCompanyInput } from './dto/admin-find-many-company.input';", + "import { AdminUpdateCompanyInput } from './dto/admin-update-company.input';", + "import { CompanyPaging } from './entity/company.entity';", + "import { getCompanyWhereAdminInput } from './helpers/get-company-where-admin.input';", + "import { TestCompanyDataService } from './test-company-data.service';", + "@Injectable()", + "export class TestCompanyDataAdminService {", + "constructor(private readonly data: TestCompanyDataService) {}", + "async createCompany(input: AdminCreateCompanyInput) {", + "return this.data.create({ ...input, ownerId });", + "}", + "async deleteCompany(companyId: string) {", + "return this.data.delete(companyId);", + "}", + "async findManyCompany(", + "input: AdminFindManyCompanyInput", + "): Promise {", + "return this.data.findMany({", + "orderBy: { createdAt: 'desc' },", + "where: getCompanyWhereAdminInput(input),", + "limit: input.limit,", + "page: input.page,", + "});", + "}", + "async findOneCompany(companyId: string) {", + "return this.data.findOne(companyId);", + "}", + "async updateCompany(companyId: string, input: AdminUpdateCompanyInput) {", + "return this.data.update(companyId, input);", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/test-company-data-admin.service.ts", + }, + "test-company-data-user.service.ts": { + "content": [ + "import { Injectable } from '@nestjs/common';", + "import { UserCreateCompanyInput } from './dto/user-create-company.input';", + "import { UserFindManyCompanyInput } from './dto/user-find-many-company.input';", + "import { UserUpdateCompanyInput } from './dto/user-update-company.input';", + "import { CompanyPaging } from './entity/company.entity';", + "import { getCompanyWhereUserInput } from './helpers/get-company-where-user.input';", + "import { TestCompanyDataService } from './test-company-data.service';", + "@Injectable()", + "export class TestCompanyDataUserService {", + "constructor(private readonly data: TestCompanyDataService) {}", + "async createCompany(ownerId: string, input: UserCreateCompanyInput) {", + "return this.data.create({ ...input, ownerId });", + "}", + "async deleteCompany(ownerId: string, companyId: string) {", + "const found = await this.data.findOne(companyId);", + "if (found.ownerId !== ownerId) {", + "throw new Error('You are not authorized to delete this Company');", + "}", + "return this.data.delete(companyId);", + "}", + "async findManyCompany(", + "ownerId: string,", + "input: UserFindManyCompanyInput", + "): Promise {", + "return this.data.findMany({", + "orderBy: { createdAt: 'desc' },", + "where: getCompanyWhereUserInput(ownerId, input),", + "limit: input.limit,", + "page: input.page,", + "});", + "}", + "async findOneCompany(ownerId: string, companyId: string) {", + "const found = await this.data.findOne(companyId);", + "if (found.ownerId !== ownerId) {", + "throw new Error('You are not authorized to view this Company');", + "}", + "return found;", + "}", + "async updateCompany(", + "ownerId: string,", + "companyId: string,", + "input: UserUpdateCompanyInput", + ") {", + "const found = await this.data.findOne(companyId);", + "if (found.ownerId !== ownerId) {", + "throw new Error('You are not authorized to update this Company');", + "}", + "return this.data.update(companyId, input);", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/test-company-data-user.service.ts", + }, + "test-company-data.service.ts": { + "content": [ + "import { Injectable } from '@nestjs/common';", + "import { Prisma } from '@prisma/client';", + "import {", + "TestCoreService,", + "type PagingInputFields,", + "} from '@proj/test-core-data-access';", + "import { CompanyPaging } from './entity/company.entity';", + "@Injectable()", + "export class TestCompanyDataService {", + "constructor(private readonly core: TestCoreService) {}", + "async create(input: Prisma.CompanyUncheckedCreateInput) {", + "return this.core.data.company.create({ data: input });", + "}", + "async delete(companyId: string) {", + "const deleted = await this.core.data.company.delete({", + "where: { id: companyId },", + "});", + "return !!deleted;", + "}", + "async findMany({", + "limit = 10,", + "page = 1,", + "...input", + "}: Prisma.CompanyFindManyArgs & PagingInputFields): Promise {", + "return this.core.data.company", + ".paginate(input)", + ".withPages({ limit, page })", + ".then(([data, meta]) => ({ data, meta }));", + "}", + "async findOne(companyId: string) {", + "const found = await this.core.data.company.findUnique({", + "where: { id: companyId },", + "});", + "if (!found) {", + "throw new Error('Company not found');", + "}", + "return found;", + "}", + "async update(companyId: string, input: Prisma.CompanyUpdateInput) {", + "return this.core.data.company.update({", + "where: { id: companyId },", + "data: input,", + "});", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/test-company-data.service.ts", + }, + "test-company.data-access.module.ts": { + "content": [ + "import { Module } from '@nestjs/common';", + "import { TestCoreDataAccessModule } from '@proj/test-core-data-access';", + "import { TestCompanyService } from './test-company.service';", + "import { TestCompanyDataService } from './test-company-data.service';", + "import { TestCompanyDataUserService } from './test-company-data-user.service';", + "import { TestCompanyDataAdminService } from './test-company-data-admin.service';", + "@Module({", + "imports: [TestCoreDataAccessModule],", + "providers: [", + "TestCompanyService,", + "TestCompanyDataService,", + "TestCompanyDataUserService,", + "TestCompanyDataAdminService,", + "],", + "exports: [TestCompanyService],", + "})", + "export class TestCompanyDataAccessModule {}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/test-company.data-access.module.ts", + }, + "test-company.service.ts": { + "content": [ + "import { Injectable } from '@nestjs/common';", + "import { TestCompanyDataService } from './test-company-data.service';", + "import { TestCompanyDataUserService } from './test-company-data-user.service';", + "import { TestCompanyDataAdminService } from './test-company-data-admin.service';", + "@Injectable()", + "export class TestCompanyService {", + "constructor(", + "readonly data: TestCompanyDataService,", + "readonly user: TestCompanyDataUserService,", + "readonly admin: TestCompanyDataAdminService", + ") {}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/test-company.service.ts", + }, + }, + "path": "libs/test/company/data-access/src/lib", + }, + }, + "path": "libs/test/company/data-access/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""extends": "../../../../tsconfig.base.json",", + ""compilerOptions": {", + ""module": "commonjs",", + ""forceConsistentCasingInFileNames": true,", + ""strict": true,", + ""noImplicitOverride": true,", + ""noPropertyAccessFromIndexSignature": true,", + ""noImplicitReturns": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "},", + "{", + ""path": "./tsconfig.spec.json"", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""declaration": true,", + ""types": ["node"],", + ""target": "es6",", + ""strictNullChecks": true,", + ""noImplicitAny": true,", + ""strictBindCallApply": true,", + ""forceConsistentCasingInFileNames": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""include": ["src/**/*.ts"],", + ""exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/tsconfig.lib.json", + }, + "tsconfig.spec.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""module": "commonjs",", + ""types": ["jest", "node"]", + "},", + ""include": [", + ""jest.config.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.d.ts"", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/tsconfig.spec.json", + }, + }, + "path": "libs/test/company/data-access", + }, + "feature": { + "children": { + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-company-feature", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-company-feature\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/company/feature/README.md", + }, + "jest.config.ts": { + "content": [ + "/* eslint-disable */", + "export default {", + "displayName: 'test-company-feature',", + "preset: '../../../../jest.preset.js',", + "testEnvironment: 'node',", + "transform: {", + "'^.+\\\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }],", + "},", + "moduleFileExtensions: ['ts', 'js', 'html'],", + "coverageDirectory: '../../../../coverage/libs/test/company/feature',", + "};", + ], + "isBinary": false, + "path": "libs/test/company/feature/jest.config.ts", + }, + "project.json": { + "content": [ + "{", + ""name": "test-company-feature",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/company/feature/src",", + ""projectType": "library",", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "},", + ""test": {", + ""executor": "@nx/jest:jest",", + ""outputs": ["{workspaceRoot}/coverage/{projectRoot}"],", + ""options": {", + ""jestConfig": "libs/test/company/feature/jest.config.ts"", + "}", + "}", + "},", + ""tags": ["app:test", "type:feature"]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [ + "export * from './lib/test-company.feature.module';", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/index.ts", + }, + "lib": { + "children": { + "test-company-admin.resolver.ts": { + "content": [ + "import { Resolver } from '@nestjs/graphql';", + "import { TestCompanyService } from '@proj/test-company-data-access';", + "import { TestAuthGraphQLAdminGuard } from '@proj/test-auth-data-access';", + "import { Mutation, Query, Args } from '@nestjs/graphql';", + "import { UseGuards } from '@nestjs/common';", + "import {", + "AdminCreateCompanyInput,", + "AdminFindManyCompanyInput,", + "Company,", + "CompanyPaging,", + "AdminUpdateCompanyInput,", + "} from '@proj/test-company-data-access';", + "@Resolver()", + "@UseGuards(TestAuthGraphQLAdminGuard)", + "export class TestCompanyAdminResolver {", + "constructor(private readonly service: TestCompanyService) {}", + "@Mutation(() => Company, { nullable: true })", + "adminCreateCompany(@Args('input') input: AdminCreateCompanyInput) {", + "return this.service.admin.createCompany(input);", + "}", + "@Mutation(() => Boolean, { nullable: true })", + "adminDeleteCompany(@Args('companyId') companyId: string) {", + "return this.service.admin.deleteCompany(companyId);", + "}", + "@Query(() => CompanyPaging)", + "adminFindManyCompany(@Args('input') input: AdminFindManyCompanyInput) {", + "return this.service.admin.findManyCompany(input);", + "}", + "@Query(() => Company, { nullable: true })", + "adminFindOneCompany(@Args('companyId') companyId: string) {", + "return this.service.admin.findOneCompany(companyId);", + "}", + "@Mutation(() => Company, { nullable: true })", + "adminUpdateCompany(", + "@Args('companyId') companyId: string,", + "@Args('input') input: AdminUpdateCompanyInput", + ") {", + "return this.service.admin.updateCompany(companyId, input);", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/test-company-admin.resolver.ts", + }, + "test-company-user.resolver.ts": { + "content": [ + "import { Resolver } from '@nestjs/graphql';", + "import { TestCompanyService } from '@proj/test-company-data-access';", + "import {", + "TestAuthGraphQLUserGuard,", + "CtxUserId,", + "} from '@proj/test-auth-data-access';", + "import { Mutation, Query, Args } from '@nestjs/graphql';", + "import { UseGuards } from '@nestjs/common';", + "import {", + "UserCreateCompanyInput,", + "UserFindManyCompanyInput,", + "Company,", + "CompanyPaging,", + "UserUpdateCompanyInput,", + "} from '@proj/test-company-data-access';", + "@Resolver()", + "@UseGuards(TestAuthGraphQLUserGuard)", + "export class TestCompanyUserResolver {", + "constructor(private readonly service: TestCompanyService) {}", + "@Mutation(() => Company, { nullable: true })", + "userCreateCompany(", + "@CtxUserId() ownerId: string,", + "@Args('input') input: UserCreateCompanyInput", + ") {", + "return this.service.user.createCompany(ownerId, input);", + "}", + "@Mutation(() => Boolean, { nullable: true })", + "userDeleteCompany(", + "@CtxUserId() ownerId: string,", + "@Args('companyId') companyId: string", + ") {", + "return this.service.user.deleteCompany(ownerId, companyId);", + "}", + "@Query(() => CompanyPaging)", + "userFindManyCompany(", + "@CtxUserId() ownerId: string,", + "@Args('input') input: UserFindManyCompanyInput", + ") {", + "return this.service.user.findManyCompany(ownerId, input);", + "}", + "@Query(() => Company, { nullable: true })", + "userFindOneCompany(", + "@CtxUserId() ownerId: string,", + "@Args('companyId') companyId: string", + ") {", + "return this.service.user.findOneCompany(ownerId, companyId);", + "}", + "@Mutation(() => Company, { nullable: true })", + "userUpdateCompany(", + "@CtxUserId() ownerId: string,", + "@Args('companyId') companyId: string,", + "@Args('input') input: UserUpdateCompanyInput", + ") {", + "return this.service.user.updateCompany(ownerId, companyId, input);", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/test-company-user.resolver.ts", + }, + "test-company.feature.module.ts": { + "content": [ + "import { Module } from '@nestjs/common';", + "import { TestCompanyDataAccessModule } from '@proj/test-company-data-access';", + "import { TestCompanyResolver } from './test-company.resolver';", + "import { TestCompanyUserResolver } from './test-company-user.resolver';", + "import { TestCompanyAdminResolver } from './test-company-admin.resolver';", + "@Module({", + "imports: [TestCompanyDataAccessModule],", + "providers: [", + "TestCompanyResolver,", + "TestCompanyUserResolver,", + "TestCompanyAdminResolver,", + "],", + "})", + "export class TestCompanyFeatureModule {}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/test-company.feature.module.ts", + }, + "test-company.resolver.ts": { + "content": [ + "import { Resolver } from '@nestjs/graphql';", + "import { TestCompanyService } from '@proj/test-company-data-access';", + "import { Company } from '@proj/test-company-data-access';", + "@Resolver(() => Company)", + "export class TestCompanyResolver {", + "constructor(private readonly service: TestCompanyService) {}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/test-company.resolver.ts", + }, + }, + "path": "libs/test/company/feature/src/lib", + }, + }, + "path": "libs/test/company/feature/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""extends": "../../../../tsconfig.base.json",", + ""compilerOptions": {", + ""module": "commonjs",", + ""forceConsistentCasingInFileNames": true,", + ""strict": true,", + ""noImplicitOverride": true,", + ""noPropertyAccessFromIndexSignature": true,", + ""noImplicitReturns": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "},", + "{", + ""path": "./tsconfig.spec.json"", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""declaration": true,", + ""types": ["node"],", + ""target": "es6",", + ""strictNullChecks": true,", + ""noImplicitAny": true,", + ""strictBindCallApply": true,", + ""forceConsistentCasingInFileNames": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""include": ["src/**/*.ts"],", + ""exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/tsconfig.lib.json", + }, + "tsconfig.spec.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""module": "commonjs",", + ""types": ["jest", "node"]", + "},", + ""include": [", + ""jest.config.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.d.ts"", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/tsconfig.spec.json", + }, + }, + "path": "libs/test/company/feature", + }, + }, + "path": "libs/test/company", + }, + "core": { + "children": { + "data-access": { + "children": { + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-core-data-access", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-core-data-access\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/core/data-access/README.md", + }, + "jest.config.ts": { + "content": [ + "/* eslint-disable */", + "export default {", + "displayName: 'test-core-data-access',", + "preset: '../../../../jest.preset.js',", + "testEnvironment: 'node',", + "transform: {", + "'^.+\\\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }],", + "},", + "moduleFileExtensions: ['ts', 'js', 'html'],", + "coverageDirectory: '../../../../coverage/libs/test/core/data-access',", + "};", + ], + "isBinary": false, + "path": "libs/test/core/data-access/jest.config.ts", + }, + "project.json": { + "content": [ + "{", + ""name": "test-core-data-access",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/core/data-access/src",", + ""projectType": "library",", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "},", + ""test": {", + ""executor": "@nx/jest:jest",", + ""outputs": ["{workspaceRoot}/coverage/{projectRoot}"],", + ""options": {", + ""jestConfig": "libs/test/core/data-access/jest.config.ts"", + "}", + "}", + "},", + ""tags": []", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [ + "export * from './lib/test-core-data-access.module';", + ], + "isBinary": false, + "path": "libs/test/core/data-access/src/index.ts", + }, + "lib": { + "children": { + "test-core-data-access.module.ts": { + "content": [ + "import { Module } from '@nestjs/common';", + "import { TestCoreService } from './test-core.service';", + "@Module({", + "controllers: [],", + "providers: [TestCoreService],", + "exports: [],", + "})", + "export class TestCoreDataAccessModule {}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/src/lib/test-core-data-access.module.ts", + }, + "test-core.service.spec.ts": { + "content": [ + "import { Test, TestingModule } from '@nestjs/testing';", + "import { TestCoreService } from './test-core.service';", + "describe('TestCoreService', () => {", + "let service: TestCoreService;", + "beforeEach(async () => {", + "const module: TestingModule = await Test.createTestingModule({", + "providers: [TestCoreService],", + "}).compile();", + "service = module.get(TestCoreService);", + "});", + "it('should be defined', () => {", + "expect(service).toBeDefined();", + "});", + "});", + ], + "isBinary": false, + "path": "libs/test/core/data-access/src/lib/test-core.service.spec.ts", + }, + "test-core.service.ts": { + "content": [ + "import { Injectable } from '@nestjs/common';", + "@Injectable()", + "export class TestCoreService {}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/src/lib/test-core.service.ts", + }, + }, + "path": "libs/test/core/data-access/src/lib", + }, + }, + "path": "libs/test/core/data-access/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""extends": "../../../../tsconfig.base.json",", + ""compilerOptions": {", + ""module": "commonjs",", + ""forceConsistentCasingInFileNames": true,", + ""strict": true,", + ""noImplicitOverride": true,", + ""noPropertyAccessFromIndexSignature": true,", + ""noImplicitReturns": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "},", + "{", + ""path": "./tsconfig.spec.json"", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""declaration": true,", + ""types": ["node"],", + ""target": "es6",", + ""strictNullChecks": true,", + ""noImplicitAny": true,", + ""strictBindCallApply": true,", + ""forceConsistentCasingInFileNames": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""include": ["src/**/*.ts"],", + ""exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/tsconfig.lib.json", + }, + "tsconfig.spec.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""module": "commonjs",", + ""types": ["jest", "node"]", + "},", + ""include": [", + ""jest.config.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.d.ts"", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/tsconfig.spec.json", + }, + }, + "path": "libs/test/core/data-access", + }, + "feature": { + "children": { + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-core-feature", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-core-feature\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/core/feature/README.md", + }, + "jest.config.ts": { + "content": [ + "/* eslint-disable */", + "export default {", + "displayName: 'test-core-feature',", + "preset: '../../../../jest.preset.js',", + "testEnvironment: 'node',", + "transform: {", + "'^.+\\\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }],", + "},", + "moduleFileExtensions: ['ts', 'js', 'html'],", + "coverageDirectory: '../../../../coverage/libs/test/core/feature',", + "};", + ], + "isBinary": false, + "path": "libs/test/core/feature/jest.config.ts", + }, + "project.json": { + "content": [ + "{", + ""name": "test-core-feature",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/core/feature/src",", + ""projectType": "library",", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "},", + ""test": {", + ""executor": "@nx/jest:jest",", + ""outputs": ["{workspaceRoot}/coverage/{projectRoot}"],", + ""options": {", + ""jestConfig": "libs/test/core/feature/jest.config.ts"", + "}", + "}", + "},", + ""tags": []", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [ + "export * from './lib/test-core-feature.module';", + ], + "isBinary": false, + "path": "libs/test/core/feature/src/index.ts", + }, + "lib": { + "children": { + "test-core-feature.module.ts": { + "content": [ + "import { Module } from '@nestjs/common';", + "import { TestCompanyFeatureModule } from '@proj/test-company-feature';", + "@Module({", + "controllers: [],", + "providers: [],", + "exports: [],", + "})", + "export class TestCoreFeatureModule {}", + ], + "isBinary": false, + "path": "libs/test/core/feature/src/lib/test-core-feature.module.ts", + }, + }, + "path": "libs/test/core/feature/src/lib", + }, + }, + "path": "libs/test/core/feature/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""extends": "../../../../tsconfig.base.json",", + ""compilerOptions": {", + ""module": "commonjs",", + ""forceConsistentCasingInFileNames": true,", + ""strict": true,", + ""noImplicitOverride": true,", + ""noPropertyAccessFromIndexSignature": true,", + ""noImplicitReturns": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "},", + "{", + ""path": "./tsconfig.spec.json"", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""declaration": true,", + ""types": ["node"],", + ""target": "es6",", + ""strictNullChecks": true,", + ""noImplicitAny": true,", + ""strictBindCallApply": true,", + ""forceConsistentCasingInFileNames": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""include": ["src/**/*.ts"],", + ""exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/tsconfig.lib.json", + }, + "tsconfig.spec.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""module": "commonjs",", + ""types": ["jest", "node"]", + "},", + ""include": [", + ""jest.config.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.d.ts"", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/tsconfig.spec.json", + }, + }, + "path": "libs/test/core/feature", + }, + }, + "path": "libs/test/core", + }, + "sdk": { + "children": { + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/sdk/.eslintrc.json", + }, + "README.md": { + "content": [ + "# sdk", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test sdk\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/sdk/README.md", + }, + "jest.config.ts": { + "content": [ + "/* eslint-disable */", + "export default {", + "displayName: 'sdk',", + "preset: '../../../jest.preset.js',", + "testEnvironment: 'node',", + "transform: {", + "'^.+\\\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }],", + "},", + "moduleFileExtensions: ['ts', 'js', 'html'],", + "coverageDirectory: '../../../coverage/libs/test/sdk',", + "};", + ], + "isBinary": false, + "path": "libs/test/sdk/jest.config.ts", + }, + "project.json": { + "content": [ + "{", + ""name": "sdk",", + ""$schema": "../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/sdk/src",", + ""projectType": "library",", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "},", + ""test": {", + ""executor": "@nx/jest:jest",", + ""outputs": ["{workspaceRoot}/coverage/{projectRoot}"],", + ""options": {", + ""jestConfig": "libs/test/sdk/jest.config.ts"", + "}", + "}", + "},", + ""tags": []", + "}", + ], + "isBinary": false, + "path": "libs/test/sdk/project.json", + }, + "src": { + "children": { + "graphql": { + "children": { + "feature-company.graphql": { + "content": [ + "fragment CompanyDetails on Company {", + "createdAt", + "id", + "name", + "location", + "phone", + "updatedAt", + "}", + "query userFindManyCompany($input: UserFindManyCompanyInput!) {", + "paging: userFindManyCompany(input: $input) {", + "data {", + "...CompanyDetails", + "}", + "meta {", + "...PagingMetaDetails", + "}", + "}", + "}", + "query userFindOneCompany($companyId: String!) {", + "item: userFindOneCompany(companyId: $companyId) {", + "...CompanyDetails", + "}", + "}", + "mutation userCreateCompany($input: UserCreateCompanyInput!) {", + "created: userCreateCompany(input: $input) {", + "...CompanyDetails", + "}", + "}", + "mutation userUpdateCompany(", + "$companyId: String!", + "$input: UserUpdateCompanyInput!", + ") {", + "updated: userUpdateCompany(companyId: $companyId, input: $input) {", + "...CompanyDetails", + "}", + "}", + "mutation userDeleteCompany($companyId: String!) {", + "deleted: userDeleteCompany(companyId: $companyId)", + "}", + "query adminFindManyCompany($input: AdminFindManyCompanyInput!) {", + "paging: adminFindManyCompany(input: $input) {", + "data {", + "...CompanyDetails", + "}", + "meta {", + "...PagingMetaDetails", + "}", + "}", + "}", + "query adminFindOneCompany($companyId: String!) {", + "item: adminFindOneCompany(companyId: $companyId) {", + "...CompanyDetails", + "}", + "}", + "mutation adminCreateCompany($input: AdminCreateCompanyInput!) {", + "created: adminCreateCompany(input: $input) {", + "...CompanyDetails", + "}", + "}", + "mutation adminUpdateCompany(", + "$companyId: String!", + "$input: AdminUpdateCompanyInput!", + ") {", + "updated: adminUpdateCompany(companyId: $companyId, input: $input) {", + "...CompanyDetails", + "}", + "}", + "mutation adminDeleteCompany($companyId: String!) {", + "deleted: adminDeleteCompany(companyId: $companyId)", + "}", + ], + "isBinary": false, + "path": "libs/test/sdk/src/graphql/feature-company.graphql", + }, + }, + "path": "libs/test/sdk/src/graphql", + }, + "index.ts": { + "content": [ + "export * from './lib/sdk.module';", + ], + "isBinary": false, + "path": "libs/test/sdk/src/index.ts", + }, + "lib": { + "children": { + "sdk.module.ts": { + "content": [ + "import { Module } from '@nestjs/common';", + "@Module({", + "controllers: [],", + "providers: [],", + "exports: [],", + "})", + "export class SdkModule {}", + ], + "isBinary": false, + "path": "libs/test/sdk/src/lib/sdk.module.ts", + }, + }, + "path": "libs/test/sdk/src/lib", + }, + }, + "path": "libs/test/sdk/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""extends": "../../../tsconfig.base.json",", + ""compilerOptions": {", + ""module": "commonjs",", + ""forceConsistentCasingInFileNames": true,", + ""strict": true,", + ""noImplicitOverride": true,", + ""noPropertyAccessFromIndexSignature": true,", + ""noImplicitReturns": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "},", + "{", + ""path": "./tsconfig.spec.json"", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/sdk/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../dist/out-tsc",", + ""declaration": true,", + ""types": ["node"],", + ""target": "es6",", + ""strictNullChecks": true,", + ""noImplicitAny": true,", + ""strictBindCallApply": true,", + ""forceConsistentCasingInFileNames": true,", + ""noFallthroughCasesInSwitch": true", + "},", + ""include": ["src/**/*.ts"],", + ""exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]", + "}", + ], + "isBinary": false, + "path": "libs/test/sdk/tsconfig.lib.json", + }, + "tsconfig.spec.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../dist/out-tsc",", + ""module": "commonjs",", + ""types": ["jest", "node"]", + "},", + ""include": [", + ""jest.config.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.d.ts"", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/sdk/tsconfig.spec.json", + }, + }, + "path": "libs/test/sdk", + }, +} +`; + +exports[`api-crud generator should create crud with modelParentid 1`] = ` +{ + "company": { + "children": { + "data-access": { + "children": { + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-company-data-access", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-company-data-access\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/company/data-access/README.md", + }, + "jest.config.ts": { + "content": [ + "/* eslint-disable */", + "export default {", + "displayName: 'test-company-data-access',", + "preset: '../../../../jest.preset.js',", + "testEnvironment: 'node',", + "transform: {", + "'^.+\\\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }],", + "},", + "moduleFileExtensions: ['ts', 'js', 'html'],", + "coverageDirectory: '../../../../coverage/libs/test/company/data-access',", + "};", + ], + "isBinary": false, + "path": "libs/test/company/data-access/jest.config.ts", + }, + "project.json": { + "content": [ + "{", + ""name": "test-company-data-access",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/company/data-access/src",", + ""projectType": "library",", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "},", + ""test": {", + ""executor": "@nx/jest:jest",", + ""outputs": ["{workspaceRoot}/coverage/{projectRoot}"],", + ""options": {", + ""jestConfig": "libs/test/company/data-access/jest.config.ts"", + "}", + "}", + "},", + ""tags": ["app:test", "type:data-access"]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [ + "export * from './lib/test-company.data-access.module';", + "export * from './lib/test-company.service';", + "export * from './lib/entity/company.entity';", + "export * from './lib/dto/admin-create-company.input';", + "export * from './lib/dto/admin-find-many-company.input';", + "export * from './lib/dto/admin-update-company.input';", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/index.ts", + }, + "lib": { + "children": { + "dto": { + "children": { + "admin-create-company.input.ts": { + "content": [ + "import { Field, InputType } from '@nestjs/graphql';", + "@InputType()", + "export class AdminCreateCompanyInput {", + "@Field()", + "name!: string;", + "@Field()", + "location!: string;", + "@Field({ nullable: true })", + "phone?: string;", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/dto/admin-create-company.input.ts", + }, + "admin-find-many-company.input.ts": { + "content": [ + "import { Field, InputType } from '@nestjs/graphql';", + "import { PagingInput } from '@proj/test-core-data-access';", + "@InputType()", + "export class AdminFindManyCompanyInput extends PagingInput() {", + "@Field()", "ownerId!: string;", "@Field({ nullable: true })", "search?: string;", @@ -172,9 +2993,9 @@ exports[`api-crud generator should create crud with parent ID 1`] = ` "location!: string;", "@Field({ nullable: true })", "phone?: string;", - "@Field(() => String)", + "@Field()", "ownerId!: string;", - "@Field(() => () => User, { nullable: true })", + "@Field(() => User, { nullable: true })", "owner?: User;", "}", "@ObjectType()", @@ -195,7 +3016,9 @@ exports[`api-crud generator should create crud with parent ID 1`] = ` "export function getCompanyWhereAdminInput(", "input: AdminFindManyCompanyInput", "): Prisma.CompanyWhereInput {", - "const where: Prisma.CompanyWhereInput = { ownerId: input.ownerId };", + "const where: Prisma.CompanyWhereInput = {", + "ownerId: input.ownerId,", + "};", "if (input.search) {", "where.OR = [", "{ id: { contains: input.search, mode: 'insensitive' } },", @@ -223,10 +3046,10 @@ exports[`api-crud generator should create crud with parent ID 1`] = ` "@Injectable()", "export class TestCompanyDataAdminService {", "constructor(private readonly data: TestCompanyDataService) {}", - "async createCompany(ownerId: string, input: AdminCreateCompanyInput) {", + "async createCompany(input: AdminCreateCompanyInput) {", "return this.data.create(input);", "}", - "async deleteCompany(ownerId: string, companyId: string) {", + "async deleteCompany(companyId: string) {", "return this.data.delete(companyId);", "}", "async findManyCompany(", @@ -239,14 +3062,10 @@ exports[`api-crud generator should create crud with parent ID 1`] = ` "page: input.page,", "});", "}", - "async findOneCompany(ownerId: string, companyId: string) {", + "async findOneCompany(companyId: string) {", "return this.data.findOne(companyId);", "}", - "async updateCompany(", - "ownerId: string,", - "companyId: string,", - "input: AdminUpdateCompanyInput", - ") {", + "async updateCompany(companyId: string, input: AdminUpdateCompanyInput) {", "return this.data.update(companyId, input);", "}", "}", @@ -286,7 +3105,13 @@ exports[`api-crud generator should create crud with parent ID 1`] = ` ".then(([data, meta]) => ({ data, meta }));", "}", "async findOne(companyId: string) {", - "return this.core.data.company.findUnique({ where: { id: companyId } });", + "const found = await this.core.data.company.findUnique({", + "where: { id: companyId },", + "});", + "if (!found) {", + "throw new Error('Company not found');", + "}", + "return found;", "}", "async update(companyId: string, input: Prisma.CompanyUpdateInput) {", "return this.core.data.company.update({", @@ -509,10 +3334,7 @@ exports[`api-crud generator should create crud with parent ID 1`] = ` "content": [ "import { Resolver } from '@nestjs/graphql';", "import { TestCompanyService } from '@proj/test-company-data-access';", - "import {", - "TestAuthGraphQLAdminGuard,", - "CtxUserId,", - "} from '@proj/test-auth-data-access';", + "import { TestAuthGraphQLAdminGuard } from '@proj/test-auth-data-access';", "import { Mutation, Query, Args } from '@nestjs/graphql';", "import { UseGuards } from '@nestjs/common';", "import {", @@ -527,37 +3349,27 @@ exports[`api-crud generator should create crud with parent ID 1`] = ` "export class TestCompanyAdminResolver {", "constructor(private readonly service: TestCompanyService) {}", "@Mutation(() => Company, { nullable: true })", - "adminCreateCompany(", - "@CtxUserId() ownerId: string,", - "@Args('input') input: AdminCreateCompanyInput", - ") {", - "return this.service.admin.createCompany(ownerId, input);", + "adminCreateCompany(@Args('input') input: AdminCreateCompanyInput) {", + "return this.service.admin.createCompany(input);", "}", "@Mutation(() => Boolean, { nullable: true })", - "adminDeleteCompany(", - "@CtxUserId() ownerId: string,", - "@Args('companyId') companyId: string", - ") {", - "return this.service.admin.deleteCompany(ownerId, companyId);", + "adminDeleteCompany(@Args('companyId') companyId: string) {", + "return this.service.admin.deleteCompany(companyId);", "}", "@Query(() => CompanyPaging)", "adminFindManyCompany(@Args('input') input: AdminFindManyCompanyInput) {", "return this.service.admin.findManyCompany(input);", "}", "@Query(() => Company, { nullable: true })", - "adminFindOneCompany(", - "@CtxUserId() ownerId: string,", - "@Args('companyId') companyId: string", - ") {", - "return this.service.admin.findOneCompany(ownerId, companyId);", + "adminFindOneCompany(@Args('companyId') companyId: string) {", + "return this.service.admin.findOneCompany(companyId);", "}", "@Mutation(() => Company, { nullable: true })", "adminUpdateCompany(", - "@CtxUserId() ownerId: string,", "@Args('companyId') companyId: string,", "@Args('input') input: AdminUpdateCompanyInput", ") {", - "return this.service.admin.updateCompany(ownerId, companyId, input);", + "return this.service.admin.updateCompany(companyId, input);", "}", "}", ], @@ -1584,7 +4396,13 @@ exports[`api-crud generator should run successfully 1`] = ` ".then(([data, meta]) => ({ data, meta }));", "}", "async findOne(companyId: string) {", - "return this.core.data.company.findUnique({ where: { id: companyId } });", + "const found = await this.core.data.company.findUnique({", + "where: { id: companyId },", + "});", + "if (!found) {", + "throw new Error('Company not found');", + "}", + "return found;", "}", "async update(companyId: string, input: Prisma.CompanyUpdateInput) {", "return this.core.data.company.update({", diff --git a/libs/tools/src/generators/api-crud/api-crud-generator.spec.ts b/libs/tools/src/generators/api-crud/api-crud-generator.spec.ts index bcfd3dd..c0d8354 100644 --- a/libs/tools/src/generators/api-crud/api-crud-generator.spec.ts +++ b/libs/tools/src/generators/api-crud/api-crud-generator.spec.ts @@ -27,7 +27,8 @@ describe('api-crud generator', () => { }) expect(contents).toMatchSnapshot() }) - it('should create crud with parent ID', async () => { + + it('should create crud with modelParentid', async () => { await apiCrudGenerator(tree, { ...options, modelParent: 'User', modelParentId: 'ownerId' }) const config = readProjectConfiguration(tree, 'test') expect(config).toBeDefined() @@ -38,4 +39,29 @@ describe('api-crud generator', () => { }) expect(contents).toMatchSnapshot() }) + + it('should create crud with modelOwnerId', async () => { + await apiCrudGenerator(tree, { ...options, modelOwnerId: 'ownerId' }) + const config = readProjectConfiguration(tree, 'test') + expect(config).toBeDefined() + + const contents = getRecursiveFileContents({ + tree, + path: 'libs/test', + }) + expect(contents).toMatchSnapshot() + }) + + it('should create crud with modelOwnerId for admin and user', async () => { + await apiCrudGenerator(tree, { ...options, modelOwnerId: 'ownerId', actor: 'user' }) + await apiCrudGenerator(tree, { ...options, modelOwnerId: 'ownerId', actor: 'admin' }) + const config = readProjectConfiguration(tree, 'test') + expect(config).toBeDefined() + + const contents = getRecursiveFileContents({ + tree, + path: 'libs/test', + }) + expect(contents).toMatchSnapshot() + }) }) diff --git a/libs/tools/src/generators/api-crud/api-crud-schema.d.ts b/libs/tools/src/generators/api-crud/api-crud-schema.d.ts index 184507e..5d71cb6 100644 --- a/libs/tools/src/generators/api-crud/api-crud-schema.d.ts +++ b/libs/tools/src/generators/api-crud/api-crud-schema.d.ts @@ -23,11 +23,15 @@ export interface ApiCrudGeneratorSchema { */ model: string /** - * The id field of the model owner. Generally 'userId' or 'ownerId'. + * The id field linked to the User model for this feature. Generally 'userId' or 'ownerId'. + */ + modelOwnerId?: string + /** + * The id field of the parent model for this feature. */ modelParentId?: string /** - * The name of the model owner. Generally 'User'. + * The name of the parent model for this feature. */ modelParent?: string } diff --git a/libs/tools/src/generators/api-crud/api-crud-schema.json b/libs/tools/src/generators/api-crud/api-crud-schema.json index 0834cbd..de04e42 100644 --- a/libs/tools/src/generators/api-crud/api-crud-schema.json +++ b/libs/tools/src/generators/api-crud/api-crud-schema.json @@ -26,13 +26,17 @@ "description": "The name of the model for this feature.", "x-prompt": "What is the name of the model for this feature?" }, + "modelOwnerId": { + "type": "string", + "description": "The id field linked to the User model for this feature. Generally 'userId' or 'ownerId'." + }, "modelParentId": { "type": "string", - "description": "The id field of the model owner. Generally 'userId' or 'ownerId'." + "description": "The id field of the parent model for this feature." }, "modelParent": { "type": "string", - "description": "The name of the model owner. Generally 'User'." + "description": "The name of the parent model for this feature." } }, "required": ["app", "actor", "model"] diff --git a/libs/tools/src/generators/api-feature/__snapshots__/api-feature-generator.spec.ts.snap b/libs/tools/src/generators/api-feature/__snapshots__/api-feature-generator.spec.ts.snap index 9a3d158..859c925 100644 --- a/libs/tools/src/generators/api-feature/__snapshots__/api-feature-generator.spec.ts.snap +++ b/libs/tools/src/generators/api-feature/__snapshots__/api-feature-generator.spec.ts.snap @@ -129,7 +129,13 @@ export class ApiTestDataService { } async findOne(testId: string) { - return this.core.data.test.findUnique({ where: { id: testId } }); + const found = await this.core.data.test.findUnique({ + where: { id: testId }, + }); + if (!found) { + throw new Error('Test not found'); + } + return found; } async update(testId: string, input: Prisma.TestUpdateInput) { diff --git a/libs/tools/src/generators/api-feature/api-feature-schema.d.ts b/libs/tools/src/generators/api-feature/api-feature-schema.d.ts index 9ff1adf..9b77015 100644 --- a/libs/tools/src/generators/api-feature/api-feature-schema.d.ts +++ b/libs/tools/src/generators/api-feature/api-feature-schema.d.ts @@ -11,11 +11,15 @@ export interface ApiFeatureGeneratorSchema { */ model: string /** - * The id field of the model owner. Generally 'userId' or 'ownerId'. + * The id field linked to the User model for this feature. Generally 'userId' or 'ownerId'. + */ + modelOwnerId?: string + /** + * The id field of the parent model for this feature. */ modelParentId?: string /** - * The name of the model owner. Generally 'User'. + * The name of the parent model for this feature. */ modelParent?: string /** diff --git a/libs/tools/src/generators/api-feature/api-feature-schema.json b/libs/tools/src/generators/api-feature/api-feature-schema.json index 5f0c31b..6213ffe 100644 --- a/libs/tools/src/generators/api-feature/api-feature-schema.json +++ b/libs/tools/src/generators/api-feature/api-feature-schema.json @@ -13,13 +13,17 @@ "index": 0 } }, + "modelOwnerId": { + "type": "string", + "description": "The id field linked to the User model for this feature. Generally 'userId' or 'ownerId'." + }, "modelParentId": { "type": "string", - "description": "The id field of the model owner. Generally 'userId' or 'ownerId'." + "description": "The id field of the parent model for this feature." }, "modelParent": { "type": "string", - "description": "The name of the model owner. Generally 'User'." + "description": "The name of the parent model for this feature." }, "app": { "type": "string", diff --git a/libs/tools/src/generators/web-feature/__snapshots__/web-feature-generator.spec.ts.snap b/libs/tools/src/generators/web-feature/__snapshots__/web-feature-generator.spec.ts.snap index 3ee4c3d..157aaf0 100644 --- a/libs/tools/src/generators/web-feature/__snapshots__/web-feature-generator.spec.ts.snap +++ b/libs/tools/src/generators/web-feature/__snapshots__/web-feature-generator.spec.ts.snap @@ -257,7 +257,7 @@ export function AdminTestCreateFeature() { exports[`web-feature generator should run successfully with crud 11`] = ` "import { useAdminFindOneTest } from '@proj/web-test-data-access'; import { TestUiInfo } from '@proj/web-test-ui'; -import { UiCard, UiDebug, UiError, UiLoader } from '@pubkey-ui/core'; +import { UiCard, UiError, UiLoader } from '@pubkey-ui/core'; export function AdminTestDetailInfoTab({ testId }: { testId: string }) { const { item, query } = useAdminFindOneTest({ testId }); @@ -313,6 +313,7 @@ import { UiTabRoutes, } from '@pubkey-ui/core'; import { useAdminFindOneTest } from '@proj/web-test-data-access'; +import { TestUiItem } from '@proj/web-test-ui'; import { useParams } from 'react-router-dom'; import { AdminTestDetailInfoTab } from './admin-test-detail-info.tab'; import { AdminTestDetailSettingsTab } from './admin-test-detail-settings.tab'; @@ -330,7 +331,7 @@ export function AdminTestDetailFeature() { return ( {item.name}} + title={} leftAction={} rightAction={ @@ -481,7 +482,7 @@ export function UserTestCreateFeature() { exports[`web-feature generator should run successfully with crud 17`] = ` "import { useUserFindOneTest } from '@proj/web-test-data-access'; import { TestUiInfo } from '@proj/web-test-ui'; -import { UiCard, UiDebug, UiError, UiLoader } from '@pubkey-ui/core'; +import { UiCard, UiError, UiLoader } from '@pubkey-ui/core'; export function UserTestDetailInfoTab({ testId }: { testId: string }) { const { item, query } = useUserFindOneTest({ testId }); @@ -537,6 +538,7 @@ import { UiTabRoutes, } from '@pubkey-ui/core'; import { useUserFindOneTest } from '@proj/web-test-data-access'; +import { TestUiItem } from '@proj/web-test-ui'; import { useParams } from 'react-router-dom'; import { UserTestDetailInfoTab } from './user-test-detail-info.tab'; import { UserTestDetailSettingsTab } from './user-test-detail-settings.tab'; @@ -554,7 +556,7 @@ export function UserTestDetailFeature() { return ( {item.name}} + title={} leftAction={} rightAction={ @@ -962,7 +964,7 @@ export function TestUiItem({ - + {test?.name} diff --git a/libs/tools/src/generators/web-feature/web-feature-schema.json b/libs/tools/src/generators/web-feature/web-feature-schema.json index 72b4e02..a37e053 100644 --- a/libs/tools/src/generators/web-feature/web-feature-schema.json +++ b/libs/tools/src/generators/web-feature/web-feature-schema.json @@ -40,7 +40,7 @@ "skipUi": { "type": "boolean", "description": "Do not create a ui library for this feature.", - "default": true + "default": false } }, "required": ["model"] diff --git a/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data-__actorFileName__.service.ts.template b/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data-__actorFileName__.service.ts.template index bf96a43..0a2b26d 100644 --- a/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data-__actorFileName__.service.ts.template +++ b/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data-__actorFileName__.service.ts.template @@ -11,28 +11,48 @@ import { <%= app.className %><%= model.className %>DataService } from './<%= app export class <%= app.className %><%= model.className %>Data<%= actor.className %>Service { constructor(private readonly data: <%= app.className %><%= model.className %>DataService) {} - async create<%= model.className %>(<% if(parent){ %><%= parentId %>: string, <% } %>input: <%= actor.className %>Create<%= model.className %>Input) { - return this.data.create(<% if(parent && parent.className !== 'User'){ %>{...input, <%= parentId %> }<% } else { %>input<% } %>) + async create<%= model.className %>(<% if(ownerId && actor.className !== 'Admin'){ %><%= ownerId %>: string, <% } %>input: <%= actor.className %>Create<%= model.className %>Input) { + return this.data.create(<% if(ownerId && actor.className !== 'Admin'){ %>{...input, <%= ownerId %> }<% } else { %>input<% } %>) } - async delete<%= model.className %>(<% if(parent){ %><%= parentId %>: string, <% } %><%= model.propertyName %>Id: string) { + async delete<%= model.className %>(<% if(ownerId && actor.className !== 'Admin'){ %><%= ownerId %>: string, <% } %><%= model.propertyName %>Id: string) { + <% if(ownerId && actor.className !== 'Admin'){ %> + const found = await this.data.findOne(<%= model.propertyName %>Id) + if (found.<%= ownerId %> !== <%= ownerId %>) { + throw new Error('You are not authorized to delete this <%= model.className %>') + } + <% } %> return this.data.delete(<%= model.propertyName %>Id) } - async findMany<%= model.className %>(input: <%= actor.className %>FindMany<%= model.className %>Input): Promise<<%= model.className %>Paging> { + async findMany<%= model.className %>(<% if(ownerId && actor.className !== 'Admin'){ %><%= ownerId %>: string, <% } %>input: <%= actor.className %>FindMany<%= model.className %>Input): Promise<<%= model.className %>Paging> { return this.data.findMany({ orderBy: { createdAt: 'desc' }, - where: get<%= model.className %>Where<%= actor.className %>Input(input), + where: get<%= model.className %>Where<%= actor.className %>Input(<% if(ownerId && actor.className !== 'Admin'){ %><%= ownerId %>, <% } %>input), limit: input.limit, page: input.page }) } - async findOne<%= model.className %>(<% if(parent){ %><%= parentId %>: string, <% } %><%= model.propertyName %>Id: string) { + async findOne<%= model.className %>(<% if(ownerId && actor.className !== 'Admin'){ %><%= ownerId %>: string, <% } %><%= model.propertyName %>Id: string) { + <% if(ownerId && actor.className !== 'Admin'){ %> + const found = await this.data.findOne(<%= model.propertyName %>Id) + if (found.<%= ownerId %> !== <%= ownerId %>) { + throw new Error('You are not authorized to view this <%= model.className %>') + } + return found + <% } else { %> return this.data.findOne(<%= model.propertyName %>Id) + <% } %> } - async update<%= model.className %>(<% if(parent){ %><%= parentId %>: string, <% } %><%= model.propertyName %>Id: string, input: <%= actor.className %>Update<%= model.className %>Input) { + async update<%= model.className %>(<% if(ownerId && actor.className !== 'Admin'){ %><%= ownerId %>: string, <% } %><%= model.propertyName %>Id: string, input: <%= actor.className %>Update<%= model.className %>Input) { + <% if(ownerId && actor.className !== 'Admin'){ %> + const found = await this.data.findOne(<%= model.propertyName %>Id) + if (found.<%= ownerId %> !== <%= ownerId %>) { + throw new Error('You are not authorized to update this <%= model.className %>') + } + <% } %> return this.data.update(<%= model.propertyName %>Id, input) } } diff --git a/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data.service.ts.template b/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data.service.ts.template index d87adb3..1dc48ab 100644 --- a/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data.service.ts.template +++ b/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data.service.ts.template @@ -28,7 +28,11 @@ export class <%= app.className %><%= model.className %>DataService { } async findOne(<%= model.propertyName %>Id: string) { - return this.core.data.<%= model.propertyName %>.findUnique({ where: { id: <%= model.propertyName %>Id } }) + const found = await this.core.data.<%= model.propertyName %>.findUnique({ where: { id: <%= model.propertyName %>Id } }) + if (!found) { + throw new Error('<%= model.className %> not found') + } + return found } async update(<%= model.propertyName %>Id: string, input: Prisma.<%= model.className %>UpdateInput) { diff --git a/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__actorFileName__-create-__modelFileName__.input.ts.template b/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__actorFileName__-create-__modelFileName__.input.ts.template index 5d11e25..cc712da 100644 --- a/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__actorFileName__-create-__modelFileName__.input.ts.template +++ b/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__actorFileName__-create-__modelFileName__.input.ts.template @@ -8,7 +8,11 @@ export class <%= actor.className %>Create<%= model.className %>Input { <%= field.name %><% if(field.optional){ %>?<% } else { %>!<% } %>: <%= field.type %> <% } %> <% if(parent && parent.className !== 'User'){ %> - @Field(() => String) + @Field() <%= parentId %>!: string <% } %> +<% if(ownerId && actor.className === 'Admin'){ %> + @Field() + <%= ownerId %>!: string +<% } %> } diff --git a/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__actorFileName__-find-many-__modelFileName__.input.ts.template b/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__actorFileName__-find-many-__modelFileName__.input.ts.template index c35f77a..a2044b9 100644 --- a/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__actorFileName__-find-many-__modelFileName__.input.ts.template +++ b/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__actorFileName__-find-many-__modelFileName__.input.ts.template @@ -3,8 +3,12 @@ import { PagingInput } from '@<%= npmScope %>/<%= app.fileName %>-core-data-acce @InputType() export class <%= actor.className %>FindMany<%= model.className %>Input extends PagingInput() { +<% if(!parent && ownerId && actor.className === 'Admin'){ %> + @Field() + <%= ownerId %>!: string +<% } %> <% if(parent){ %> - @Field(() => String) + @Field() <%= parentId %>!: string <% } %> @Field({ nullable: true }) diff --git a/libs/tools/src/lib/api-crud/files/data-access/lib/helpers/get-__modelFileName__-where-__actorFileName__.input.ts.template b/libs/tools/src/lib/api-crud/files/data-access/lib/helpers/get-__modelFileName__-where-__actorFileName__.input.ts.template index e017349..258fd25 100644 --- a/libs/tools/src/lib/api-crud/files/data-access/lib/helpers/get-__modelFileName__-where-__actorFileName__.input.ts.template +++ b/libs/tools/src/lib/api-crud/files/data-access/lib/helpers/get-__modelFileName__-where-__actorFileName__.input.ts.template @@ -1,8 +1,12 @@ import { Prisma } from '@prisma/client' import { <%= actor.className %>FindMany<%= model.className %>Input } from '../dto/<%= actor.fileName %>-find-many-<%= model.fileName %>.input' -export function get<%= model.className %>Where<%= actor.className %>Input(input: <%= actor.className %>FindMany<%= model.className %>Input): Prisma.<%= model.className %>WhereInput { - const where: Prisma.<%= model.className %>WhereInput = {<% if(parent){ %><%= parentId %>: input.<%= parentId %><% } %>} +export function get<%= model.className %>Where<%= actor.className %>Input(<% if(ownerId && actor.className !== 'Admin'){ %><%= ownerId %>: string, <% } %>input: <%= actor.className %>FindMany<%= model.className %>Input): Prisma.<%= model.className %>WhereInput { + const where: Prisma.<%= model.className %>WhereInput = { + <% if(parent){ %><%= parentId %>: input.<%= parentId %><% } %> + <% if(owner && actor.className !== 'Admin'){ %><%= ownerId %>: <%= ownerId %><% } %> + <% if(!parent && owner && actor.className === 'Admin'){ %><%= ownerId %>: input.<%= ownerId %><% } %> + } if (input.search) { where.OR = [ diff --git a/libs/tools/src/lib/api-crud/files/entity/lib/entity/__modelFileName__.entity.ts.template b/libs/tools/src/lib/api-crud/files/entity/lib/entity/__modelFileName__.entity.ts.template index 6f1f54a..17a1cb4 100644 --- a/libs/tools/src/lib/api-crud/files/entity/lib/entity/__modelFileName__.entity.ts.template +++ b/libs/tools/src/lib/api-crud/files/entity/lib/entity/__modelFileName__.entity.ts.template @@ -1,6 +1,7 @@ import { Field, ObjectType } from '@nestjs/graphql' import { PagingResponse } from '@<%= npmScope %>/<%= app.fileName %>-core-data-access' <% if(parent){ %> import { <%= parent.className %> } from '@<%= npmScope %>/<%= app.fileName %>-<%= parent.fileName %>-data-access' <% } %> +<% if(owner){ %> import { <%= owner.className %> } from '@<%= npmScope %>/<%= app.fileName %>-<%= owner.fileName %>-data-access' <% } %> @ObjectType() export class <%= model.className %> { @@ -15,11 +16,17 @@ export class <%= model.className %> { <%= field.name %><% if(field.optional){ %>?<% } else { %>!<% } %>: <%= field.type %> <% } %> <% if(parent){ %> - @Field(() => String) + @Field() <%= parentId %>!: string - @Field(() => () => <%= parent.className %>, { nullable: true }) + @Field(() => <%= parent.className %>, { nullable: true }) <%= parentPropertyId %>?: <%= parent.className %> <% } %> +<% if(owner){ %> + @Field() + <%= ownerId %>!: string + @Field(() => <%= owner.className %>, { nullable: true }) + <%= ownerPropertyId %>?: <%= owner.className %> +<% } %> } @ObjectType() diff --git a/libs/tools/src/lib/api-crud/files/feature/lib/__appFileName__-__modelFileName__-__actorFileName__.resolver.ts.template b/libs/tools/src/lib/api-crud/files/feature/lib/__appFileName__-__modelFileName__-__actorFileName__.resolver.ts.template index 3e5cf72..7a156ce 100644 --- a/libs/tools/src/lib/api-crud/files/feature/lib/__appFileName__-__modelFileName__-__actorFileName__.resolver.ts.template +++ b/libs/tools/src/lib/api-crud/files/feature/lib/__appFileName__-__modelFileName__-__actorFileName__.resolver.ts.template @@ -1,6 +1,6 @@ import { Resolver } from '@nestjs/graphql' import { <%= app.className %><%= model.className %>Service } from '@<%= npmScope %>/<%= app.fileName %>-<%= model.fileName %>-data-access' -import { <%= app.className %>AuthGraphQL<%= actor.className %>Guard<% if(parent){ %>, CtxUserId<% } %> } from '@<%= npmScope %>/<%= app.fileName %>-auth-data-access' +import { <%= app.className %>AuthGraphQL<%= actor.className %>Guard<% if(ownerId && actor.className !== 'Admin'){ %>, CtxUserId<% } %> } from '@<%= npmScope %>/<%= app.fileName %>-auth-data-access' import { Mutation, Query, Args } from '@nestjs/graphql' import { UseGuards } from '@nestjs/common' import { @@ -18,34 +18,36 @@ export class <%= app.className %><%= model.className %><%= actor.className %>Res @Mutation(() => <%= model.className %>, { nullable: true }) <%= actor.propertyName %>Create<%= model.className %>( - <% if(parent){ %>@CtxUserId() <%= parentId %>: string,<% } %> + <% if(ownerId && actor.className !== 'Admin'){ %>@CtxUserId() <%= ownerId %>: string,<% } %> @Args('input') input: <%= actor.className %>Create<%= model.className %>Input) { - return this.service.<%= actor.propertyName %>.create<%= model.className %>(<% if(parent){ %><%= parentId %>, <% } %>input) + return this.service.<%= actor.propertyName %>.create<%= model.className %>(<% if(ownerId && actor.className !== 'Admin'){ %><%= ownerId %>, <% } %>input) } @Mutation(() => Boolean, { nullable: true }) <%= actor.propertyName %>Delete<%= model.className %>( - <% if(parent){ %>@CtxUserId() <%= parentId %>: string,<% } %> + <% if(ownerId && actor.className !== 'Admin'){ %>@CtxUserId() <%= ownerId %>: string,<% } %> @Args('<%= model.propertyName %>Id') <%= model.propertyName %>Id: string) { - return this.service.<%= actor.propertyName %>.delete<%= model.className %>(<% if(parent){ %><%= parentId %>, <% } %><%= model.propertyName %>Id) + return this.service.<%= actor.propertyName %>.delete<%= model.className %>(<% if(ownerId && actor.className !== 'Admin'){ %><%= ownerId %>, <% } %><%= model.propertyName %>Id) } @Query(() => <%= model.className %>Paging) - <%= actor.propertyName %>FindMany<%= model.className %>(@Args('input') input: <%= actor.className %>FindMany<%= model.className %>Input) { - return this.service.<%= actor.propertyName %>.findMany<%= model.className %>(input) + <%= actor.propertyName %>FindMany<%= model.className %>( + <% if(ownerId && actor.className !== 'Admin'){ %>@CtxUserId() <%= ownerId %>: string,<% } %> + @Args('input') input: <%= actor.className %>FindMany<%= model.className %>Input) { + return this.service.<%= actor.propertyName %>.findMany<%= model.className %>(<% if(ownerId && actor.className !== 'Admin'){ %><%= ownerId %>, <% } %>input) } @Query(() => <%= model.className %>, { nullable: true }) <%= actor.propertyName %>FindOne<%= model.className %>( - <% if(parent){ %>@CtxUserId() <%= parentId %>: string,<% } %> + <% if(ownerId && actor.className !== 'Admin'){ %>@CtxUserId() <%= ownerId %>: string,<% } %> @Args('<%= model.propertyName %>Id') <%= model.propertyName %>Id: string) { - return this.service.<%= actor.propertyName %>.findOne<%= model.className %>(<% if(parent){ %><%= parentId %>, <% } %><%= model.propertyName %>Id) + return this.service.<%= actor.propertyName %>.findOne<%= model.className %>(<% if(ownerId && actor.className !== 'Admin'){ %><%= ownerId %>, <% } %><%= model.propertyName %>Id) } @Mutation(() => <%= model.className %>, { nullable: true }) <%= actor.propertyName %>Update<%= model.className %>( - <% if(parent){ %>@CtxUserId() <%= parentId %>: string,<% } %> + <% if(ownerId && actor.className !== 'Admin'){ %>@CtxUserId() <%= ownerId %>: string,<% } %> @Args('<%= model.propertyName %>Id') <%= model.propertyName %>Id: string, @Args('input') input: <%= actor.className %>Update<%= model.className %>Input) { - return this.service.<%= actor.propertyName %>.update<%= model.className %>(<% if(parent){ %><%= parentId %>, <% } %><%= model.propertyName %>Id, input) + return this.service.<%= actor.propertyName %>.update<%= model.className %>(<% if(ownerId && actor.className !== 'Admin'){ %><%= ownerId %>, <% } %><%= model.propertyName %>Id, input) } } diff --git a/libs/tools/src/lib/api-crud/get-api-crud-substitutions.ts b/libs/tools/src/lib/api-crud/get-api-crud-substitutions.ts index 6815df8..517b97e 100644 --- a/libs/tools/src/lib/api-crud/get-api-crud-substitutions.ts +++ b/libs/tools/src/lib/api-crud/get-api-crud-substitutions.ts @@ -18,6 +18,9 @@ export function getApiCrudSubstitutions(options: NormalizedApiCrudSchema) { model, modelFileName: model.fileName, modelPropertyNamePlural: names(pluralize.plural(options.model)).propertyName, + owner: options.modelOwner ? names(options.modelOwner) : undefined, + ownerId: options.modelOwnerId, + ownerPropertyId: options.modelOwnerId?.replace('Id', ''), parent: options.modelParent ? names(options.modelParent) : undefined, parentId: options.modelParentId, parentPropertyId: options.modelParentId?.replace('Id', ''), diff --git a/libs/tools/src/lib/api-crud/normalize-api-crud-schema.ts b/libs/tools/src/lib/api-crud/normalize-api-crud-schema.ts index 0ee8838..91541e3 100644 --- a/libs/tools/src/lib/api-crud/normalize-api-crud-schema.ts +++ b/libs/tools/src/lib/api-crud/normalize-api-crud-schema.ts @@ -6,6 +6,8 @@ import { NormalizedApiCrudSchema } from './normalized-api-crud.schema' export function normalizeApiCrudSchema(tree: Tree, schema: ApiCrudGeneratorSchema): NormalizedApiCrudSchema { const npmScope = getNpmScope(tree) + const modelOwnerId = schema.modelOwnerId ?? undefined + const modelOwnerProperty = modelOwnerId?.replace('Id', '') const modelParent = schema.modelParent ?? undefined const modelParentId = schema.modelParentId ?? undefined const modelParentProperty = modelParentId?.replace('Id', '') @@ -16,9 +18,14 @@ export function normalizeApiCrudSchema(tree: Tree, schema: ApiCrudGeneratorSchem actor: schema.actor, label: schema.label ?? 'name', model: schema.model, + modelOwner: schema.modelOwnerId ? 'User' : undefined, + modelOwnerId, + modelOwnerProperty, modelParent, modelParentId, npmScope, - fields: fields.filter((f) => ![modelParentId, modelParentProperty].includes(f.name)), + fields: fields.filter( + (f) => ![modelOwnerId, modelOwnerProperty, modelParentId, modelParentProperty].includes(f.name), + ), } } diff --git a/libs/tools/src/lib/api-crud/normalized-api-crud.schema.d.ts b/libs/tools/src/lib/api-crud/normalized-api-crud.schema.ts similarity index 66% rename from libs/tools/src/lib/api-crud/normalized-api-crud.schema.d.ts rename to libs/tools/src/lib/api-crud/normalized-api-crud.schema.ts index 6f77aed..4f13a9c 100644 --- a/libs/tools/src/lib/api-crud/normalized-api-crud.schema.d.ts +++ b/libs/tools/src/lib/api-crud/normalized-api-crud.schema.ts @@ -1,7 +1,10 @@ import { ApiCrudGeneratorSchema } from '../../generators/api-crud/api-crud-schema' +import { PrismaModelField } from '../prisma/get-prisma-models' export interface NormalizedApiCrudSchema extends ApiCrudGeneratorSchema { label: string npmScope: string fields?: PrismaModelField[] + modelOwner: string + modelOwnerProperty: string } diff --git a/libs/tools/src/lib/api/get-api-substitutions.ts b/libs/tools/src/lib/api/get-api-substitutions.ts index 3363ad7..517a4ed 100644 --- a/libs/tools/src/lib/api/get-api-substitutions.ts +++ b/libs/tools/src/lib/api/get-api-substitutions.ts @@ -12,6 +12,9 @@ export function getApiSubstitutions(options: NormalizedApiFeatureSchema) { appFileName: app.fileName, modelFileName: model.fileName, modelPropertyNamePlural: plural.propertyName, + owner: options.modelOwner ? names(options.modelOwner) : undefined, + ownerId: options.modelOwnerId, + ownerPropertyId: options.modelOwnerId?.replace('Id', ''), parent: options.modelParent ? names(options.modelParent) : undefined, parentId: options.modelParentId, parentPropertyId: options.modelParentId?.replace('Id', ''), diff --git a/libs/tools/src/lib/api/normalize-api-feature-schema.ts b/libs/tools/src/lib/api/normalize-api-feature-schema.ts index 01d594c..4acbb8a 100644 --- a/libs/tools/src/lib/api/normalize-api-feature-schema.ts +++ b/libs/tools/src/lib/api/normalize-api-feature-schema.ts @@ -12,6 +12,8 @@ export function normalizeApiFeatureSchema(tree: Tree, schema: ApiFeatureGenerato label: schema.label ?? 'name', crud: schema.crud?.length ? schema.crud.split(',') : [], model, + modelOwner: schema.modelOwnerId ? 'User' : undefined, + modelOwnerId: schema.modelOwnerId ?? undefined, modelParent: schema.modelParent ?? undefined, modelParentId: schema.modelParentId ?? undefined, npmScope, diff --git a/libs/tools/src/lib/api/normalized-api-feature-schema.ts b/libs/tools/src/lib/api/normalized-api-feature-schema.ts index c7a9c2d..5f902f9 100644 --- a/libs/tools/src/lib/api/normalized-api-feature-schema.ts +++ b/libs/tools/src/lib/api/normalized-api-feature-schema.ts @@ -5,6 +5,7 @@ export interface NormalizedApiFeatureSchema extends OmitFindOne<%= model.className %> } from '@<%= npmScope %>/<%= app.fileName %>-<%= model.fileName %>-data-access' import { <%= model.className %>UiInfo } from '@<%= npmScope %>/<%= app.fileName %>-<%= model.fileName %>-ui' -import { UiCard, UiDebug, UiError, UiLoader } from '@pubkey-ui/core' +import { UiCard, UiError, UiLoader } from '@pubkey-ui/core' export function <%= actor.className %><%= model.className %>DetailInfoTab({ <%= model.propertyName %>Id }: { <%= model.propertyName %>Id: string }) { const { item, query } = use<%= actor.className %>FindOne<%= model.className %>({ <%= model.propertyName %>Id }) diff --git a/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-detail.feature.tsx.template b/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-detail.feature.tsx.template index e1a7051..cc01a19 100644 --- a/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-detail.feature.tsx.template +++ b/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-detail.feature.tsx.template @@ -1,6 +1,7 @@ import { Group } from '@mantine/core' import { UiBack, UiDebugModal, UiError, UiLoader, UiPage, UiTabRoutes } from '@pubkey-ui/core' import { use<%= actor.className %>FindOne<%= model.className %> } from '@<%= npmScope %>/<%= app.fileName %>-<%= model.fileName %>-data-access' +import { <%= model.className %>UiItem } from '@<%= npmScope %>/<%= app.fileName %>-<%= model.fileName %>-ui' import { useParams } from 'react-router-dom' import { <%= actor.className %><%= model.className %>DetailInfoTab } from './<%= actor.propertyName %>-<%= model.fileName %>-detail-info.tab' import { <%= actor.className %><%= model.className %>DetailSettingsTab } from './<%= actor.propertyName %>-<%= model.fileName %>-detail-settings.tab' @@ -18,7 +19,7 @@ export function <%= actor.className %><%= model.className %>DetailFeature() { return ( {item.<%= label.propertyName %>} } + title={<<%= model.className %>UiItem <%= model.propertyName %>={item} />} leftAction={} rightAction={ diff --git a/libs/tools/src/lib/web-crud/files/ui/lib/__modelFileName__-ui-item.tsx.template b/libs/tools/src/lib/web-crud/files/ui/lib/__modelFileName__-ui-item.tsx.template index be3774e..b1825b7 100644 --- a/libs/tools/src/lib/web-crud/files/ui/lib/__modelFileName__-ui-item.tsx.template +++ b/libs/tools/src/lib/web-crud/files/ui/lib/__modelFileName__-ui-item.tsx.template @@ -23,7 +23,7 @@ export function <%= model.className %>UiItem({ <<%= model.className %>UiAvatar <%= model.propertyName %>={<%= model.propertyName %>} {...avatarProps} /> - + {<%= model.propertyName %>?.<%= label.propertyName %>} From 352c0ad4ef13a335a00c3c34d2ff4a86cb56da0f Mon Sep 17 00:00:00 2001 From: Bram Borggreve Date: Fri, 15 Mar 2024 05:45:20 +0000 Subject: [PATCH 05/12] feat: add support for ownerId to web generator --- .../api-crud-generator.spec.ts.snap | 22 +- .../api-crud/api-crud-generator.spec.ts | 6 +- .../web-crud-generator.spec.ts.snap | 4886 +++++++++++++++++ .../web-crud/web-crud-generator.spec.ts | 45 +- .../generators/web-crud/web-crud-schema.d.ts | 12 + .../generators/web-crud/web-crud-schema.json | 12 + .../web-feature-generator.spec.ts.snap | 8 +- .../web-feature/web-feature-schema.d.ts | 12 + .../web-feature/web-feature-schema.json | 12 + ...__-find-many-__modelFileName__.ts.template | 6 +- ...odelFileName__-create.feature.tsx.template | 4 +- ..._modelFileName__-list.feature.tsx.template | 19 +- ...me__-__modelFileName__.routes.tsx.template | 6 +- ...odelFileName__-ui-create-form.tsx.template | 6 + .../web-crud/get-web-crud-substitutions.ts | 6 + .../lib/web-crud/normalize-web-crud-schema.ts | 14 +- .../normalized-web-crud-generator-schema.ts | 2 + libs/tools/src/lib/web/create-mock-web-app.ts | 7 +- .../lib/web/normalize-web-feature-schema.ts | 4 + .../lib/web/normalized-web-feature-schema.ts | 5 +- 20 files changed, 5068 insertions(+), 26 deletions(-) create mode 100644 libs/tools/src/generators/web-crud/__snapshots__/web-crud-generator.spec.ts.snap diff --git a/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap b/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap index d62aadd..e4f2fb3 100644 --- a/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap +++ b/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap @@ -112,6 +112,8 @@ exports[`api-crud generator should create crud with modelOwnerId 1`] = ` "location!: string;", "@Field({ nullable: true })", "phone?: string;", + "@Field()", + "ownerId!: string;", "}", ], "isBinary": false, @@ -123,6 +125,8 @@ exports[`api-crud generator should create crud with modelOwnerId 1`] = ` "import { PagingInput } from '@proj/test-core-data-access';", "@InputType()", "export class AdminFindManyCompanyInput extends PagingInput() {", + "@Field()", + "ownerId!: string;", "@Field({ nullable: true })", "search?: string;", "}", @@ -193,7 +197,9 @@ exports[`api-crud generator should create crud with modelOwnerId 1`] = ` "export function getCompanyWhereAdminInput(", "input: AdminFindManyCompanyInput", "): Prisma.CompanyWhereInput {", - "const where: Prisma.CompanyWhereInput = {};", + "const where: Prisma.CompanyWhereInput = {", + "ownerId: input.ownerId,", + "};", "if (input.search) {", "where.OR = [", "{ id: { contains: input.search, mode: 'insensitive' } },", @@ -222,7 +228,7 @@ exports[`api-crud generator should create crud with modelOwnerId 1`] = ` "export class TestCompanyDataAdminService {", "constructor(private readonly data: TestCompanyDataService) {}", "async createCompany(input: AdminCreateCompanyInput) {", - "return this.data.create({ ...input, ownerId });", + "return this.data.create(input);", "}", "async deleteCompany(companyId: string) {", "return this.data.delete(companyId);", @@ -1411,6 +1417,8 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "location!: string;", "@Field({ nullable: true })", "phone?: string;", + "@Field()", + "ownerId!: string;", "}", ], "isBinary": false, @@ -1422,6 +1430,8 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "import { PagingInput } from '@proj/test-core-data-access';", "@InputType()", "export class AdminFindManyCompanyInput extends PagingInput() {", + "@Field()", + "ownerId!: string;", "@Field({ nullable: true })", "search?: string;", "}", @@ -1537,7 +1547,9 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "export function getCompanyWhereAdminInput(", "input: AdminFindManyCompanyInput", "): Prisma.CompanyWhereInput {", - "const where: Prisma.CompanyWhereInput = {};", + "const where: Prisma.CompanyWhereInput = {", + "ownerId: input.ownerId,", + "};", "if (input.search) {", "where.OR = [", "{ id: { contains: input.search, mode: 'insensitive' } },", @@ -1589,7 +1601,7 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "export class TestCompanyDataAdminService {", "constructor(private readonly data: TestCompanyDataService) {}", "async createCompany(input: AdminCreateCompanyInput) {", - "return this.data.create({ ...input, ownerId });", + "return this.data.create(input);", "}", "async deleteCompany(companyId: string) {", "return this.data.delete(companyId);", @@ -2821,7 +2833,7 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u } `; -exports[`api-crud generator should create crud with modelParentid 1`] = ` +exports[`api-crud generator should create crud with modelParentId 1`] = ` { "company": { "children": { diff --git a/libs/tools/src/generators/api-crud/api-crud-generator.spec.ts b/libs/tools/src/generators/api-crud/api-crud-generator.spec.ts index c0d8354..77376a3 100644 --- a/libs/tools/src/generators/api-crud/api-crud-generator.spec.ts +++ b/libs/tools/src/generators/api-crud/api-crud-generator.spec.ts @@ -2,8 +2,8 @@ import { readProjectConfiguration, Tree } from '@nx/devkit' import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing' import { createMockApiApp } from '../../lib/api/create-mock-api-app' import { getRecursiveFileContents } from '../../lib/utils/get-recursive-file-contents' -import apiFeatureGenerator from '../api-feature/api-feature-generator' -import apiCrudGenerator from './api-crud-generator' +import { apiFeatureGenerator } from '../api-feature/api-feature-generator' +import { apiCrudGenerator } from './api-crud-generator' import { ApiCrudGeneratorSchema } from './api-crud-schema' describe('api-crud generator', () => { @@ -28,7 +28,7 @@ describe('api-crud generator', () => { expect(contents).toMatchSnapshot() }) - it('should create crud with modelParentid', async () => { + it('should create crud with modelParentId', async () => { await apiCrudGenerator(tree, { ...options, modelParent: 'User', modelParentId: 'ownerId' }) const config = readProjectConfiguration(tree, 'test') expect(config).toBeDefined() diff --git a/libs/tools/src/generators/web-crud/__snapshots__/web-crud-generator.spec.ts.snap b/libs/tools/src/generators/web-crud/__snapshots__/web-crud-generator.spec.ts.snap new file mode 100644 index 0000000..b011fd0 --- /dev/null +++ b/libs/tools/src/generators/web-crud/__snapshots__/web-crud-generator.spec.ts.snap @@ -0,0 +1,4886 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`web-crud generator should create crud with modelOwnerId 1`] = ` +{ + "company": { + "children": { + "data-access": { + "children": { + ".babelrc": { + "content": [ + "{", + ""presets": [", + "[", + ""@nx/react/babel",", + "{", + ""runtime": "automatic",", + ""useBuiltIns": "usage"", + "}", + "]", + "],", + ""plugins": []", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/.babelrc", + }, + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["plugin:@nx/react", "../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-company-data-access", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-company-data-access\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/company/data-access/README.md", + }, + "project.json": { + "content": [ + "{", + ""name": "test-company-data-access",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/company/data-access/src",", + ""projectType": "library",", + ""tags": ["app:test", "type:data-access"],", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "}", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [ + "export * from './lib/use-manager-find-many-company';", + "export * from './lib/use-manager-find-one-company';", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/index.ts", + }, + "lib": { + "children": { + "use-manager-find-many-company.ts": { + "content": [ + "import {", + "ManagerCreateCompanyInput,", + "ManagerFindManyCompanyInput,", + "} from '@proj/sdk';", + "import { useSdk } from '@proj/test-core-data-access';", + "import { toastError, toastSuccess } from '@pubkey-ui/core';", + "import { useQuery } from '@tanstack/react-query';", + "import { useState } from 'react';", + "export function useManagerFindManyCompany(", + "props: Partial = {}", + ") {", + "const sdk = useSdk();", + "const [limit, setLimit] = useState(props?.limit ?? 10);", + "const [page, setPage] = useState(props?.page ?? 1);", + "const [search, setSearch] = useState(props?.search ?? '');", + "const input: ManagerFindManyCompanyInput = { page, limit, search };", + "const query = useQuery({", + "queryKey: ['manager', 'find-many-company', input],", + "queryFn: () =>", + "sdk.managerFindManyCompany({ input }).then((res) => res.data),", + "});", + "const total = query.data?.paging?.meta?.totalCount ?? 0;", + "const items = query.data?.paging.data ?? [];", + "return {", + "items,", + "query,", + "pagination: {", + "page,", + "setPage,", + "limit,", + "setLimit,", + "total,", + "},", + "setSearch,", + "createCompany: (input: ManagerCreateCompanyInput) =>", + "sdk", + ".managerCreateCompany({ input })", + ".then((res) => res.data)", + ".then((res) => {", + "if (res.created) {", + "toastSuccess(\`Company created\`);", + "} else {", + "toastError(\`Company not created\`);", + "}", + "return res.created;", + "})", + ".catch((err) => {", + "toastError(err.message);", + "return undefined;", + "}),", + "deleteCompany: (companyId: string) =>", + "sdk.managerDeleteCompany({ companyId }).then(() => {", + "toastSuccess('Company deleted');", + "return query.refetch();", + "}),", + "};", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/use-manager-find-many-company.ts", + }, + "use-manager-find-one-company.ts": { + "content": [ + "import { ManagerUpdateCompanyInput } from '@proj/sdk';", + "import { useSdk } from '@proj/test-core-data-access';", + "import { toastError, toastSuccess } from '@pubkey-ui/core';", + "import { useQuery } from '@tanstack/react-query';", + "export function useManagerFindOneCompany({ companyId }: { companyId: string }) {", + "const sdk = useSdk();", + "const query = useQuery({", + "queryKey: ['manager', 'find-one-company', companyId],", + "queryFn: () =>", + "sdk.managerFindOneCompany({ companyId }).then((res) => res.data),", + "retry: 0,", + "});", + "const item = query.data?.item ?? undefined;", + "return {", + "item,", + "query,", + "updateCompany: async (input: ManagerUpdateCompanyInput) =>", + "sdk", + ".managerUpdateCompany({ companyId, input })", + ".then((res) => res.data)", + ".then(async (res) => {", + "if (res) {", + "toastSuccess('Company updated');", + "await query.refetch();", + "return true;", + "}", + "toastError('Company not updated');", + "return false;", + "})", + ".catch((err) => {", + "toastError(err.message);", + "return false;", + "}),", + "};", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/use-manager-find-one-company.ts", + }, + }, + "path": "libs/test/company/data-access/src/lib", + }, + }, + "path": "libs/test/company/data-access/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""compilerOptions": {", + ""jsx": "react-jsx",", + ""allowJs": false,", + ""esModuleInterop": false,", + ""allowSyntheticDefaultImports": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "}", + "],", + ""extends": "../../../../tsconfig.base.json"", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""types": [", + ""node",", + ""@nx/react/typings/cssmodule.d.ts",", + ""@nx/react/typings/image.d.ts"", + "]", + "},", + ""exclude": [", + ""jest.config.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.tsx",", + ""src/**/*.test.tsx",", + ""src/**/*.spec.js",", + ""src/**/*.test.js",", + ""src/**/*.spec.jsx",", + ""src/**/*.test.jsx"", + "],", + ""include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/tsconfig.lib.json", + }, + }, + "path": "libs/test/company/data-access", + }, + "feature": { + "children": { + ".babelrc": { + "content": [ + "{", + ""presets": [", + "[", + ""@nx/react/babel",", + "{", + ""runtime": "automatic",", + ""useBuiltIns": "usage"", + "}", + "]", + "],", + ""plugins": []", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/.babelrc", + }, + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["plugin:@nx/react", "../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-company-feature", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-company-feature\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/company/feature/README.md", + }, + "project.json": { + "content": [ + "{", + ""name": "test-company-feature",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/company/feature/src",", + ""projectType": "library",", + ""tags": ["app:test", "type:feature"],", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "}", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [ + "import { lazy } from 'react';", + "export const ManagerCompanyFeature = lazy(", + "() => import('./lib/manager-company.routes')", + ");", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/index.ts", + }, + "lib": { + "children": { + "manager-company-create.feature.tsx": { + "content": [ + "import { ManagerCreateCompanyInput } from '@proj/sdk';", + "import { useManagerFindManyCompany } from '@proj/test-company-data-access';", + "import { ManagerCompanyUiCreateForm } from '@proj/test-company-ui';", + "import { toastError, UiBack, UiCard, UiPage } from '@pubkey-ui/core';", + "import { useNavigate } from 'react-router-dom';", + "export function ManagerCompanyCreateFeature() {", + "const navigate = useNavigate();", + "const { createCompany } = useManagerFindManyCompany();", + "async function submit(input: ManagerCreateCompanyInput) {", + "return createCompany(input)", + ".then((res) => {", + "if (res) {", + "navigate(\`../\${res?.id}\`);", + "}", + "})", + ".then(() => true)", + ".catch((err) => {", + "toastError(err.message);", + "return false;", + "});", + "}", + "return (", + "} title="Create Company">", + "", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/manager-company-create.feature.tsx", + }, + "manager-company-detail-info.tab.tsx": { + "content": [ + "import { useManagerFindOneCompany } from '@proj/test-company-data-access';", + "import { CompanyUiInfo } from '@proj/test-company-ui';", + "import { UiCard, UiError, UiLoader } from '@pubkey-ui/core';", + "export function ManagerCompanyDetailInfoTab({", + "companyId,", + "}: {", + "companyId: string;", + "}) {", + "const { item, query } = useManagerFindOneCompany({ companyId });", + "if (query.isLoading) {", + "return ;", + "}", + "if (!item) {", + "return ;", + "}", + "return (", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/manager-company-detail-info.tab.tsx", + }, + "manager-company-detail-settings.tab.tsx": { + "content": [ + "import { useManagerFindOneCompany } from '@proj/test-company-data-access';", + "import { ManagerCompanyUiUpdateForm } from '@proj/test-company-ui';", + "import { UiCard, UiError, UiLoader } from '@pubkey-ui/core';", + "export function ManagerCompanyDetailSettingsTab({", + "companyId,", + "}: {", + "companyId: string;", + "}) {", + "const { item, query, updateCompany } = useManagerFindOneCompany({", + "companyId,", + "});", + "if (query.isLoading) {", + "return ;", + "}", + "if (!item) {", + "return ;", + "}", + "return (", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/manager-company-detail-settings.tab.tsx", + }, + "manager-company-detail.feature.tsx": { + "content": [ + "import { Group } from '@mantine/core';", + "import {", + "UiBack,", + "UiDebugModal,", + "UiError,", + "UiLoader,", + "UiPage,", + "UiTabRoutes,", + "} from '@pubkey-ui/core';", + "import { useManagerFindOneCompany } from '@proj/test-company-data-access';", + "import { CompanyUiItem } from '@proj/test-company-ui';", + "import { useParams } from 'react-router-dom';", + "import { ManagerCompanyDetailInfoTab } from './manager-company-detail-info.tab';", + "import { ManagerCompanyDetailSettingsTab } from './manager-company-detail-settings.tab';", + "export function ManagerCompanyDetailFeature() {", + "const { companyId } = useParams<{ companyId: string }>() as {", + "companyId: string;", + "};", + "const { item, query } = useManagerFindOneCompany({ companyId });", + "if (query.isLoading) {", + "return ;", + "}", + "if (!item) {", + "return ;", + "}", + "return (", + "}", + "leftAction={}", + "rightAction={", + "", + "", + "", + "}", + ">", + ",", + "},", + "{", + "path: 'settings',", + "label: 'Settings',", + "element: ,", + "},", + "]}", + "/>", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/manager-company-detail.feature.tsx", + }, + "manager-company-list.feature.tsx": { + "content": [ + "import { Button, Group } from '@mantine/core';", + "import { UiPageLimit, UiSearchField } from '@proj/test-core-ui';", + "import { useManagerFindManyCompany } from '@proj/test-company-data-access';", + "import { CompanyUiGrid } from '@proj/test-company-ui';", + "import {", + "UiBack,", + "UiDebugModal,", + "UiInfo,", + "UiLoader,", + "UiPage,", + "} from '@pubkey-ui/core';", + "import { Link } from 'react-router-dom';", + "export function ManagerCompanyListFeature() {", + "const { deleteCompany, items, pagination, query, setSearch } =", + "useManagerFindManyCompany({", + "limit: 12,", + "});", + "return (", + "}", + "rightAction={", + "", + "", + "", + "", + "}", + ">", + "", + "", + "", + "{query.isLoading ? (", + "", + ") : items?.length ? (", + "", + ") : (", + "", + ")}", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/manager-company-list.feature.tsx", + }, + "manager-company.routes.tsx": { + "content": [ + "import { useRoutes } from 'react-router-dom';", + "import { ManagerCompanyDetailFeature } from './manager-company-detail.feature';", + "import { ManagerCompanyCreateFeature } from './manager-company-create.feature';", + "import { ManagerCompanyListFeature } from './manager-company-list.feature';", + "export default function ManagerCompanyRoutes() {", + "return useRoutes([", + "{ path: '', element: },", + "{", + "path: 'create',", + "element: ,", + "},", + "{ path: ':companyId/*', element: },", + "]);", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/manager-company.routes.tsx", + }, + }, + "path": "libs/test/company/feature/src/lib", + }, + }, + "path": "libs/test/company/feature/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""compilerOptions": {", + ""jsx": "react-jsx",", + ""allowJs": false,", + ""esModuleInterop": false,", + ""allowSyntheticDefaultImports": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "}", + "],", + ""extends": "../../../../tsconfig.base.json"", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""types": [", + ""node",", + ""@nx/react/typings/cssmodule.d.ts",", + ""@nx/react/typings/image.d.ts"", + "]", + "},", + ""exclude": [", + ""jest.config.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.tsx",", + ""src/**/*.test.tsx",", + ""src/**/*.spec.js",", + ""src/**/*.test.js",", + ""src/**/*.spec.jsx",", + ""src/**/*.test.jsx"", + "],", + ""include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/tsconfig.lib.json", + }, + }, + "path": "libs/test/company/feature", + }, + "ui": { + "children": { + ".babelrc": { + "content": [ + "{", + ""presets": [", + "[", + ""@nx/react/babel",", + "{", + ""runtime": "automatic",", + ""useBuiltIns": "usage"", + "}", + "]", + "],", + ""plugins": []", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/.babelrc", + }, + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["plugin:@nx/react", "../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-company-ui", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-company-ui\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/company/ui/README.md", + }, + "project.json": { + "content": [ + "{", + ""name": "test-company-ui",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/company/ui/src",", + ""projectType": "library",", + ""tags": ["app:test", "type:ui"],", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "}", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [ + "export * from './lib/manager-company-ui-create-form';", + "export * from './lib/manager-company-ui-table';", + "export * from './lib/manager-company-ui-update-form';", + "export * from './lib/company-ui-avatar';", + "export * from './lib/company-ui-grid';", + "export * from './lib/company-ui-grid-item';", + "export * from './lib/company-ui-info';", + "export * from './lib/company-ui-item';", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/index.ts", + }, + "lib": { + "children": { + "company-ui-avatar.tsx": { + "content": [ + "import { Company } from '@proj/sdk';", + "import { UiAvatar, UiAvatarProps } from '@pubkey-ui/core';", + "export type CompanyUiAvatarProps = UiAvatarProps & {", + "company?: Company;", + "};", + "export function CompanyUiAvatar({ company, ...props }: CompanyUiAvatarProps) {", + "return ;", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/company-ui-avatar.tsx", + }, + "company-ui-grid-item.tsx": { + "content": [ + "import { Paper } from '@mantine/core';", + "import { Company } from '@proj/sdk';", + "import { UiDebugModal, UiGroup } from '@pubkey-ui/core';", + "import { CompanyUiItem } from './company-ui-item';", + "export function CompanyUiGridItem({", + "company,", + "to,", + "}: {", + "company: Company;", + "to?: string;", + "}) {", + "return (", + "", + "", + "", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/company-ui-grid-item.tsx", + }, + "company-ui-grid.tsx": { + "content": [ + "import { Group, Pagination, SimpleGrid } from '@mantine/core';", + "import { Company } from '@proj/sdk';", + "import { gridLimits, UiPageLimit } from '@proj/test-core-ui';", + "import { UiDebugModal, UiGroup, UiStack } from '@pubkey-ui/core';", + "import { DataTableProps } from 'mantine-datatable';", + "import { CompanyUiGridItem } from './company-ui-grid-item';", + "export function CompanyUiGrid({", + "companies = [],", + "onPageChange,", + "page,", + "totalRecords,", + "limit,", + "setLimit,", + "setPage,", + "}: {", + "companies: Company[];", + "page: DataTableProps['page'];", + "totalRecords: number;", + "onPageChange: (page: number) => void;", + "limit: number;", + "setLimit: (limit: number) => void;", + "setPage: (page: number) => void;", + "}) {", + "const totalPages = totalRecords / limit + 1;", + "return (", + "", + "", + "{companies.map((company) => (", + "", + "))}", + "", + "", + "", + "", + "", + "", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/company-ui-grid.tsx", + }, + "company-ui-info.tsx": { + "content": [ + "import { Company } from '@proj/sdk';", + "import { UiInfoItems, UiInfoTable, UiTime } from '@pubkey-ui/core';", + "export function CompanyUiInfo({ company }: { company?: Company }) {", + "if (!company) return null;", + "const items: UiInfoItems = [", + "['name', company.name],", + "[", + "'Created At',", + ",", + "],", + "[", + "'Updated At',", + ",", + "],", + "];", + "return ;", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/company-ui-info.tsx", + }, + "company-ui-item.tsx": { + "content": [ + "import {", + "AvatarProps,", + "Group,", + "type GroupProps,", + "Stack,", + "Text,", + "} from '@mantine/core';", + "import { Company } from '@proj/sdk';", + "import { UiAnchor, type UiAnchorProps } from '@pubkey-ui/core';", + "import { CompanyUiAvatar } from './company-ui-avatar';", + "export function CompanyUiItem({", + "anchorProps,", + "avatarProps,", + "groupProps,", + "company,", + "to,", + "}: {", + "anchorProps?: UiAnchorProps;", + "avatarProps?: Omit;", + "groupProps?: GroupProps;", + "company?: Company;", + "to?: string | null;", + "}) {", + "if (!company) return null;", + "return (", + "", + "", + "", + "", + "", + "{company?.name}", + "", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/company-ui-item.tsx", + }, + "manager-company-ui-create-form.tsx": { + "content": [ + "import { Button, Group } from '@mantine/core';", + "import { ManagerCreateCompanyInput } from '@proj/sdk';", + "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", + "import { ReactNode } from 'react';", + "export function ManagerCompanyUiCreateForm({", + "submit,", + "}: {", + "submit: (res: ManagerCreateCompanyInput) => Promise;", + "}) {", + "const model: ManagerCreateCompanyInput = {", + "name: '',", + "location: '',", + "phone: '',", + "};", + "const fields: UiFormField[] = [", + "formFieldText('name', { label: 'name', required: true }),", + "formFieldText('location', { label: 'location', required: true }),", + "formFieldText('phone', { label: 'phone', required: true }),", + "];", + "return (", + " submit(res as ManagerCreateCompanyInput)}", + ">", + "", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/manager-company-ui-create-form.tsx", + }, + "manager-company-ui-table.tsx": { + "content": [ + "import { ActionIcon, Anchor, Group, ScrollArea } from '@mantine/core';", + "import { Company } from '@proj/sdk';", + "import { IconPencil, IconTrash } from '@tabler/icons-react';", + "import { DataTable, DataTableProps } from 'mantine-datatable';", + "import { Link } from 'react-router-dom';", + "export function ManagerCompanyUiTable({", + "deleteCompany,", + "companies = [],", + "onPageChange,", + "page,", + "recordsPerPage,", + "totalRecords,", + "}: {", + "deleteCompany: (company: Company) => void;", + "companies: Company[];", + "page: DataTableProps['page'];", + "totalRecords: DataTableProps['totalRecords'];", + "recordsPerPage: DataTableProps['recordsPerPage'];", + "onPageChange: (page: number) => void;", + "}) {", + "return (", + "", + " (", + "", + "{item.name}", + "", + "),", + "},", + "{", + "accessor: 'actions',", + "title: 'Actions',", + "textAlign: 'right',", + "render: (item) => (", + "", + "", + "", + "", + " deleteCompany(item)}", + ">", + "", + "", + "", + "),", + "},", + "]}", + "records={companies}", + "/>", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/manager-company-ui-table.tsx", + }, + "manager-company-ui-update-form.tsx": { + "content": [ + "import { Button, Group } from '@mantine/core';", + "import { ManagerUpdateCompanyInput, Company } from '@proj/sdk';", + "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", + "export function ManagerCompanyUiUpdateForm({", + "submit,", + "company,", + "}: {", + "submit: (res: ManagerUpdateCompanyInput) => Promise;", + "company: Company;", + "}) {", + "const model: ManagerUpdateCompanyInput = {", + "name: company.name ?? '',", + "location: company.location ?? '',", + "phone: company.phone ?? '',", + "};", + "const fields: UiFormField[] = [", + "formFieldText('name', { label: 'name' }),", + "formFieldText('location', { label: 'location' }),", + "formFieldText('phone', { label: 'phone' }),", + "];", + "return (", + " submit(res as ManagerUpdateCompanyInput)}", + ">", + "", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/manager-company-ui-update-form.tsx", + }, + }, + "path": "libs/test/company/ui/src/lib", + }, + }, + "path": "libs/test/company/ui/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""compilerOptions": {", + ""jsx": "react-jsx",", + ""allowJs": false,", + ""esModuleInterop": false,", + ""allowSyntheticDefaultImports": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "}", + "],", + ""extends": "../../../../tsconfig.base.json"", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""types": [", + ""node",", + ""@nx/react/typings/cssmodule.d.ts",", + ""@nx/react/typings/image.d.ts"", + "]", + "},", + ""exclude": [", + ""jest.config.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.tsx",", + ""src/**/*.test.tsx",", + ""src/**/*.spec.js",", + ""src/**/*.test.js",", + ""src/**/*.spec.jsx",", + ""src/**/*.test.jsx"", + "],", + ""include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/tsconfig.lib.json", + }, + }, + "path": "libs/test/company/ui", + }, + }, + "path": "libs/test/company", + }, + "core": { + "children": { + "data-access": { + "children": { + ".babelrc": { + "content": [ + "{", + ""presets": [", + "[", + ""@nx/react/babel",", + "{", + ""runtime": "automatic",", + ""useBuiltIns": "usage"", + "}", + "]", + "],", + ""plugins": []", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/.babelrc", + }, + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["plugin:@nx/react", "../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-core-data-access", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-core-data-access\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/core/data-access/README.md", + }, + "project.json": { + "content": [ + "{", + ""name": "test-core-data-access",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/core/data-access/src",", + ""projectType": "library",", + ""tags": [],", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "}", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [], + "isBinary": false, + "path": "libs/test/core/data-access/src/index.ts", + }, + }, + "path": "libs/test/core/data-access/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""compilerOptions": {", + ""jsx": "react-jsx",", + ""allowJs": false,", + ""esModuleInterop": false,", + ""allowSyntheticDefaultImports": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "}", + "],", + ""extends": "../../../../tsconfig.base.json"", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""types": [", + ""node",", + ""@nx/react/typings/cssmodule.d.ts",", + ""@nx/react/typings/image.d.ts"", + "]", + "},", + ""exclude": [", + ""jest.config.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.tsx",", + ""src/**/*.test.tsx",", + ""src/**/*.spec.js",", + ""src/**/*.test.js",", + ""src/**/*.spec.jsx",", + ""src/**/*.test.jsx"", + "],", + ""include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/tsconfig.lib.json", + }, + }, + "path": "libs/test/core/data-access", + }, + "feature": { + "children": { + ".babelrc": { + "content": [ + "{", + ""presets": [", + "[", + ""@nx/react/babel",", + "{", + ""runtime": "automatic",", + ""useBuiltIns": "usage"", + "}", + "]", + "],", + ""plugins": []", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/.babelrc", + }, + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["plugin:@nx/react", "../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-core-feature", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-core-feature\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/core/feature/README.md", + }, + "project.json": { + "content": [ + "{", + ""name": "test-core-feature",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/core/feature/src",", + ""projectType": "library",", + ""tags": [],", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "}", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [], + "isBinary": false, + "path": "libs/test/core/feature/src/index.ts", + }, + "lib": { + "children": { + "test-core-feature.tsx": { + "content": [ + "/* eslint-disable-next-line */", + "export interface TestCoreFeatureProps {}", + "export function TestCoreFeature(props: TestCoreFeatureProps) {", + "return (", + "
", + "

Welcome to TestCoreFeature!

", + "
", + ");", + "}", + "export default TestCoreFeature;", + ], + "isBinary": false, + "path": "libs/test/core/feature/src/lib/test-core-feature.tsx", + }, + "test-core-routes-admin.tsx": { + "content": [ + "/* eslint-disable-next-line */", + "export interface TestCoreRoutesAdminProps {}", + "export function TestCoreRoutesAdmin(props: TestCoreRoutesAdminProps) {", + "return (", + "
", + "

Welcome to TestCoreRoutesAdmin!

", + "
", + ");", + "}", + "export default TestCoreRoutesAdmin;", + ], + "isBinary": false, + "path": "libs/test/core/feature/src/lib/test-core-routes-admin.tsx", + }, + "test-core-routes-manager.tsx": { + "content": [ + "import { IconBuilding } from '@tabler/icons-react';", + "import { ManagerCompanyFeature } from '@proj/test-company-feature';", + "/* eslint-disable-next-line */", + "export interface TestCoreRoutesManagerProps {}", + "export function TestCoreRoutesManager(props: TestCoreRoutesManagerProps) {", + "return (", + "
", + "

Welcome to TestCoreRoutesManager!

", + "
", + ");", + "}", + "export default TestCoreRoutesManager;", + ], + "isBinary": false, + "path": "libs/test/core/feature/src/lib/test-core-routes-manager.tsx", + }, + "test-core-routes-user.tsx": { + "content": [ + "/* eslint-disable-next-line */", + "export interface TestCoreRoutesUserProps {}", + "export function TestCoreRoutesUser(props: TestCoreRoutesUserProps) {", + "return (", + "
", + "

Welcome to TestCoreRoutesUser!

", + "
", + ");", + "}", + "export default TestCoreRoutesUser;", + ], + "isBinary": false, + "path": "libs/test/core/feature/src/lib/test-core-routes-user.tsx", + }, + "test-core-routes.tsx": { + "content": [ + "/* eslint-disable-next-line */", + "export interface TestCoreRoutesProps {}", + "export function TestCoreRoutes(props: TestCoreRoutesProps) {", + "return (", + "
", + "

Welcome to TestCoreRoutes!

", + "
", + ");", + "}", + "export default TestCoreRoutes;", + ], + "isBinary": false, + "path": "libs/test/core/feature/src/lib/test-core-routes.tsx", + }, + }, + "path": "libs/test/core/feature/src/lib", + }, + }, + "path": "libs/test/core/feature/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""compilerOptions": {", + ""jsx": "react-jsx",", + ""allowJs": false,", + ""esModuleInterop": false,", + ""allowSyntheticDefaultImports": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "}", + "],", + ""extends": "../../../../tsconfig.base.json"", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""types": [", + ""node",", + ""@nx/react/typings/cssmodule.d.ts",", + ""@nx/react/typings/image.d.ts"", + "]", + "},", + ""exclude": [", + ""jest.config.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.tsx",", + ""src/**/*.test.tsx",", + ""src/**/*.spec.js",", + ""src/**/*.test.js",", + ""src/**/*.spec.jsx",", + ""src/**/*.test.jsx"", + "],", + ""include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/tsconfig.lib.json", + }, + }, + "path": "libs/test/core/feature", + }, + }, + "path": "libs/test/core", + }, +} +`; + +exports[`web-crud generator should create crud with modelOwnerId for admin and user 1`] = ` +{ + "company": { + "children": { + "data-access": { + "children": { + ".babelrc": { + "content": [ + "{", + ""presets": [", + "[", + ""@nx/react/babel",", + "{", + ""runtime": "automatic",", + ""useBuiltIns": "usage"", + "}", + "]", + "],", + ""plugins": []", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/.babelrc", + }, + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["plugin:@nx/react", "../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-company-data-access", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-company-data-access\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/company/data-access/README.md", + }, + "project.json": { + "content": [ + "{", + ""name": "test-company-data-access",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/company/data-access/src",", + ""projectType": "library",", + ""tags": ["app:test", "type:data-access"],", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "}", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [ + "export * from './lib/use-user-find-many-company';", + "export * from './lib/use-user-find-one-company';", + "export * from './lib/use-admin-find-many-company';", + "export * from './lib/use-admin-find-one-company';", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/index.ts", + }, + "lib": { + "children": { + "use-admin-find-many-company.ts": { + "content": [ + "import { AdminCreateCompanyInput, AdminFindManyCompanyInput } from '@proj/sdk';", + "import { useSdk } from '@proj/test-core-data-access';", + "import { toastError, toastSuccess } from '@pubkey-ui/core';", + "import { useQuery } from '@tanstack/react-query';", + "import { useState } from 'react';", + "export function useAdminFindManyCompany(", + "props: Partial & { ownerId: string }", + ") {", + "const sdk = useSdk();", + "const [limit, setLimit] = useState(props?.limit ?? 10);", + "const [page, setPage] = useState(props?.page ?? 1);", + "const [search, setSearch] = useState(props?.search ?? '');", + "const input: AdminFindManyCompanyInput = {", + "page,", + "limit,", + "searchownerId: props.ownerId,", + "};", + "const query = useQuery({", + "queryKey: ['admin', 'find-many-company', input],", + "queryFn: () => sdk.adminFindManyCompany({ input }).then((res) => res.data),", + "});", + "const total = query.data?.paging?.meta?.totalCount ?? 0;", + "const items = query.data?.paging.data ?? [];", + "return {", + "items,", + "query,", + "pagination: {", + "page,", + "setPage,", + "limit,", + "setLimit,", + "total,", + "},", + "setSearch,", + "createCompany: (input: AdminCreateCompanyInput) =>", + "sdk", + ".adminCreateCompany({ input: { ...input, ownerId: props.ownerId } })", + ".then((res) => res.data)", + ".then((res) => {", + "if (res.created) {", + "toastSuccess(\`Company created\`);", + "} else {", + "toastError(\`Company not created\`);", + "}", + "return res.created;", + "})", + ".catch((err) => {", + "toastError(err.message);", + "return undefined;", + "}),", + "deleteCompany: (companyId: string) =>", + "sdk.adminDeleteCompany({ companyId }).then(() => {", + "toastSuccess('Company deleted');", + "return query.refetch();", + "}),", + "};", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/use-admin-find-many-company.ts", + }, + "use-admin-find-one-company.ts": { + "content": [ + "import { AdminUpdateCompanyInput } from '@proj/sdk';", + "import { useSdk } from '@proj/test-core-data-access';", + "import { toastError, toastSuccess } from '@pubkey-ui/core';", + "import { useQuery } from '@tanstack/react-query';", + "export function useAdminFindOneCompany({ companyId }: { companyId: string }) {", + "const sdk = useSdk();", + "const query = useQuery({", + "queryKey: ['admin', 'find-one-company', companyId],", + "queryFn: () =>", + "sdk.adminFindOneCompany({ companyId }).then((res) => res.data),", + "retry: 0,", + "});", + "const item = query.data?.item ?? undefined;", + "return {", + "item,", + "query,", + "updateCompany: async (input: AdminUpdateCompanyInput) =>", + "sdk", + ".adminUpdateCompany({ companyId, input })", + ".then((res) => res.data)", + ".then(async (res) => {", + "if (res) {", + "toastSuccess('Company updated');", + "await query.refetch();", + "return true;", + "}", + "toastError('Company not updated');", + "return false;", + "})", + ".catch((err) => {", + "toastError(err.message);", + "return false;", + "}),", + "};", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/use-admin-find-one-company.ts", + }, + "use-user-find-many-company.ts": { + "content": [ + "import { UserCreateCompanyInput, UserFindManyCompanyInput } from '@proj/sdk';", + "import { useSdk } from '@proj/test-core-data-access';", + "import { toastError, toastSuccess } from '@pubkey-ui/core';", + "import { useQuery } from '@tanstack/react-query';", + "import { useState } from 'react';", + "export function useUserFindManyCompany(", + "props: Partial = {}", + ") {", + "const sdk = useSdk();", + "const [limit, setLimit] = useState(props?.limit ?? 10);", + "const [page, setPage] = useState(props?.page ?? 1);", + "const [search, setSearch] = useState(props?.search ?? '');", + "const input: UserFindManyCompanyInput = { page, limit, search };", + "const query = useQuery({", + "queryKey: ['user', 'find-many-company', input],", + "queryFn: () => sdk.userFindManyCompany({ input }).then((res) => res.data),", + "});", + "const total = query.data?.paging?.meta?.totalCount ?? 0;", + "const items = query.data?.paging.data ?? [];", + "return {", + "items,", + "query,", + "pagination: {", + "page,", + "setPage,", + "limit,", + "setLimit,", + "total,", + "},", + "setSearch,", + "createCompany: (input: UserCreateCompanyInput) =>", + "sdk", + ".userCreateCompany({ input })", + ".then((res) => res.data)", + ".then((res) => {", + "if (res.created) {", + "toastSuccess(\`Company created\`);", + "} else {", + "toastError(\`Company not created\`);", + "}", + "return res.created;", + "})", + ".catch((err) => {", + "toastError(err.message);", + "return undefined;", + "}),", + "deleteCompany: (companyId: string) =>", + "sdk.userDeleteCompany({ companyId }).then(() => {", + "toastSuccess('Company deleted');", + "return query.refetch();", + "}),", + "};", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/use-user-find-many-company.ts", + }, + "use-user-find-one-company.ts": { + "content": [ + "import { UserUpdateCompanyInput } from '@proj/sdk';", + "import { useSdk } from '@proj/test-core-data-access';", + "import { toastError, toastSuccess } from '@pubkey-ui/core';", + "import { useQuery } from '@tanstack/react-query';", + "export function useUserFindOneCompany({ companyId }: { companyId: string }) {", + "const sdk = useSdk();", + "const query = useQuery({", + "queryKey: ['user', 'find-one-company', companyId],", + "queryFn: () =>", + "sdk.userFindOneCompany({ companyId }).then((res) => res.data),", + "retry: 0,", + "});", + "const item = query.data?.item ?? undefined;", + "return {", + "item,", + "query,", + "updateCompany: async (input: UserUpdateCompanyInput) =>", + "sdk", + ".userUpdateCompany({ companyId, input })", + ".then((res) => res.data)", + ".then(async (res) => {", + "if (res) {", + "toastSuccess('Company updated');", + "await query.refetch();", + "return true;", + "}", + "toastError('Company not updated');", + "return false;", + "})", + ".catch((err) => {", + "toastError(err.message);", + "return false;", + "}),", + "};", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/use-user-find-one-company.ts", + }, + }, + "path": "libs/test/company/data-access/src/lib", + }, + }, + "path": "libs/test/company/data-access/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""compilerOptions": {", + ""jsx": "react-jsx",", + ""allowJs": false,", + ""esModuleInterop": false,", + ""allowSyntheticDefaultImports": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "}", + "],", + ""extends": "../../../../tsconfig.base.json"", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""types": [", + ""node",", + ""@nx/react/typings/cssmodule.d.ts",", + ""@nx/react/typings/image.d.ts"", + "]", + "},", + ""exclude": [", + ""jest.config.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.tsx",", + ""src/**/*.test.tsx",", + ""src/**/*.spec.js",", + ""src/**/*.test.js",", + ""src/**/*.spec.jsx",", + ""src/**/*.test.jsx"", + "],", + ""include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/tsconfig.lib.json", + }, + }, + "path": "libs/test/company/data-access", + }, + "feature": { + "children": { + ".babelrc": { + "content": [ + "{", + ""presets": [", + "[", + ""@nx/react/babel",", + "{", + ""runtime": "automatic",", + ""useBuiltIns": "usage"", + "}", + "]", + "],", + ""plugins": []", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/.babelrc", + }, + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["plugin:@nx/react", "../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-company-feature", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-company-feature\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/company/feature/README.md", + }, + "project.json": { + "content": [ + "{", + ""name": "test-company-feature",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/company/feature/src",", + ""projectType": "library",", + ""tags": ["app:test", "type:feature"],", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "}", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [ + "import { lazy } from 'react';", + "export const UserCompanyFeature = lazy(", + "() => import('./lib/user-company.routes')", + ");", + "export const AdminCompanyFeature = lazy(", + "() => import('./lib/admin-company.routes')", + ");", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/index.ts", + }, + "lib": { + "children": { + "admin-company-create.feature.tsx": { + "content": [ + "import { AdminCreateCompanyInput } from '@proj/sdk';", + "import { useAdminFindManyCompany } from '@proj/test-company-data-access';", + "import { AdminCompanyUiCreateForm } from '@proj/test-company-ui';", + "import { toastError, UiBack, UiCard, UiPage } from '@pubkey-ui/core';", + "import { useNavigate } from 'react-router-dom';", + "export function AdminCompanyCreateFeature({ ownerId }: { ownerId: string }) {", + "const navigate = useNavigate();", + "const { createCompany } = useAdminFindManyCompany(ownerId);", + "async function submit(input: AdminCreateCompanyInput) {", + "return createCompany(input)", + ".then((res) => {", + "if (res) {", + "navigate(\`../\${res?.id}\`);", + "}", + "})", + ".then(() => true)", + ".catch((err) => {", + "toastError(err.message);", + "return false;", + "});", + "}", + "return (", + "} title="Create Company">", + "", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/admin-company-create.feature.tsx", + }, + "admin-company-detail-info.tab.tsx": { + "content": [ + "import { useAdminFindOneCompany } from '@proj/test-company-data-access';", + "import { CompanyUiInfo } from '@proj/test-company-ui';", + "import { UiCard, UiError, UiLoader } from '@pubkey-ui/core';", + "export function AdminCompanyDetailInfoTab({", + "companyId,", + "}: {", + "companyId: string;", + "}) {", + "const { item, query } = useAdminFindOneCompany({ companyId });", + "if (query.isLoading) {", + "return ;", + "}", + "if (!item) {", + "return ;", + "}", + "return (", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/admin-company-detail-info.tab.tsx", + }, + "admin-company-detail-settings.tab.tsx": { + "content": [ + "import { useAdminFindOneCompany } from '@proj/test-company-data-access';", + "import { AdminCompanyUiUpdateForm } from '@proj/test-company-ui';", + "import { UiCard, UiError, UiLoader } from '@pubkey-ui/core';", + "export function AdminCompanyDetailSettingsTab({", + "companyId,", + "}: {", + "companyId: string;", + "}) {", + "const { item, query, updateCompany } = useAdminFindOneCompany({ companyId });", + "if (query.isLoading) {", + "return ;", + "}", + "if (!item) {", + "return ;", + "}", + "return (", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/admin-company-detail-settings.tab.tsx", + }, + "admin-company-detail.feature.tsx": { + "content": [ + "import { Group } from '@mantine/core';", + "import {", + "UiBack,", + "UiDebugModal,", + "UiError,", + "UiLoader,", + "UiPage,", + "UiTabRoutes,", + "} from '@pubkey-ui/core';", + "import { useAdminFindOneCompany } from '@proj/test-company-data-access';", + "import { CompanyUiItem } from '@proj/test-company-ui';", + "import { useParams } from 'react-router-dom';", + "import { AdminCompanyDetailInfoTab } from './admin-company-detail-info.tab';", + "import { AdminCompanyDetailSettingsTab } from './admin-company-detail-settings.tab';", + "export function AdminCompanyDetailFeature() {", + "const { companyId } = useParams<{ companyId: string }>() as {", + "companyId: string;", + "};", + "const { item, query } = useAdminFindOneCompany({ companyId });", + "if (query.isLoading) {", + "return ;", + "}", + "if (!item) {", + "return ;", + "}", + "return (", + "}", + "leftAction={}", + "rightAction={", + "", + "", + "", + "}", + ">", + ",", + "},", + "{", + "path: 'settings',", + "label: 'Settings',", + "element: ,", + "},", + "]}", + "/>", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/admin-company-detail.feature.tsx", + }, + "admin-company-list.feature.tsx": { + "content": [ + "import { Button, Group } from '@mantine/core';", + "import { UiPageLimit, UiSearchField } from '@proj/test-core-ui';", + "import { useAdminFindManyCompany } from '@proj/test-company-data-access';", + "import { AdminCompanyUiTable } from '@proj/test-company-ui';", + "import {", + "UiBack,", + "UiDebugModal,", + "UiInfo,", + "UiLoader,", + "UiStack,", + "} from '@pubkey-ui/core';", + "import { Link } from 'react-router-dom';", + "export function AdminCompanyListFeature({ ownerId }: { ownerId: string }) {", + "const { deleteCompany, items, pagination, query, setSearch } =", + "useAdminFindManyCompany({", + "limit: 10,", + "ownerId,", + "});", + "return (", + "", + "", + "", + "", + "", + "", + "", + "{query.isLoading ? (", + "", + ") : items?.length ? (", + " {", + "if (!window.confirm('Are you sure?')) return;", + "return deleteCompany(company.id);", + "}}", + "companies={items}", + "page={pagination.page}", + "totalRecords={pagination.total}", + "recordsPerPage={pagination.limit}", + "onPageChange={(page) => void pagination.setPage(page)}", + "/>", + ") : (", + "", + ")}", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/admin-company-list.feature.tsx", + }, + "admin-company.routes.tsx": { + "content": [ + "import { useRoutes } from 'react-router-dom';", + "import { AdminCompanyDetailFeature } from './admin-company-detail.feature';", + "import { AdminCompanyCreateFeature } from './admin-company-create.feature';", + "import { AdminCompanyListFeature } from './admin-company-list.feature';", + "export default function AdminCompanyRoutes({ ownerId }: { ownerId: string }) {", + "return useRoutes([", + "{ path: '', element: },", + "{", + "path: 'create',", + "element: ,", + "},", + "{ path: ':companyId/*', element: },", + "]);", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/admin-company.routes.tsx", + }, + "user-company-create.feature.tsx": { + "content": [ + "import { UserCreateCompanyInput } from '@proj/sdk';", + "import { useUserFindManyCompany } from '@proj/test-company-data-access';", + "import { UserCompanyUiCreateForm } from '@proj/test-company-ui';", + "import { toastError, UiBack, UiCard, UiPage } from '@pubkey-ui/core';", + "import { useNavigate } from 'react-router-dom';", + "export function UserCompanyCreateFeature() {", + "const navigate = useNavigate();", + "const { createCompany } = useUserFindManyCompany();", + "async function submit(input: UserCreateCompanyInput) {", + "return createCompany(input)", + ".then((res) => {", + "if (res) {", + "navigate(\`../\${res?.id}\`);", + "}", + "})", + ".then(() => true)", + ".catch((err) => {", + "toastError(err.message);", + "return false;", + "});", + "}", + "return (", + "} title="Create Company">", + "", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/user-company-create.feature.tsx", + }, + "user-company-detail-info.tab.tsx": { + "content": [ + "import { useUserFindOneCompany } from '@proj/test-company-data-access';", + "import { CompanyUiInfo } from '@proj/test-company-ui';", + "import { UiCard, UiError, UiLoader } from '@pubkey-ui/core';", + "export function UserCompanyDetailInfoTab({ companyId }: { companyId: string }) {", + "const { item, query } = useUserFindOneCompany({ companyId });", + "if (query.isLoading) {", + "return ;", + "}", + "if (!item) {", + "return ;", + "}", + "return (", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/user-company-detail-info.tab.tsx", + }, + "user-company-detail-settings.tab.tsx": { + "content": [ + "import { useUserFindOneCompany } from '@proj/test-company-data-access';", + "import { UserCompanyUiUpdateForm } from '@proj/test-company-ui';", + "import { UiCard, UiError, UiLoader } from '@pubkey-ui/core';", + "export function UserCompanyDetailSettingsTab({", + "companyId,", + "}: {", + "companyId: string;", + "}) {", + "const { item, query, updateCompany } = useUserFindOneCompany({ companyId });", + "if (query.isLoading) {", + "return ;", + "}", + "if (!item) {", + "return ;", + "}", + "return (", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/user-company-detail-settings.tab.tsx", + }, + "user-company-detail.feature.tsx": { + "content": [ + "import { Group } from '@mantine/core';", + "import {", + "UiBack,", + "UiDebugModal,", + "UiError,", + "UiLoader,", + "UiPage,", + "UiTabRoutes,", + "} from '@pubkey-ui/core';", + "import { useUserFindOneCompany } from '@proj/test-company-data-access';", + "import { CompanyUiItem } from '@proj/test-company-ui';", + "import { useParams } from 'react-router-dom';", + "import { UserCompanyDetailInfoTab } from './user-company-detail-info.tab';", + "import { UserCompanyDetailSettingsTab } from './user-company-detail-settings.tab';", + "export function UserCompanyDetailFeature() {", + "const { companyId } = useParams<{ companyId: string }>() as {", + "companyId: string;", + "};", + "const { item, query } = useUserFindOneCompany({ companyId });", + "if (query.isLoading) {", + "return ;", + "}", + "if (!item) {", + "return ;", + "}", + "return (", + "}", + "leftAction={}", + "rightAction={", + "", + "", + "", + "}", + ">", + ",", + "},", + "{", + "path: 'settings',", + "label: 'Settings',", + "element: ,", + "},", + "]}", + "/>", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/user-company-detail.feature.tsx", + }, + "user-company-list.feature.tsx": { + "content": [ + "import { Button, Group } from '@mantine/core';", + "import { UiPageLimit, UiSearchField } from '@proj/test-core-ui';", + "import { useUserFindManyCompany } from '@proj/test-company-data-access';", + "import { CompanyUiGrid } from '@proj/test-company-ui';", + "import {", + "UiBack,", + "UiDebugModal,", + "UiInfo,", + "UiLoader,", + "UiPage,", + "} from '@pubkey-ui/core';", + "import { Link } from 'react-router-dom';", + "export function UserCompanyListFeature() {", + "const { deleteCompany, items, pagination, query, setSearch } =", + "useUserFindManyCompany({", + "limit: 12,", + "});", + "return (", + "}", + "rightAction={", + "", + "", + "", + "", + "}", + ">", + "", + "", + "", + "{query.isLoading ? (", + "", + ") : items?.length ? (", + "", + ") : (", + "", + ")}", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/user-company-list.feature.tsx", + }, + "user-company.routes.tsx": { + "content": [ + "import { useRoutes } from 'react-router-dom';", + "import { UserCompanyDetailFeature } from './user-company-detail.feature';", + "import { UserCompanyCreateFeature } from './user-company-create.feature';", + "import { UserCompanyListFeature } from './user-company-list.feature';", + "export default function UserCompanyRoutes() {", + "return useRoutes([", + "{ path: '', element: },", + "{", + "path: 'create',", + "element: ,", + "},", + "{ path: ':companyId/*', element: },", + "]);", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/user-company.routes.tsx", + }, + }, + "path": "libs/test/company/feature/src/lib", + }, + }, + "path": "libs/test/company/feature/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""compilerOptions": {", + ""jsx": "react-jsx",", + ""allowJs": false,", + ""esModuleInterop": false,", + ""allowSyntheticDefaultImports": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "}", + "],", + ""extends": "../../../../tsconfig.base.json"", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""types": [", + ""node",", + ""@nx/react/typings/cssmodule.d.ts",", + ""@nx/react/typings/image.d.ts"", + "]", + "},", + ""exclude": [", + ""jest.config.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.tsx",", + ""src/**/*.test.tsx",", + ""src/**/*.spec.js",", + ""src/**/*.test.js",", + ""src/**/*.spec.jsx",", + ""src/**/*.test.jsx"", + "],", + ""include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/tsconfig.lib.json", + }, + }, + "path": "libs/test/company/feature", + }, + "ui": { + "children": { + ".babelrc": { + "content": [ + "{", + ""presets": [", + "[", + ""@nx/react/babel",", + "{", + ""runtime": "automatic",", + ""useBuiltIns": "usage"", + "}", + "]", + "],", + ""plugins": []", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/.babelrc", + }, + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["plugin:@nx/react", "../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-company-ui", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-company-ui\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/company/ui/README.md", + }, + "project.json": { + "content": [ + "{", + ""name": "test-company-ui",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/company/ui/src",", + ""projectType": "library",", + ""tags": ["app:test", "type:ui"],", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "}", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [ + "export * from './lib/user-company-ui-create-form';", + "export * from './lib/user-company-ui-table';", + "export * from './lib/user-company-ui-update-form';", + "export * from './lib/company-ui-avatar';", + "export * from './lib/company-ui-grid';", + "export * from './lib/company-ui-grid-item';", + "export * from './lib/company-ui-info';", + "export * from './lib/company-ui-item';", + "export * from './lib/admin-company-ui-create-form';", + "export * from './lib/admin-company-ui-table';", + "export * from './lib/admin-company-ui-update-form';", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/index.ts", + }, + "lib": { + "children": { + "admin-company-ui-create-form.tsx": { + "content": [ + "import { Button, Group } from '@mantine/core';", + "import { AdminCreateCompanyInput } from '@proj/sdk';", + "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", + "import { ReactNode } from 'react';", + "export function AdminCompanyUiCreateForm({", + "submit,", + "}: {", + "submit: (res: AdminCreateCompanyInput) => Promise;", + "}) {", + "const model: AdminCreateCompanyInput = {", + "name: '',", + "location: '',", + "phone: '',", + "};", + "const fields: UiFormField[] = [", + "formFieldText('name', { label: 'name', required: true }),", + "formFieldText('location', { label: 'location', required: true }),", + "formFieldText('phone', { label: 'phone', required: true }),", + "];", + "return (", + " submit(res as AdminCreateCompanyInput)}", + ">", + "", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/admin-company-ui-create-form.tsx", + }, + "admin-company-ui-table.tsx": { + "content": [ + "import { ActionIcon, Anchor, Group, ScrollArea } from '@mantine/core';", + "import { Company } from '@proj/sdk';", + "import { IconPencil, IconTrash } from '@tabler/icons-react';", + "import { DataTable, DataTableProps } from 'mantine-datatable';", + "import { Link } from 'react-router-dom';", + "export function AdminCompanyUiTable({", + "deleteCompany,", + "companies = [],", + "onPageChange,", + "page,", + "recordsPerPage,", + "totalRecords,", + "}: {", + "deleteCompany: (company: Company) => void;", + "companies: Company[];", + "page: DataTableProps['page'];", + "totalRecords: DataTableProps['totalRecords'];", + "recordsPerPage: DataTableProps['recordsPerPage'];", + "onPageChange: (page: number) => void;", + "}) {", + "return (", + "", + " (", + "", + "{item.name}", + "", + "),", + "},", + "{", + "accessor: 'actions',", + "title: 'Actions',", + "textAlign: 'right',", + "render: (item) => (", + "", + "", + "", + "", + " deleteCompany(item)}", + ">", + "", + "", + "", + "),", + "},", + "]}", + "records={companies}", + "/>", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/admin-company-ui-table.tsx", + }, + "admin-company-ui-update-form.tsx": { + "content": [ + "import { Button, Group } from '@mantine/core';", + "import { AdminUpdateCompanyInput, Company } from '@proj/sdk';", + "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", + "export function AdminCompanyUiUpdateForm({", + "submit,", + "company,", + "}: {", + "submit: (res: AdminUpdateCompanyInput) => Promise;", + "company: Company;", + "}) {", + "const model: AdminUpdateCompanyInput = {", + "name: company.name ?? '',", + "location: company.location ?? '',", + "phone: company.phone ?? '',", + "};", + "const fields: UiFormField[] = [", + "formFieldText('name', { label: 'name' }),", + "formFieldText('location', { label: 'location' }),", + "formFieldText('phone', { label: 'phone' }),", + "];", + "return (", + " submit(res as AdminUpdateCompanyInput)}", + ">", + "", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/admin-company-ui-update-form.tsx", + }, + "company-ui-avatar.tsx": { + "content": [ + "import { Company } from '@proj/sdk';", + "import { UiAvatar, UiAvatarProps } from '@pubkey-ui/core';", + "export type CompanyUiAvatarProps = UiAvatarProps & {", + "company?: Company;", + "};", + "export function CompanyUiAvatar({ company, ...props }: CompanyUiAvatarProps) {", + "return ;", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/company-ui-avatar.tsx", + }, + "company-ui-grid-item.tsx": { + "content": [ + "import { Paper } from '@mantine/core';", + "import { Company } from '@proj/sdk';", + "import { UiDebugModal, UiGroup } from '@pubkey-ui/core';", + "import { CompanyUiItem } from './company-ui-item';", + "export function CompanyUiGridItem({", + "company,", + "to,", + "}: {", + "company: Company;", + "to?: string;", + "}) {", + "return (", + "", + "", + "", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/company-ui-grid-item.tsx", + }, + "company-ui-grid.tsx": { + "content": [ + "import { Group, Pagination, SimpleGrid } from '@mantine/core';", + "import { Company } from '@proj/sdk';", + "import { gridLimits, UiPageLimit } from '@proj/test-core-ui';", + "import { UiDebugModal, UiGroup, UiStack } from '@pubkey-ui/core';", + "import { DataTableProps } from 'mantine-datatable';", + "import { CompanyUiGridItem } from './company-ui-grid-item';", + "export function CompanyUiGrid({", + "companies = [],", + "onPageChange,", + "page,", + "totalRecords,", + "limit,", + "setLimit,", + "setPage,", + "}: {", + "companies: Company[];", + "page: DataTableProps['page'];", + "totalRecords: number;", + "onPageChange: (page: number) => void;", + "limit: number;", + "setLimit: (limit: number) => void;", + "setPage: (page: number) => void;", + "}) {", + "const totalPages = totalRecords / limit + 1;", + "return (", + "", + "", + "{companies.map((company) => (", + "", + "))}", + "", + "", + "", + "", + "", + "", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/company-ui-grid.tsx", + }, + "company-ui-info.tsx": { + "content": [ + "import { Company } from '@proj/sdk';", + "import { UiInfoItems, UiInfoTable, UiTime } from '@pubkey-ui/core';", + "export function CompanyUiInfo({ company }: { company?: Company }) {", + "if (!company) return null;", + "const items: UiInfoItems = [", + "['name', company.name],", + "[", + "'Created At',", + ",", + "],", + "[", + "'Updated At',", + ",", + "],", + "];", + "return ;", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/company-ui-info.tsx", + }, + "company-ui-item.tsx": { + "content": [ + "import {", + "AvatarProps,", + "Group,", + "type GroupProps,", + "Stack,", + "Text,", + "} from '@mantine/core';", + "import { Company } from '@proj/sdk';", + "import { UiAnchor, type UiAnchorProps } from '@pubkey-ui/core';", + "import { CompanyUiAvatar } from './company-ui-avatar';", + "export function CompanyUiItem({", + "anchorProps,", + "avatarProps,", + "groupProps,", + "company,", + "to,", + "}: {", + "anchorProps?: UiAnchorProps;", + "avatarProps?: Omit;", + "groupProps?: GroupProps;", + "company?: Company;", + "to?: string | null;", + "}) {", + "if (!company) return null;", + "return (", + "", + "", + "", + "", + "", + "{company?.name}", + "", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/company-ui-item.tsx", + }, + "user-company-ui-create-form.tsx": { + "content": [ + "import { Button, Group } from '@mantine/core';", + "import { UserCreateCompanyInput } from '@proj/sdk';", + "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", + "import { ReactNode } from 'react';", + "export function UserCompanyUiCreateForm({", + "submit,", + "}: {", + "submit: (res: UserCreateCompanyInput) => Promise;", + "}) {", + "const model: UserCreateCompanyInput = {", + "name: '',", + "location: '',", + "phone: '',", + "};", + "const fields: UiFormField[] = [", + "formFieldText('name', { label: 'name', required: true }),", + "formFieldText('location', { label: 'location', required: true }),", + "formFieldText('phone', { label: 'phone', required: true }),", + "];", + "return (", + " submit(res as UserCreateCompanyInput)}", + ">", + "", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/user-company-ui-create-form.tsx", + }, + "user-company-ui-table.tsx": { + "content": [ + "import { ActionIcon, Anchor, Group, ScrollArea } from '@mantine/core';", + "import { Company } from '@proj/sdk';", + "import { IconPencil, IconTrash } from '@tabler/icons-react';", + "import { DataTable, DataTableProps } from 'mantine-datatable';", + "import { Link } from 'react-router-dom';", + "export function UserCompanyUiTable({", + "deleteCompany,", + "companies = [],", + "onPageChange,", + "page,", + "recordsPerPage,", + "totalRecords,", + "}: {", + "deleteCompany: (company: Company) => void;", + "companies: Company[];", + "page: DataTableProps['page'];", + "totalRecords: DataTableProps['totalRecords'];", + "recordsPerPage: DataTableProps['recordsPerPage'];", + "onPageChange: (page: number) => void;", + "}) {", + "return (", + "", + " (", + "", + "{item.name}", + "", + "),", + "},", + "{", + "accessor: 'actions',", + "title: 'Actions',", + "textAlign: 'right',", + "render: (item) => (", + "", + "", + "", + "", + " deleteCompany(item)}", + ">", + "", + "", + "", + "),", + "},", + "]}", + "records={companies}", + "/>", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/user-company-ui-table.tsx", + }, + "user-company-ui-update-form.tsx": { + "content": [ + "import { Button, Group } from '@mantine/core';", + "import { UserUpdateCompanyInput, Company } from '@proj/sdk';", + "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", + "export function UserCompanyUiUpdateForm({", + "submit,", + "company,", + "}: {", + "submit: (res: UserUpdateCompanyInput) => Promise;", + "company: Company;", + "}) {", + "const model: UserUpdateCompanyInput = {", + "name: company.name ?? '',", + "location: company.location ?? '',", + "phone: company.phone ?? '',", + "};", + "const fields: UiFormField[] = [", + "formFieldText('name', { label: 'name' }),", + "formFieldText('location', { label: 'location' }),", + "formFieldText('phone', { label: 'phone' }),", + "];", + "return (", + " submit(res as UserUpdateCompanyInput)}", + ">", + "", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/user-company-ui-update-form.tsx", + }, + }, + "path": "libs/test/company/ui/src/lib", + }, + }, + "path": "libs/test/company/ui/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""compilerOptions": {", + ""jsx": "react-jsx",", + ""allowJs": false,", + ""esModuleInterop": false,", + ""allowSyntheticDefaultImports": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "}", + "],", + ""extends": "../../../../tsconfig.base.json"", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""types": [", + ""node",", + ""@nx/react/typings/cssmodule.d.ts",", + ""@nx/react/typings/image.d.ts"", + "]", + "},", + ""exclude": [", + ""jest.config.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.tsx",", + ""src/**/*.test.tsx",", + ""src/**/*.spec.js",", + ""src/**/*.test.js",", + ""src/**/*.spec.jsx",", + ""src/**/*.test.jsx"", + "],", + ""include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/tsconfig.lib.json", + }, + }, + "path": "libs/test/company/ui", + }, + }, + "path": "libs/test/company", + }, + "core": { + "children": { + "data-access": { + "children": { + ".babelrc": { + "content": [ + "{", + ""presets": [", + "[", + ""@nx/react/babel",", + "{", + ""runtime": "automatic",", + ""useBuiltIns": "usage"", + "}", + "]", + "],", + ""plugins": []", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/.babelrc", + }, + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["plugin:@nx/react", "../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-core-data-access", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-core-data-access\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/core/data-access/README.md", + }, + "project.json": { + "content": [ + "{", + ""name": "test-core-data-access",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/core/data-access/src",", + ""projectType": "library",", + ""tags": [],", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "}", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [], + "isBinary": false, + "path": "libs/test/core/data-access/src/index.ts", + }, + }, + "path": "libs/test/core/data-access/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""compilerOptions": {", + ""jsx": "react-jsx",", + ""allowJs": false,", + ""esModuleInterop": false,", + ""allowSyntheticDefaultImports": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "}", + "],", + ""extends": "../../../../tsconfig.base.json"", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""types": [", + ""node",", + ""@nx/react/typings/cssmodule.d.ts",", + ""@nx/react/typings/image.d.ts"", + "]", + "},", + ""exclude": [", + ""jest.config.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.tsx",", + ""src/**/*.test.tsx",", + ""src/**/*.spec.js",", + ""src/**/*.test.js",", + ""src/**/*.spec.jsx",", + ""src/**/*.test.jsx"", + "],", + ""include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/tsconfig.lib.json", + }, + }, + "path": "libs/test/core/data-access", + }, + "feature": { + "children": { + ".babelrc": { + "content": [ + "{", + ""presets": [", + "[", + ""@nx/react/babel",", + "{", + ""runtime": "automatic",", + ""useBuiltIns": "usage"", + "}", + "]", + "],", + ""plugins": []", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/.babelrc", + }, + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["plugin:@nx/react", "../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-core-feature", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-core-feature\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/core/feature/README.md", + }, + "project.json": { + "content": [ + "{", + ""name": "test-core-feature",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/core/feature/src",", + ""projectType": "library",", + ""tags": [],", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "}", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [], + "isBinary": false, + "path": "libs/test/core/feature/src/index.ts", + }, + "lib": { + "children": { + "test-core-feature.tsx": { + "content": [ + "/* eslint-disable-next-line */", + "export interface TestCoreFeatureProps {}", + "export function TestCoreFeature(props: TestCoreFeatureProps) {", + "return (", + "
", + "

Welcome to TestCoreFeature!

", + "
", + ");", + "}", + "export default TestCoreFeature;", + ], + "isBinary": false, + "path": "libs/test/core/feature/src/lib/test-core-feature.tsx", + }, + "test-core-routes-admin.tsx": { + "content": [ + "import { IconBuilding } from '@tabler/icons-react';", + "import { AdminCompanyFeature } from '@proj/test-company-feature';", + "/* eslint-disable-next-line */", + "export interface TestCoreRoutesAdminProps {}", + "export function TestCoreRoutesAdmin(props: TestCoreRoutesAdminProps) {", + "return (", + "
", + "

Welcome to TestCoreRoutesAdmin!

", + "
", + ");", + "}", + "export default TestCoreRoutesAdmin;", + ], + "isBinary": false, + "path": "libs/test/core/feature/src/lib/test-core-routes-admin.tsx", + }, + "test-core-routes-manager.tsx": { + "content": [ + "/* eslint-disable-next-line */", + "export interface TestCoreRoutesManagerProps {}", + "export function TestCoreRoutesManager(props: TestCoreRoutesManagerProps) {", + "return (", + "
", + "

Welcome to TestCoreRoutesManager!

", + "
", + ");", + "}", + "export default TestCoreRoutesManager;", + ], + "isBinary": false, + "path": "libs/test/core/feature/src/lib/test-core-routes-manager.tsx", + }, + "test-core-routes-user.tsx": { + "content": [ + "import { IconBuilding } from '@tabler/icons-react';", + "import { UserCompanyFeature } from '@proj/test-company-feature';", + "/* eslint-disable-next-line */", + "export interface TestCoreRoutesUserProps {}", + "export function TestCoreRoutesUser(props: TestCoreRoutesUserProps) {", + "return (", + "
", + "

Welcome to TestCoreRoutesUser!

", + "
", + ");", + "}", + "export default TestCoreRoutesUser;", + ], + "isBinary": false, + "path": "libs/test/core/feature/src/lib/test-core-routes-user.tsx", + }, + "test-core-routes.tsx": { + "content": [ + "/* eslint-disable-next-line */", + "export interface TestCoreRoutesProps {}", + "export function TestCoreRoutes(props: TestCoreRoutesProps) {", + "return (", + "
", + "

Welcome to TestCoreRoutes!

", + "
", + ");", + "}", + "export default TestCoreRoutes;", + ], + "isBinary": false, + "path": "libs/test/core/feature/src/lib/test-core-routes.tsx", + }, + }, + "path": "libs/test/core/feature/src/lib", + }, + }, + "path": "libs/test/core/feature/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""compilerOptions": {", + ""jsx": "react-jsx",", + ""allowJs": false,", + ""esModuleInterop": false,", + ""allowSyntheticDefaultImports": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "}", + "],", + ""extends": "../../../../tsconfig.base.json"", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""types": [", + ""node",", + ""@nx/react/typings/cssmodule.d.ts",", + ""@nx/react/typings/image.d.ts"", + "]", + "},", + ""exclude": [", + ""jest.config.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.tsx",", + ""src/**/*.test.tsx",", + ""src/**/*.spec.js",", + ""src/**/*.test.js",", + ""src/**/*.spec.jsx",", + ""src/**/*.test.jsx"", + "],", + ""include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/tsconfig.lib.json", + }, + }, + "path": "libs/test/core/feature", + }, + }, + "path": "libs/test/core", + }, +} +`; + +exports[`web-crud generator should create crud with modelParentId 1`] = ` +{ + "company": { + "children": { + "data-access": { + "children": { + ".babelrc": { + "content": [ + "{", + ""presets": [", + "[", + ""@nx/react/babel",", + "{", + ""runtime": "automatic",", + ""useBuiltIns": "usage"", + "}", + "]", + "],", + ""plugins": []", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/.babelrc", + }, + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["plugin:@nx/react", "../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-company-data-access", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-company-data-access\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/company/data-access/README.md", + }, + "project.json": { + "content": [ + "{", + ""name": "test-company-data-access",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/company/data-access/src",", + ""projectType": "library",", + ""tags": ["app:test", "type:data-access"],", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "}", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [ + "export * from './lib/use-manager-find-many-company';", + "export * from './lib/use-manager-find-one-company';", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/index.ts", + }, + "lib": { + "children": { + "use-manager-find-many-company.ts": { + "content": [ + "import {", + "ManagerCreateCompanyInput,", + "ManagerFindManyCompanyInput,", + "} from '@proj/sdk';", + "import { useSdk } from '@proj/test-core-data-access';", + "import { toastError, toastSuccess } from '@pubkey-ui/core';", + "import { useQuery } from '@tanstack/react-query';", + "import { useState } from 'react';", + "export function useManagerFindManyCompany(", + "props: Partial = {}", + ") {", + "const sdk = useSdk();", + "const [limit, setLimit] = useState(props?.limit ?? 10);", + "const [page, setPage] = useState(props?.page ?? 1);", + "const [search, setSearch] = useState(props?.search ?? '');", + "const input: ManagerFindManyCompanyInput = { page, limit, search };", + "const query = useQuery({", + "queryKey: ['manager', 'find-many-company', input],", + "queryFn: () =>", + "sdk.managerFindManyCompany({ input }).then((res) => res.data),", + "});", + "const total = query.data?.paging?.meta?.totalCount ?? 0;", + "const items = query.data?.paging.data ?? [];", + "return {", + "items,", + "query,", + "pagination: {", + "page,", + "setPage,", + "limit,", + "setLimit,", + "total,", + "},", + "setSearch,", + "createCompany: (input: ManagerCreateCompanyInput) =>", + "sdk", + ".managerCreateCompany({ input })", + ".then((res) => res.data)", + ".then((res) => {", + "if (res.created) {", + "toastSuccess(\`Company created\`);", + "} else {", + "toastError(\`Company not created\`);", + "}", + "return res.created;", + "})", + ".catch((err) => {", + "toastError(err.message);", + "return undefined;", + "}),", + "deleteCompany: (companyId: string) =>", + "sdk.managerDeleteCompany({ companyId }).then(() => {", + "toastSuccess('Company deleted');", + "return query.refetch();", + "}),", + "};", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/use-manager-find-many-company.ts", + }, + "use-manager-find-one-company.ts": { + "content": [ + "import { ManagerUpdateCompanyInput } from '@proj/sdk';", + "import { useSdk } from '@proj/test-core-data-access';", + "import { toastError, toastSuccess } from '@pubkey-ui/core';", + "import { useQuery } from '@tanstack/react-query';", + "export function useManagerFindOneCompany({ companyId }: { companyId: string }) {", + "const sdk = useSdk();", + "const query = useQuery({", + "queryKey: ['manager', 'find-one-company', companyId],", + "queryFn: () =>", + "sdk.managerFindOneCompany({ companyId }).then((res) => res.data),", + "retry: 0,", + "});", + "const item = query.data?.item ?? undefined;", + "return {", + "item,", + "query,", + "updateCompany: async (input: ManagerUpdateCompanyInput) =>", + "sdk", + ".managerUpdateCompany({ companyId, input })", + ".then((res) => res.data)", + ".then(async (res) => {", + "if (res) {", + "toastSuccess('Company updated');", + "await query.refetch();", + "return true;", + "}", + "toastError('Company not updated');", + "return false;", + "})", + ".catch((err) => {", + "toastError(err.message);", + "return false;", + "}),", + "};", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/src/lib/use-manager-find-one-company.ts", + }, + }, + "path": "libs/test/company/data-access/src/lib", + }, + }, + "path": "libs/test/company/data-access/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""compilerOptions": {", + ""jsx": "react-jsx",", + ""allowJs": false,", + ""esModuleInterop": false,", + ""allowSyntheticDefaultImports": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "}", + "],", + ""extends": "../../../../tsconfig.base.json"", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""types": [", + ""node",", + ""@nx/react/typings/cssmodule.d.ts",", + ""@nx/react/typings/image.d.ts"", + "]", + "},", + ""exclude": [", + ""jest.config.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.tsx",", + ""src/**/*.test.tsx",", + ""src/**/*.spec.js",", + ""src/**/*.test.js",", + ""src/**/*.spec.jsx",", + ""src/**/*.test.jsx"", + "],", + ""include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/data-access/tsconfig.lib.json", + }, + }, + "path": "libs/test/company/data-access", + }, + "feature": { + "children": { + ".babelrc": { + "content": [ + "{", + ""presets": [", + "[", + ""@nx/react/babel",", + "{", + ""runtime": "automatic",", + ""useBuiltIns": "usage"", + "}", + "]", + "],", + ""plugins": []", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/.babelrc", + }, + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["plugin:@nx/react", "../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-company-feature", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-company-feature\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/company/feature/README.md", + }, + "project.json": { + "content": [ + "{", + ""name": "test-company-feature",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/company/feature/src",", + ""projectType": "library",", + ""tags": ["app:test", "type:feature"],", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "}", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [ + "import { lazy } from 'react';", + "export const ManagerCompanyFeature = lazy(", + "() => import('./lib/manager-company.routes')", + ");", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/index.ts", + }, + "lib": { + "children": { + "manager-company-create.feature.tsx": { + "content": [ + "import { ManagerCreateCompanyInput } from '@proj/sdk';", + "import { useManagerFindManyCompany } from '@proj/test-company-data-access';", + "import { ManagerCompanyUiCreateForm } from '@proj/test-company-ui';", + "import { toastError, UiBack, UiCard, UiPage } from '@pubkey-ui/core';", + "import { useNavigate } from 'react-router-dom';", + "export function ManagerCompanyCreateFeature() {", + "const navigate = useNavigate();", + "const { createCompany } = useManagerFindManyCompany();", + "async function submit(input: ManagerCreateCompanyInput) {", + "return createCompany(input)", + ".then((res) => {", + "if (res) {", + "navigate(\`../\${res?.id}\`);", + "}", + "})", + ".then(() => true)", + ".catch((err) => {", + "toastError(err.message);", + "return false;", + "});", + "}", + "return (", + "} title="Create Company">", + "", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/manager-company-create.feature.tsx", + }, + "manager-company-detail-info.tab.tsx": { + "content": [ + "import { useManagerFindOneCompany } from '@proj/test-company-data-access';", + "import { CompanyUiInfo } from '@proj/test-company-ui';", + "import { UiCard, UiError, UiLoader } from '@pubkey-ui/core';", + "export function ManagerCompanyDetailInfoTab({", + "companyId,", + "}: {", + "companyId: string;", + "}) {", + "const { item, query } = useManagerFindOneCompany({ companyId });", + "if (query.isLoading) {", + "return ;", + "}", + "if (!item) {", + "return ;", + "}", + "return (", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/manager-company-detail-info.tab.tsx", + }, + "manager-company-detail-settings.tab.tsx": { + "content": [ + "import { useManagerFindOneCompany } from '@proj/test-company-data-access';", + "import { ManagerCompanyUiUpdateForm } from '@proj/test-company-ui';", + "import { UiCard, UiError, UiLoader } from '@pubkey-ui/core';", + "export function ManagerCompanyDetailSettingsTab({", + "companyId,", + "}: {", + "companyId: string;", + "}) {", + "const { item, query, updateCompany } = useManagerFindOneCompany({", + "companyId,", + "});", + "if (query.isLoading) {", + "return ;", + "}", + "if (!item) {", + "return ;", + "}", + "return (", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/manager-company-detail-settings.tab.tsx", + }, + "manager-company-detail.feature.tsx": { + "content": [ + "import { Group } from '@mantine/core';", + "import {", + "UiBack,", + "UiDebugModal,", + "UiError,", + "UiLoader,", + "UiPage,", + "UiTabRoutes,", + "} from '@pubkey-ui/core';", + "import { useManagerFindOneCompany } from '@proj/test-company-data-access';", + "import { CompanyUiItem } from '@proj/test-company-ui';", + "import { useParams } from 'react-router-dom';", + "import { ManagerCompanyDetailInfoTab } from './manager-company-detail-info.tab';", + "import { ManagerCompanyDetailSettingsTab } from './manager-company-detail-settings.tab';", + "export function ManagerCompanyDetailFeature() {", + "const { companyId } = useParams<{ companyId: string }>() as {", + "companyId: string;", + "};", + "const { item, query } = useManagerFindOneCompany({ companyId });", + "if (query.isLoading) {", + "return ;", + "}", + "if (!item) {", + "return ;", + "}", + "return (", + "}", + "leftAction={}", + "rightAction={", + "", + "", + "", + "}", + ">", + ",", + "},", + "{", + "path: 'settings',", + "label: 'Settings',", + "element: ,", + "},", + "]}", + "/>", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/manager-company-detail.feature.tsx", + }, + "manager-company-list.feature.tsx": { + "content": [ + "import { Button, Group } from '@mantine/core';", + "import { UiPageLimit, UiSearchField } from '@proj/test-core-ui';", + "import { useManagerFindManyCompany } from '@proj/test-company-data-access';", + "import { CompanyUiGrid } from '@proj/test-company-ui';", + "import {", + "UiBack,", + "UiDebugModal,", + "UiInfo,", + "UiLoader,", + "UiPage,", + "} from '@pubkey-ui/core';", + "import { Link } from 'react-router-dom';", + "export function ManagerCompanyListFeature() {", + "const { deleteCompany, items, pagination, query, setSearch } =", + "useManagerFindManyCompany({", + "limit: 12,", + "});", + "return (", + "}", + "rightAction={", + "", + "", + "", + "", + "}", + ">", + "", + "", + "", + "{query.isLoading ? (", + "", + ") : items?.length ? (", + "", + ") : (", + "", + ")}", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/manager-company-list.feature.tsx", + }, + "manager-company.routes.tsx": { + "content": [ + "import { useRoutes } from 'react-router-dom';", + "import { ManagerCompanyDetailFeature } from './manager-company-detail.feature';", + "import { ManagerCompanyCreateFeature } from './manager-company-create.feature';", + "import { ManagerCompanyListFeature } from './manager-company-list.feature';", + "export default function ManagerCompanyRoutes() {", + "return useRoutes([", + "{ path: '', element: },", + "{", + "path: 'create',", + "element: ,", + "},", + "{ path: ':companyId/*', element: },", + "]);", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/src/lib/manager-company.routes.tsx", + }, + }, + "path": "libs/test/company/feature/src/lib", + }, + }, + "path": "libs/test/company/feature/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""compilerOptions": {", + ""jsx": "react-jsx",", + ""allowJs": false,", + ""esModuleInterop": false,", + ""allowSyntheticDefaultImports": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "}", + "],", + ""extends": "../../../../tsconfig.base.json"", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""types": [", + ""node",", + ""@nx/react/typings/cssmodule.d.ts",", + ""@nx/react/typings/image.d.ts"", + "]", + "},", + ""exclude": [", + ""jest.config.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.tsx",", + ""src/**/*.test.tsx",", + ""src/**/*.spec.js",", + ""src/**/*.test.js",", + ""src/**/*.spec.jsx",", + ""src/**/*.test.jsx"", + "],", + ""include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/feature/tsconfig.lib.json", + }, + }, + "path": "libs/test/company/feature", + }, + "ui": { + "children": { + ".babelrc": { + "content": [ + "{", + ""presets": [", + "[", + ""@nx/react/babel",", + "{", + ""runtime": "automatic",", + ""useBuiltIns": "usage"", + "}", + "]", + "],", + ""plugins": []", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/.babelrc", + }, + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["plugin:@nx/react", "../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-company-ui", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-company-ui\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/company/ui/README.md", + }, + "project.json": { + "content": [ + "{", + ""name": "test-company-ui",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/company/ui/src",", + ""projectType": "library",", + ""tags": ["app:test", "type:ui"],", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "}", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [ + "export * from './lib/manager-company-ui-create-form';", + "export * from './lib/manager-company-ui-table';", + "export * from './lib/manager-company-ui-update-form';", + "export * from './lib/company-ui-avatar';", + "export * from './lib/company-ui-grid';", + "export * from './lib/company-ui-grid-item';", + "export * from './lib/company-ui-info';", + "export * from './lib/company-ui-item';", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/index.ts", + }, + "lib": { + "children": { + "company-ui-avatar.tsx": { + "content": [ + "import { Company } from '@proj/sdk';", + "import { UiAvatar, UiAvatarProps } from '@pubkey-ui/core';", + "export type CompanyUiAvatarProps = UiAvatarProps & {", + "company?: Company;", + "};", + "export function CompanyUiAvatar({ company, ...props }: CompanyUiAvatarProps) {", + "return ;", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/company-ui-avatar.tsx", + }, + "company-ui-grid-item.tsx": { + "content": [ + "import { Paper } from '@mantine/core';", + "import { Company } from '@proj/sdk';", + "import { UiDebugModal, UiGroup } from '@pubkey-ui/core';", + "import { CompanyUiItem } from './company-ui-item';", + "export function CompanyUiGridItem({", + "company,", + "to,", + "}: {", + "company: Company;", + "to?: string;", + "}) {", + "return (", + "", + "", + "", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/company-ui-grid-item.tsx", + }, + "company-ui-grid.tsx": { + "content": [ + "import { Group, Pagination, SimpleGrid } from '@mantine/core';", + "import { Company } from '@proj/sdk';", + "import { gridLimits, UiPageLimit } from '@proj/test-core-ui';", + "import { UiDebugModal, UiGroup, UiStack } from '@pubkey-ui/core';", + "import { DataTableProps } from 'mantine-datatable';", + "import { CompanyUiGridItem } from './company-ui-grid-item';", + "export function CompanyUiGrid({", + "companies = [],", + "onPageChange,", + "page,", + "totalRecords,", + "limit,", + "setLimit,", + "setPage,", + "}: {", + "companies: Company[];", + "page: DataTableProps['page'];", + "totalRecords: number;", + "onPageChange: (page: number) => void;", + "limit: number;", + "setLimit: (limit: number) => void;", + "setPage: (page: number) => void;", + "}) {", + "const totalPages = totalRecords / limit + 1;", + "return (", + "", + "", + "{companies.map((company) => (", + "", + "))}", + "", + "", + "", + "", + "", + "", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/company-ui-grid.tsx", + }, + "company-ui-info.tsx": { + "content": [ + "import { Company } from '@proj/sdk';", + "import { UiInfoItems, UiInfoTable, UiTime } from '@pubkey-ui/core';", + "export function CompanyUiInfo({ company }: { company?: Company }) {", + "if (!company) return null;", + "const items: UiInfoItems = [", + "['name', company.name],", + "[", + "'Created At',", + ",", + "],", + "[", + "'Updated At',", + ",", + "],", + "];", + "return ;", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/company-ui-info.tsx", + }, + "company-ui-item.tsx": { + "content": [ + "import {", + "AvatarProps,", + "Group,", + "type GroupProps,", + "Stack,", + "Text,", + "} from '@mantine/core';", + "import { Company } from '@proj/sdk';", + "import { UiAnchor, type UiAnchorProps } from '@pubkey-ui/core';", + "import { CompanyUiAvatar } from './company-ui-avatar';", + "export function CompanyUiItem({", + "anchorProps,", + "avatarProps,", + "groupProps,", + "company,", + "to,", + "}: {", + "anchorProps?: UiAnchorProps;", + "avatarProps?: Omit;", + "groupProps?: GroupProps;", + "company?: Company;", + "to?: string | null;", + "}) {", + "if (!company) return null;", + "return (", + "", + "", + "", + "", + "", + "{company?.name}", + "", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/company-ui-item.tsx", + }, + "manager-company-ui-create-form.tsx": { + "content": [ + "import { Button, Group } from '@mantine/core';", + "import { ManagerCreateCompanyInput } from '@proj/sdk';", + "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", + "import { ReactNode } from 'react';", + "export function ManagerCompanyUiCreateForm({", + "submit,", + "}: {", + "submit: (res: ManagerCreateCompanyInput) => Promise;", + "}) {", + "const model: ManagerCreateCompanyInput = {", + "name: '',", + "location: '',", + "phone: '',", + "};", + "const fields: UiFormField[] = [", + "formFieldText('name', { label: 'name', required: true }),", + "formFieldText('location', { label: 'location', required: true }),", + "formFieldText('phone', { label: 'phone', required: true }),", + "];", + "return (", + " submit(res as ManagerCreateCompanyInput)}", + ">", + "", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/manager-company-ui-create-form.tsx", + }, + "manager-company-ui-table.tsx": { + "content": [ + "import { ActionIcon, Anchor, Group, ScrollArea } from '@mantine/core';", + "import { Company } from '@proj/sdk';", + "import { IconPencil, IconTrash } from '@tabler/icons-react';", + "import { DataTable, DataTableProps } from 'mantine-datatable';", + "import { Link } from 'react-router-dom';", + "export function ManagerCompanyUiTable({", + "deleteCompany,", + "companies = [],", + "onPageChange,", + "page,", + "recordsPerPage,", + "totalRecords,", + "}: {", + "deleteCompany: (company: Company) => void;", + "companies: Company[];", + "page: DataTableProps['page'];", + "totalRecords: DataTableProps['totalRecords'];", + "recordsPerPage: DataTableProps['recordsPerPage'];", + "onPageChange: (page: number) => void;", + "}) {", + "return (", + "", + " (", + "", + "{item.name}", + "", + "),", + "},", + "{", + "accessor: 'actions',", + "title: 'Actions',", + "textAlign: 'right',", + "render: (item) => (", + "", + "", + "", + "", + " deleteCompany(item)}", + ">", + "", + "", + "", + "),", + "},", + "]}", + "records={companies}", + "/>", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/manager-company-ui-table.tsx", + }, + "manager-company-ui-update-form.tsx": { + "content": [ + "import { Button, Group } from '@mantine/core';", + "import { ManagerUpdateCompanyInput, Company } from '@proj/sdk';", + "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", + "export function ManagerCompanyUiUpdateForm({", + "submit,", + "company,", + "}: {", + "submit: (res: ManagerUpdateCompanyInput) => Promise;", + "company: Company;", + "}) {", + "const model: ManagerUpdateCompanyInput = {", + "name: company.name ?? '',", + "location: company.location ?? '',", + "phone: company.phone ?? '',", + "};", + "const fields: UiFormField[] = [", + "formFieldText('name', { label: 'name' }),", + "formFieldText('location', { label: 'location' }),", + "formFieldText('phone', { label: 'phone' }),", + "];", + "return (", + " submit(res as ManagerUpdateCompanyInput)}", + ">", + "", + "", + "", + "", + ");", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/src/lib/manager-company-ui-update-form.tsx", + }, + }, + "path": "libs/test/company/ui/src/lib", + }, + }, + "path": "libs/test/company/ui/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""compilerOptions": {", + ""jsx": "react-jsx",", + ""allowJs": false,", + ""esModuleInterop": false,", + ""allowSyntheticDefaultImports": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "}", + "],", + ""extends": "../../../../tsconfig.base.json"", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""types": [", + ""node",", + ""@nx/react/typings/cssmodule.d.ts",", + ""@nx/react/typings/image.d.ts"", + "]", + "},", + ""exclude": [", + ""jest.config.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.tsx",", + ""src/**/*.test.tsx",", + ""src/**/*.spec.js",", + ""src/**/*.test.js",", + ""src/**/*.spec.jsx",", + ""src/**/*.test.jsx"", + "],", + ""include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]", + "}", + ], + "isBinary": false, + "path": "libs/test/company/ui/tsconfig.lib.json", + }, + }, + "path": "libs/test/company/ui", + }, + }, + "path": "libs/test/company", + }, + "core": { + "children": { + "data-access": { + "children": { + ".babelrc": { + "content": [ + "{", + ""presets": [", + "[", + ""@nx/react/babel",", + "{", + ""runtime": "automatic",", + ""useBuiltIns": "usage"", + "}", + "]", + "],", + ""plugins": []", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/.babelrc", + }, + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["plugin:@nx/react", "../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-core-data-access", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-core-data-access\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/core/data-access/README.md", + }, + "project.json": { + "content": [ + "{", + ""name": "test-core-data-access",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/core/data-access/src",", + ""projectType": "library",", + ""tags": [],", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "}", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [], + "isBinary": false, + "path": "libs/test/core/data-access/src/index.ts", + }, + }, + "path": "libs/test/core/data-access/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""compilerOptions": {", + ""jsx": "react-jsx",", + ""allowJs": false,", + ""esModuleInterop": false,", + ""allowSyntheticDefaultImports": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "}", + "],", + ""extends": "../../../../tsconfig.base.json"", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""types": [", + ""node",", + ""@nx/react/typings/cssmodule.d.ts",", + ""@nx/react/typings/image.d.ts"", + "]", + "},", + ""exclude": [", + ""jest.config.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.tsx",", + ""src/**/*.test.tsx",", + ""src/**/*.spec.js",", + ""src/**/*.test.js",", + ""src/**/*.spec.jsx",", + ""src/**/*.test.jsx"", + "],", + ""include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/data-access/tsconfig.lib.json", + }, + }, + "path": "libs/test/core/data-access", + }, + "feature": { + "children": { + ".babelrc": { + "content": [ + "{", + ""presets": [", + "[", + ""@nx/react/babel",", + "{", + ""runtime": "automatic",", + ""useBuiltIns": "usage"", + "}", + "]", + "],", + ""plugins": []", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/.babelrc", + }, + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["plugin:@nx/react", "../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-core-feature", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-core-feature\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/core/feature/README.md", + }, + "project.json": { + "content": [ + "{", + ""name": "test-core-feature",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/core/feature/src",", + ""projectType": "library",", + ""tags": [],", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "}", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [], + "isBinary": false, + "path": "libs/test/core/feature/src/index.ts", + }, + "lib": { + "children": { + "test-core-feature.tsx": { + "content": [ + "/* eslint-disable-next-line */", + "export interface TestCoreFeatureProps {}", + "export function TestCoreFeature(props: TestCoreFeatureProps) {", + "return (", + "
", + "

Welcome to TestCoreFeature!

", + "
", + ");", + "}", + "export default TestCoreFeature;", + ], + "isBinary": false, + "path": "libs/test/core/feature/src/lib/test-core-feature.tsx", + }, + "test-core-routes-admin.tsx": { + "content": [ + "/* eslint-disable-next-line */", + "export interface TestCoreRoutesAdminProps {}", + "export function TestCoreRoutesAdmin(props: TestCoreRoutesAdminProps) {", + "return (", + "
", + "

Welcome to TestCoreRoutesAdmin!

", + "
", + ");", + "}", + "export default TestCoreRoutesAdmin;", + ], + "isBinary": false, + "path": "libs/test/core/feature/src/lib/test-core-routes-admin.tsx", + }, + "test-core-routes-manager.tsx": { + "content": [ + "import { IconBuilding } from '@tabler/icons-react';", + "import { ManagerCompanyFeature } from '@proj/test-company-feature';", + "/* eslint-disable-next-line */", + "export interface TestCoreRoutesManagerProps {}", + "export function TestCoreRoutesManager(props: TestCoreRoutesManagerProps) {", + "return (", + "
", + "

Welcome to TestCoreRoutesManager!

", + "
", + ");", + "}", + "export default TestCoreRoutesManager;", + ], + "isBinary": false, + "path": "libs/test/core/feature/src/lib/test-core-routes-manager.tsx", + }, + "test-core-routes-user.tsx": { + "content": [ + "/* eslint-disable-next-line */", + "export interface TestCoreRoutesUserProps {}", + "export function TestCoreRoutesUser(props: TestCoreRoutesUserProps) {", + "return (", + "
", + "

Welcome to TestCoreRoutesUser!

", + "
", + ");", + "}", + "export default TestCoreRoutesUser;", + ], + "isBinary": false, + "path": "libs/test/core/feature/src/lib/test-core-routes-user.tsx", + }, + "test-core-routes.tsx": { + "content": [ + "/* eslint-disable-next-line */", + "export interface TestCoreRoutesProps {}", + "export function TestCoreRoutes(props: TestCoreRoutesProps) {", + "return (", + "
", + "

Welcome to TestCoreRoutes!

", + "
", + ");", + "}", + "export default TestCoreRoutes;", + ], + "isBinary": false, + "path": "libs/test/core/feature/src/lib/test-core-routes.tsx", + }, + }, + "path": "libs/test/core/feature/src/lib", + }, + }, + "path": "libs/test/core/feature/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""compilerOptions": {", + ""jsx": "react-jsx",", + ""allowJs": false,", + ""esModuleInterop": false,", + ""allowSyntheticDefaultImports": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "}", + "],", + ""extends": "../../../../tsconfig.base.json"", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""types": [", + ""node",", + ""@nx/react/typings/cssmodule.d.ts",", + ""@nx/react/typings/image.d.ts"", + "]", + "},", + ""exclude": [", + ""jest.config.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.tsx",", + ""src/**/*.test.tsx",", + ""src/**/*.spec.js",", + ""src/**/*.test.js",", + ""src/**/*.spec.jsx",", + ""src/**/*.test.jsx"", + "],", + ""include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]", + "}", + ], + "isBinary": false, + "path": "libs/test/core/feature/tsconfig.lib.json", + }, + }, + "path": "libs/test/core/feature", + }, + }, + "path": "libs/test/core", + }, +} +`; diff --git a/libs/tools/src/generators/web-crud/web-crud-generator.spec.ts b/libs/tools/src/generators/web-crud/web-crud-generator.spec.ts index ecc9337..671e0e0 100644 --- a/libs/tools/src/generators/web-crud/web-crud-generator.spec.ts +++ b/libs/tools/src/generators/web-crud/web-crud-generator.spec.ts @@ -1,8 +1,12 @@ import { readProjectConfiguration, Tree } from '@nx/devkit' import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing' import { createMockWebApp } from '../../lib/web' -import webFeatureGenerator from '../web-feature/web-feature-generator' +import { apiFeatureGenerator } from '../api-feature/api-feature-generator' +import { webFeatureGenerator } from '../web-feature/web-feature-generator' import { WebCrudGeneratorSchema } from './web-crud-schema' +import { webCrudGenerator } from './web-crud-generator' +import { getRecursiveFileContents } from '../../lib/utils/get-recursive-file-contents' +import { createMockApiApp } from '../../lib/api/create-mock-api-app' describe('web-crud generator', () => { let tree: Tree @@ -11,6 +15,8 @@ describe('web-crud generator', () => { beforeEach(async () => { tree = createTreeWithEmptyWorkspace() + await createMockApiApp(tree, 'api') + await apiFeatureGenerator(tree, { app: 'api', model: options.model }) await createMockWebApp(tree, options.app) await webFeatureGenerator(tree, { app: options.app, model: options.model }) }) @@ -20,4 +26,41 @@ describe('web-crud generator', () => { const config = readProjectConfiguration(tree, options.app) expect(config).toBeDefined() }) + + it('should create crud with modelParentId', async () => { + await webCrudGenerator(tree, { ...options, modelParent: 'User', modelParentId: 'ownerId' }) + const config = readProjectConfiguration(tree, 'test') + expect(config).toBeDefined() + + const contents = getRecursiveFileContents({ + tree, + path: 'libs/test', + }) + expect(contents).toMatchSnapshot() + }) + + it('should create crud with modelOwnerId', async () => { + await webCrudGenerator(tree, { ...options, modelOwnerId: 'ownerId' }) + const config = readProjectConfiguration(tree, 'test') + expect(config).toBeDefined() + + const contents = getRecursiveFileContents({ + tree, + path: 'libs/test', + }) + expect(contents).toMatchSnapshot() + }) + + it('should create crud with modelOwnerId for admin and user', async () => { + await webCrudGenerator(tree, { ...options, modelOwnerId: 'ownerId', actor: 'user' }) + await webCrudGenerator(tree, { ...options, modelOwnerId: 'ownerId', actor: 'admin' }) + const config = readProjectConfiguration(tree, 'test') + expect(config).toBeDefined() + + const contents = getRecursiveFileContents({ + tree, + path: 'libs/test', + }) + expect(contents).toMatchSnapshot() + }) }) diff --git a/libs/tools/src/generators/web-crud/web-crud-schema.d.ts b/libs/tools/src/generators/web-crud/web-crud-schema.d.ts index bef035d..b66ef45 100644 --- a/libs/tools/src/generators/web-crud/web-crud-schema.d.ts +++ b/libs/tools/src/generators/web-crud/web-crud-schema.d.ts @@ -22,4 +22,16 @@ export interface WebCrudGeneratorSchema { * The name of the model for this feature. */ model: string + /** + * The id field linked to the User model for this feature. Generally 'userId' or 'ownerId'. + */ + modelOwnerId?: string + /** + * The id field of the parent model for this feature. + */ + modelParentId?: string + /** + * The name of the parent model for this feature. + */ + modelParent?: string } diff --git a/libs/tools/src/generators/web-crud/web-crud-schema.json b/libs/tools/src/generators/web-crud/web-crud-schema.json index 7eb0bc2..4863960 100644 --- a/libs/tools/src/generators/web-crud/web-crud-schema.json +++ b/libs/tools/src/generators/web-crud/web-crud-schema.json @@ -25,6 +25,18 @@ "type": "string", "description": "The name of the model for this feature.", "x-prompt": "What is the name of the model for this feature?" + }, + "modelOwnerId": { + "type": "string", + "description": "The id field linked to the User model for this feature. Generally 'userId' or 'ownerId'." + }, + "modelParentId": { + "type": "string", + "description": "The id field of the parent model for this feature." + }, + "modelParent": { + "type": "string", + "description": "The name of the parent model for this feature." } }, "required": ["app", "actor", "model"] diff --git a/libs/tools/src/generators/web-feature/__snapshots__/web-feature-generator.spec.ts.snap b/libs/tools/src/generators/web-feature/__snapshots__/web-feature-generator.spec.ts.snap index 157aaf0..0b68496 100644 --- a/libs/tools/src/generators/web-feature/__snapshots__/web-feature-generator.spec.ts.snap +++ b/libs/tools/src/generators/web-feature/__snapshots__/web-feature-generator.spec.ts.snap @@ -21,7 +21,9 @@ import { toastError, toastSuccess } from '@pubkey-ui/core'; import { useQuery } from '@tanstack/react-query'; import { useState } from 'react'; -export function useAdminFindManyTest(props?: Partial) { +export function useAdminFindManyTest( + props: Partial = {} +) { const sdk = useSdk(); const [limit, setLimit] = useState(props?.limit ?? 10); const [page, setPage] = useState(props?.page ?? 1); @@ -119,7 +121,9 @@ import { toastError, toastSuccess } from '@pubkey-ui/core'; import { useQuery } from '@tanstack/react-query'; import { useState } from 'react'; -export function useUserFindManyTest(props?: Partial) { +export function useUserFindManyTest( + props: Partial = {} +) { const sdk = useSdk(); const [limit, setLimit] = useState(props?.limit ?? 10); const [page, setPage] = useState(props?.page ?? 1); diff --git a/libs/tools/src/generators/web-feature/web-feature-schema.d.ts b/libs/tools/src/generators/web-feature/web-feature-schema.d.ts index dc8464a..76eec91 100644 --- a/libs/tools/src/generators/web-feature/web-feature-schema.d.ts +++ b/libs/tools/src/generators/web-feature/web-feature-schema.d.ts @@ -10,6 +10,18 @@ export interface WebFeatureGeneratorSchema { * The name of the model for this feature. */ model: string + /** + * The id field linked to the User model for this feature. Generally 'userId' or 'ownerId'. + */ + modelOwnerId?: string + /** + * The id field of the parent model for this feature. + */ + modelParentId?: string + /** + * The name of the parent model for this feature. + */ + modelParent?: string /** * The name of the application you are adding the feature to. */ diff --git a/libs/tools/src/generators/web-feature/web-feature-schema.json b/libs/tools/src/generators/web-feature/web-feature-schema.json index a37e053..fdecc82 100644 --- a/libs/tools/src/generators/web-feature/web-feature-schema.json +++ b/libs/tools/src/generators/web-feature/web-feature-schema.json @@ -13,6 +13,18 @@ "index": 0 } }, + "modelOwnerId": { + "type": "string", + "description": "The id field linked to the User model for this feature. Generally 'userId' or 'ownerId'." + }, + "modelParentId": { + "type": "string", + "description": "The id field of the parent model for this feature." + }, + "modelParent": { + "type": "string", + "description": "The name of the parent model for this feature." + }, "app": { "type": "string", "description": "The name of the application you are adding the feature to.", diff --git a/libs/tools/src/lib/web-crud/files/data-access/lib/use-__actorFileName__-find-many-__modelFileName__.ts.template b/libs/tools/src/lib/web-crud/files/data-access/lib/use-__actorFileName__-find-many-__modelFileName__.ts.template index 02e0805..7d73703 100644 --- a/libs/tools/src/lib/web-crud/files/data-access/lib/use-__actorFileName__-find-many-__modelFileName__.ts.template +++ b/libs/tools/src/lib/web-crud/files/data-access/lib/use-__actorFileName__-find-many-__modelFileName__.ts.template @@ -4,13 +4,13 @@ import { toastError, toastSuccess } from '@pubkey-ui/core' import { useQuery } from '@tanstack/react-query' import { useState } from 'react' -export function use<%= actor.className %>FindMany<%= model.className %>(props?: Partial<<%= actor.className %>FindMany<%= model.className %>Input>) { +export function use<%= actor.className %>FindMany<%= model.className %>(props: Partial<<%= actor.className %>FindMany<%= model.className %>Input><% if(ownerId && actor.className === 'Admin'){ %> & { <%= ownerId %>: string } <% } else { %> = {} <% } %> ) { const sdk = useSdk() const [limit, setLimit] = useState(props?.limit ?? 10) const [page, setPage] = useState(props?.page ?? 1) const [search, setSearch] = useState(props?.search ?? '') - const input: <%= actor.className %>FindMany<%= model.className %>Input = { page, limit, search } + const input: <%= actor.className %>FindMany<%= model.className %>Input = { page, limit, search<% if(ownerId && actor.className === 'Admin'){ %>, <%= ownerId %>: props.<%= ownerId %> <% } %> } const query = useQuery({ queryKey: ['<%= actor.propertyName %>', 'find-many-<%= model.fileName %>', input], queryFn: () => sdk.<%= actor.propertyName %>FindMany<%= model.className %>({ input }).then((res) => res.data), @@ -31,7 +31,7 @@ export function use<%= actor.className %>FindMany<%= model.className %>(props?: setSearch, create<%= model.className %>: (input: <%= actor.className %>Create<%= model.className %>Input) => sdk - .<%= actor.propertyName %>Create<%= model.className %>({ input }) + .<%= actor.propertyName %>Create<%= model.className %>({ input<% if(ownerId && actor.className === 'Admin'){ %>: { ...input, <%= ownerId %>: props.<%= ownerId %> } <% } %> }) .then((res) => res.data) .then((res) => { if (res.created) { diff --git a/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-create.feature.tsx.template b/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-create.feature.tsx.template index 3f4e167..f139d1f 100644 --- a/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-create.feature.tsx.template +++ b/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-create.feature.tsx.template @@ -4,9 +4,9 @@ import { <%= actor.className %><%= model.className %>UiCreateForm } from '@<%= n import { toastError, UiBack, UiCard, UiPage } from '@pubkey-ui/core' import { useNavigate } from 'react-router-dom' -export function <%= actor.className %><%= model.className %>CreateFeature() { +export function <%= actor.className %><%= model.className %>CreateFeature(<% if(ownerId && actor.className === 'Admin'){ %>{ <%= ownerId %> }: { <%= ownerId %>: string } <% } %>) { const navigate = useNavigate() - const { create<%= model.className %> } = use<%= actor.className %>FindMany<%= model.className %>() + const { create<%= model.className %> } = use<%= actor.className %>FindMany<%= model.className %>(<% if(ownerId && actor.className === 'Admin'){ %>{ <%= ownerId %> }<% } %>) async function submit(input: <%= actor.className %>Create<%= model.className %>Input) { return create<%= model.className %>(input) diff --git a/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-list.feature.tsx.template b/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-list.feature.tsx.template index d3329b9..f90e7c6 100644 --- a/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-list.feature.tsx.template +++ b/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-list.feature.tsx.template @@ -2,15 +2,19 @@ import { Button, Group } from '@mantine/core' import { UiPageLimit, UiSearchField } from '@<%= npmScope %>/<%= app.fileName %>-core-ui' import { use<%= actor.className %>FindMany<%= model.className %> } from '@<%= npmScope %>/<%= app.fileName %>-<%= model.fileName %>-data-access' import { <% if(actorAdmin){ %><%= actor.className %><%= model.className %>UiTable<% } else { %><%= model.className %>UiGrid<% } %> } from '@<%= npmScope %>/<%= app.fileName %>-<%= model.fileName %>-ui' -import { UiBack, UiDebugModal, UiInfo, UiLoader, UiPage } from '@pubkey-ui/core' +import { UiBack, UiDebugModal, UiInfo, UiLoader, <% if(ownerId && actor.className === 'Admin'){ %>UiStack<% } else { %>UiPage<% } %> } from '@pubkey-ui/core' import { Link } from 'react-router-dom' -export function <%= actor.className %><%= model.className %>ListFeature() { +export function <%= actor.className %><%= model.className %>ListFeature(<% if(ownerId && actor.className === 'Admin'){ %>{ <%= ownerId %> }: { <%= ownerId %>: string } <% } %>) { const { delete<%= model.className %>, items, pagination, query, setSearch } = use<%= actor.className %>FindMany<%= model.className %>({ limit: <% if(actorAdmin){ %>10<% } else { %>12<% } %>, + <% if(ownerId && actor.className === 'Admin'){ %><%= ownerId %>,<% } %> }) return ( + <% if(ownerId && actor.className === 'Admin'){ %> + + <% } else { %> } @@ -23,9 +27,16 @@ export function <%= actor.className %><%= model.className %>ListFeature() { } > + <% } %> <% if(actorAdmin){ %><% } %> + <% if(ownerId && actor.className === 'Admin'){ %> + + + <% } %> {query.isLoading ? ( @@ -52,6 +63,10 @@ export function <%= actor.className %><%= model.className %>ListFeature() { />)<% } %> : ( )} + <% if(ownerId && actor.className === 'Admin'){ %> + + <% } else { %> + <% } %> ) } diff --git a/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__.routes.tsx.template b/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__.routes.tsx.template index 455de54..04115ee 100644 --- a/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__.routes.tsx.template +++ b/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__.routes.tsx.template @@ -3,12 +3,12 @@ import { <%= actor.className %><%= model.className %>DetailFeature } from './<%= import { <%= actor.className %><%= model.className %>CreateFeature } from './<%= actor.propertyName %>-<%= model.fileName %>-create.feature' import { <%= actor.className %><%= model.className %>ListFeature } from './<%= actor.propertyName %>-<%= model.fileName %>-list.feature' -export default function <%= actor.className %><%= model.className %>Routes() { +export default function <%= actor.className %><%= model.className %>Routes(<% if(ownerId && actor.className === 'Admin'){ %>{ <%= ownerId %> }: { <%= ownerId %>: string } <% } %>) { return useRoutes([ - { path: '', element: <<%= actor.className %><%= model.className %>ListFeature /> }, + { path: '', element: <<%= actor.className %><%= model.className %>ListFeature <% if(ownerId && actor.className === 'Admin'){ %><%= ownerId %>={<%= ownerId %>}<% } %> /> }, { path: 'create', - element: <<%= actor.className %><%= model.className %>CreateFeature />, + element: <<%= actor.className %><%= model.className %>CreateFeature <% if(ownerId && actor.className === 'Admin'){ %><%= ownerId %>={<%= ownerId %>}<% } %> />, }, { path: ':<%= model.propertyName %>Id/*', element: <<%= actor.className %><%= model.className %>DetailFeature /> }, ]) diff --git a/libs/tools/src/lib/web-crud/files/ui/lib/__actorFileName__-__modelFileName__-ui-create-form.tsx.template b/libs/tools/src/lib/web-crud/files/ui/lib/__actorFileName__-__modelFileName__-ui-create-form.tsx.template index e143798..4864c98 100644 --- a/libs/tools/src/lib/web-crud/files/ui/lib/__actorFileName__-__modelFileName__-ui-create-form.tsx.template +++ b/libs/tools/src/lib/web-crud/files/ui/lib/__actorFileName__-__modelFileName__-ui-create-form.tsx.template @@ -8,12 +8,18 @@ export function <%= actor.className %><%= model.className %>UiCreateForm({ submi <% for (let field of fields){ %> <%= field.name %>: '', <% } %> + <% if(ownerId && actor.className === 'Admin'){ %> + <%= ownerId %>: '', + <% } %> } const fields: UiFormField<<%= actor.className %>Create<%= model.className %>Input>[] = [ <% for (let field of fields){ %> formFieldText('<%= field.name %>', { label: '<%= field.name %>', required: true, }), <% } %> + <% if(ownerId && actor.className === 'Admin'){ %> + formFieldText('<%= ownerId %>', { label: '<%= ownerId %>', required: true, }), + <% } %> ] return ( submit(res as <%= actor.className %>Create<%= model.className %>Input)}> diff --git a/libs/tools/src/lib/web-crud/get-web-crud-substitutions.ts b/libs/tools/src/lib/web-crud/get-web-crud-substitutions.ts index 08972bb..3058ec6 100644 --- a/libs/tools/src/lib/web-crud/get-web-crud-substitutions.ts +++ b/libs/tools/src/lib/web-crud/get-web-crud-substitutions.ts @@ -20,6 +20,12 @@ export function getWebCrudSubstitutions(options: NormalizedApiCrudSchema) { model, modelFileName: model.fileName, modelPropertyNamePlural: plural.propertyName, + owner: options.modelOwner ? names(options.modelOwner) : undefined, + ownerId: options.modelOwnerId, + ownerPropertyId: options.modelOwnerId?.replace('Id', ''), + parent: options.modelParent ? names(options.modelParent) : undefined, + parentId: options.modelParentId, + parentPropertyId: options.modelParentId?.replace('Id', ''), npmScope: options.npmScope, plural, } diff --git a/libs/tools/src/lib/web-crud/normalize-web-crud-schema.ts b/libs/tools/src/lib/web-crud/normalize-web-crud-schema.ts index 6984fe0..1ee7e70 100644 --- a/libs/tools/src/lib/web-crud/normalize-web-crud-schema.ts +++ b/libs/tools/src/lib/web-crud/normalize-web-crud-schema.ts @@ -6,6 +6,11 @@ import { NormalizedWebCrudGeneratorSchema } from './normalized-web-crud-generato export function normalizeWebCrudSchema(tree: Tree, schema: WebCrudGeneratorSchema): NormalizedWebCrudGeneratorSchema { const npmScope = getNpmScope(tree) + const modelOwnerId = schema.modelOwnerId ?? undefined + const modelOwnerProperty = modelOwnerId?.replace('Id', '') + const modelParent = schema.modelParent ?? undefined + const modelParentId = schema.modelParentId ?? undefined + const modelParentProperty = modelParentId?.replace('Id', '') const fields = getPrismaModelFields(tree, schema.model) ?? [{ name: 'name', type: 'string', optional: false }] return { @@ -13,7 +18,14 @@ export function normalizeWebCrudSchema(tree: Tree, schema: WebCrudGeneratorSchem actor: schema.actor, label: schema.label ?? 'name', model: schema.model, + modelOwner: schema.modelOwnerId ? 'User' : undefined, + modelOwnerId, + modelOwnerProperty, + modelParent, + modelParentId, npmScope, - fields, + fields: fields.filter( + (f) => ![modelOwnerId, modelOwnerProperty, modelParentId, modelParentProperty].includes(f.name), + ), } } diff --git a/libs/tools/src/lib/web-crud/normalized-web-crud-generator-schema.ts b/libs/tools/src/lib/web-crud/normalized-web-crud-generator-schema.ts index 248e602..6320e75 100644 --- a/libs/tools/src/lib/web-crud/normalized-web-crud-generator-schema.ts +++ b/libs/tools/src/lib/web-crud/normalized-web-crud-generator-schema.ts @@ -5,4 +5,6 @@ export interface NormalizedWebCrudGeneratorSchema extends WebCrudGeneratorSchema label: string npmScope: string fields?: PrismaModelField[] + modelOwner: string + modelOwnerProperty: string } diff --git a/libs/tools/src/lib/web/create-mock-web-app.ts b/libs/tools/src/lib/web/create-mock-web-app.ts index 5107258..ae06e92 100644 --- a/libs/tools/src/lib/web/create-mock-web-app.ts +++ b/libs/tools/src/lib/web/create-mock-web-app.ts @@ -38,9 +38,10 @@ export async function createMockWebApp(tree: Tree, app: string) { await createMockComponent(tree, `${app}-core-feature`, `${app}-core-feature`) // Create the core routes libs - await createMockComponent(tree, `${app}-core-feature`, `web-core-routes`) - await createMockComponent(tree, `${app}-core-feature`, `web-core-routes-admin`) - await createMockComponent(tree, `${app}-core-feature`, `web-core-routes-user`) + await createMockComponent(tree, `${app}-core-feature`, `${app}-core-routes`) + await createMockComponent(tree, `${app}-core-feature`, `${app}-core-routes-admin`) + await createMockComponent(tree, `${app}-core-feature`, `${app}-core-routes-user`) + await createMockComponent(tree, `${app}-core-feature`, `${app}-core-routes-manager`) } function createMockComponent(tree: Tree, project: string, name: string) { diff --git a/libs/tools/src/lib/web/normalize-web-feature-schema.ts b/libs/tools/src/lib/web/normalize-web-feature-schema.ts index 4a1898f..5e5202c 100644 --- a/libs/tools/src/lib/web/normalize-web-feature-schema.ts +++ b/libs/tools/src/lib/web/normalize-web-feature-schema.ts @@ -12,6 +12,10 @@ export function normalizeWebFeatureSchema(tree: Tree, schema: WebFeatureGenerato label: schema.label ?? 'name', crud: schema.crud?.length ? schema.crud.split(',') : [], model, + modelOwner: schema.modelOwnerId ? 'User' : undefined, + modelOwnerId: schema.modelOwnerId ?? undefined, + modelParent: schema.modelParent ?? undefined, + modelParentId: schema.modelParentId ?? undefined, npmScope, skipDataAccess: schema.skipDataAccess ?? false, skipFeature: schema.skipFeature ?? false, diff --git a/libs/tools/src/lib/web/normalized-web-feature-schema.ts b/libs/tools/src/lib/web/normalized-web-feature-schema.ts index 46e49c4..152d757 100644 --- a/libs/tools/src/lib/web/normalized-web-feature-schema.ts +++ b/libs/tools/src/lib/web/normalized-web-feature-schema.ts @@ -1,8 +1,11 @@ -export interface NormalizedWebFeatureSchema { +import { WebFeatureGeneratorSchema } from '../../generators/web-feature/web-feature-schema' + +export interface NormalizedWebFeatureSchema extends Omit { app: string crud: string[] label: string model: string + modelOwner: string npmScope: string skipDataAccess: boolean skipFeature: boolean From ce04db46b352e6e91046ee1ced068396ef2284c9 Mon Sep 17 00:00:00 2001 From: Bram Borggreve Date: Sat, 16 Mar 2024 05:57:29 +0000 Subject: [PATCH 06/12] feat: improve support for ownerId in web generator --- .../api-crud-generator.spec.ts.snap | 2 + .../web-crud-generator.spec.ts.snap | 788 ++++++++++++++---- .../web-crud/web-crud-generator.spec.ts | 6 +- .../web-feature-generator.spec.ts.snap | 72 +- .../web-feature/web-feature-generator.spec.ts | 2 +- .../add-service-to-class-constructor.ts | 2 +- .../add-service-to-module-decorator.ts | 2 +- .../src/lib/api-crud/generate-api-crud.ts | 2 +- .../src/lib/api-crud/generate-sdk-file.ts | 11 +- .../lib/api/api-update-core-feature-module.ts | 4 +- .../lib/api/generate-api-lib-data-access.ts | 2 +- .../src/lib/api/generate-api-lib-feature.ts | 2 +- libs/tools/src/lib/utils/add-array-item.ts | 14 - .../utils/ast/add-array-item-in-function.ts | 23 + .../tools/src/lib/utils/ast/add-array-item.ts | 13 + .../lib/utils/{ => ast}/add-constructors.ts | 0 .../src/lib/utils/{ => ast}/add-export.ts | 0 .../lib/utils/{ => ast}/add-named-import.ts | 0 libs/tools/src/lib/utils/ast/get-array.ts | 5 + .../lib/utils/{ => ast}/get-decorator-args.ts | 0 .../lib/utils/{ => ast}/get-source-file.ts | 0 .../lib/utils/{ => ast}/update-source-file.ts | 0 ...odelFileName__-create.feature.tsx.template | 9 +- ...odelFileName__-detail.feature.tsx.template | 43 +- ..._modelFileName__-list.feature.tsx.template | 2 +- ...odelFileName__-ui-create-form.tsx.template | 3 - .../src/lib/web-crud/generate-web-crud.ts | 72 +- libs/tools/src/lib/web/create-mock-web-app.ts | 51 +- .../src/lib/admin-user-detail-feature.tsx | 29 +- 29 files changed, 878 insertions(+), 281 deletions(-) delete mode 100644 libs/tools/src/lib/utils/add-array-item.ts create mode 100644 libs/tools/src/lib/utils/ast/add-array-item-in-function.ts create mode 100644 libs/tools/src/lib/utils/ast/add-array-item.ts rename libs/tools/src/lib/utils/{ => ast}/add-constructors.ts (100%) rename libs/tools/src/lib/utils/{ => ast}/add-export.ts (100%) rename libs/tools/src/lib/utils/{ => ast}/add-named-import.ts (100%) create mode 100644 libs/tools/src/lib/utils/ast/get-array.ts rename libs/tools/src/lib/utils/{ => ast}/get-decorator-args.ts (100%) rename libs/tools/src/lib/utils/{ => ast}/get-source-file.ts (100%) rename libs/tools/src/lib/utils/{ => ast}/update-source-file.ts (100%) diff --git a/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap b/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap index e4f2fb3..37f923f 100644 --- a/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap +++ b/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap @@ -1158,6 +1158,7 @@ exports[`api-crud generator should create crud with modelOwnerId 1`] = ` "name", "location", "phone", + "ownerId", "updatedAt", "}", "query adminFindManyCompany($input: AdminFindManyCompanyInput!) {", @@ -2658,6 +2659,7 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "name", "location", "phone", + "ownerId", "updatedAt", "}", "query userFindManyCompany($input: UserFindManyCompanyInput!) {", diff --git a/libs/tools/src/generators/web-crud/__snapshots__/web-crud-generator.spec.ts.snap b/libs/tools/src/generators/web-crud/__snapshots__/web-crud-generator.spec.ts.snap index b011fd0..b3b29f0 100644 --- a/libs/tools/src/generators/web-crud/__snapshots__/web-crud-generator.spec.ts.snap +++ b/libs/tools/src/generators/web-crud/__snapshots__/web-crud-generator.spec.ts.snap @@ -440,6 +440,7 @@ exports[`web-crud generator should create crud with modelOwnerId 1`] = ` "UiError,", "UiLoader,", "UiPage,", + "UiTabRoute,", "UiTabRoutes,", "} from '@pubkey-ui/core';", "import { useManagerFindOneCompany } from '@proj/test-company-data-access';", @@ -458,18 +459,7 @@ exports[`web-crud generator should create crud with modelOwnerId 1`] = ` "if (!item) {", "return ;", "}", - "return (", - "}", - "leftAction={}", - "rightAction={", - "", - "", - "", - "}", - ">", - ",", "},", - "]}", - "/>", + "];", + "return (", + "}", + "leftAction={}", + "rightAction={", + "", + "", + "", + "}", + ">", + "", "", ");", "}", @@ -504,8 +504,7 @@ exports[`web-crud generator should create crud with modelOwnerId 1`] = ` "} from '@pubkey-ui/core';", "import { Link } from 'react-router-dom';", "export function ManagerCompanyListFeature() {", - "const { deleteCompany, items, pagination, query, setSearch } =", - "useManagerFindManyCompany({", + "const { items, pagination, query, setSearch } = useManagerFindManyCompany({", "limit: 12,", "});", "return (", @@ -1338,16 +1337,12 @@ exports[`web-crud generator should create crud with modelOwnerId 1`] = ` }, "test-core-routes-admin.tsx": { "content": [ - "/* eslint-disable-next-line */", - "export interface TestCoreRoutesAdminProps {}", - "export function TestCoreRoutesAdmin(props: TestCoreRoutesAdminProps) {", - "return (", - "
", - "

Welcome to TestCoreRoutesAdmin!

", - "
", - ");", + "import { RouteObject, useRoutes } from 'react-router-dom';", + "const links = [];", + "const routes = [];", + "export default function () {", + "return useRoutes(routes);", "}", - "export default TestCoreRoutesAdmin;", ], "isBinary": false, "path": "libs/test/core/feature/src/lib/test-core-routes-admin.tsx", @@ -1355,33 +1350,25 @@ exports[`web-crud generator should create crud with modelOwnerId 1`] = ` "test-core-routes-manager.tsx": { "content": [ "import { IconBuilding } from '@tabler/icons-react';", + "import { RouteObject, useRoutes } from 'react-router-dom';", "import { ManagerCompanyFeature } from '@proj/test-company-feature';", - "/* eslint-disable-next-line */", - "export interface TestCoreRoutesManagerProps {}", - "export function TestCoreRoutesManager(props: TestCoreRoutesManagerProps) {", - "return (", - "
", - "

Welcome to TestCoreRoutesManager!

", - "
", - ");", + "const links = [{ label: 'Companies', icon: IconBuilding, to: '/companies' }];", + "const routes = [{ path: '/companies/*', element: }];", + "export default function () {", + "return useRoutes(routes);", "}", - "export default TestCoreRoutesManager;", ], "isBinary": false, "path": "libs/test/core/feature/src/lib/test-core-routes-manager.tsx", }, "test-core-routes-user.tsx": { "content": [ - "/* eslint-disable-next-line */", - "export interface TestCoreRoutesUserProps {}", - "export function TestCoreRoutesUser(props: TestCoreRoutesUserProps) {", - "return (", - "
", - "

Welcome to TestCoreRoutesUser!

", - "
", - ");", + "import { RouteObject, useRoutes } from 'react-router-dom';", + "const links = [];", + "const routes = [];", + "export default function () {", + "return useRoutes(routes);", "}", - "export default TestCoreRoutesUser;", ], "isBinary": false, "path": "libs/test/core/feature/src/lib/test-core-routes-user.tsx", @@ -1465,6 +1452,175 @@ exports[`web-crud generator should create crud with modelOwnerId 1`] = ` }, "path": "libs/test/core", }, + "user": { + "children": { + "feature": { + "children": { + ".babelrc": { + "content": [ + "{", + ""presets": [", + "[", + ""@nx/react/babel",", + "{", + ""runtime": "automatic",", + ""useBuiltIns": "usage"", + "}", + "]", + "],", + ""plugins": []", + "}", + ], + "isBinary": false, + "path": "libs/test/user/feature/.babelrc", + }, + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["plugin:@nx/react", "../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/user/feature/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-user-feature", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-user-feature\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/user/feature/README.md", + }, + "project.json": { + "content": [ + "{", + ""name": "test-user-feature",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/user/feature/src",", + ""projectType": "library",", + ""tags": [],", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "}", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/user/feature/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [], + "isBinary": false, + "path": "libs/test/user/feature/src/index.ts", + }, + "lib": { + "children": { + "admin-user-detail-feature.tsx": { + "content": [ + "export function AdminUserDetailFeature() {", + "const { userId } = useParams<{ userId: string }>() as { userId: string };", + "const tabs = [", + "{", + "path: 'settings',", + "label: 'Settings',", + "element: ,", + "},", + "{", + "path: 'identities',", + "label: 'Identities',", + "element: ,", + "},", + "];", + "return ;", + "}", + ], + "isBinary": false, + "path": "libs/test/user/feature/src/lib/admin-user-detail-feature.tsx", + }, + }, + "path": "libs/test/user/feature/src/lib", + }, + }, + "path": "libs/test/user/feature/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""compilerOptions": {", + ""jsx": "react-jsx",", + ""allowJs": false,", + ""esModuleInterop": false,", + ""allowSyntheticDefaultImports": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "}", + "],", + ""extends": "../../../../tsconfig.base.json"", + "}", + ], + "isBinary": false, + "path": "libs/test/user/feature/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""types": [", + ""node",", + ""@nx/react/typings/cssmodule.d.ts",", + ""@nx/react/typings/image.d.ts"", + "]", + "},", + ""exclude": [", + ""jest.config.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.tsx",", + ""src/**/*.test.tsx",", + ""src/**/*.spec.js",", + ""src/**/*.test.js",", + ""src/**/*.spec.jsx",", + ""src/**/*.test.jsx"", + "],", + ""include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]", + "}", + ], + "isBinary": false, + "path": "libs/test/user/feature/tsconfig.lib.json", + }, + }, + "path": "libs/test/user/feature", + }, + }, + "path": "libs/test/user", + }, } `; @@ -1576,7 +1732,8 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "const input: AdminFindManyCompanyInput = {", "page,", "limit,", - "searchownerId: props.ownerId,", + "search,", + "ownerId: props.ownerId,", "};", "const query = useQuery({", "queryKey: ['admin', 'find-many-company', input],", @@ -1918,11 +2075,12 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "import { AdminCreateCompanyInput } from '@proj/sdk';", "import { useAdminFindManyCompany } from '@proj/test-company-data-access';", "import { AdminCompanyUiCreateForm } from '@proj/test-company-ui';", - "import { toastError, UiBack, UiCard, UiPage } from '@pubkey-ui/core';", + "import { toastError, UiBack, UiCard } from '@pubkey-ui/core';", "import { useNavigate } from 'react-router-dom';", + "import { Group, Text } from '@mantine/core';", "export function AdminCompanyCreateFeature({ ownerId }: { ownerId: string }) {", "const navigate = useNavigate();", - "const { createCompany } = useAdminFindManyCompany(ownerId);", + "const { createCompany } = useAdminFindManyCompany({ ownerId });", "async function submit(input: AdminCreateCompanyInput) {", "return createCompany(input)", ".then((res) => {", @@ -1937,11 +2095,18 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "});", "}", "return (", - "} title="Create Company">", - "", + "", + "", + "", + "Create Company", + "", + "", + "}", + ">", "", "", - "", ");", "}", ], @@ -2010,7 +2175,8 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "UiDebugModal,", "UiError,", "UiLoader,", - "UiPage,", + "UiStack,", + "UiTabRoute,", "UiTabRoutes,", "} from '@pubkey-ui/core';", "import { useAdminFindOneCompany } from '@proj/test-company-data-access';", @@ -2029,18 +2195,7 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "if (!item) {", "return ;", "}", - "return (", - "}", - "leftAction={}", - "rightAction={", - "", - "", - "", - "}", - ">", - ",", "},", - "]}", - "/>", - "", + "];", + "return (", + "", + "", + "", + "", + "", + "", + "", + "", ");", "}", ], @@ -2232,6 +2394,7 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "UiError,", "UiLoader,", "UiPage,", + "UiTabRoute,", "UiTabRoutes,", "} from '@pubkey-ui/core';", "import { useUserFindOneCompany } from '@proj/test-company-data-access';", @@ -2250,18 +2413,7 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "if (!item) {", "return ;", "}", - "return (", - "}", - "leftAction={}", - "rightAction={", - "", - "", - "", - "}", - ">", - ",", "},", - "]}", - "/>", + "];", + "return (", + "}", + "leftAction={}", + "rightAction={", + "", + "", + "", + "}", + ">", + "", "", ");", "}", @@ -2296,8 +2458,7 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "} from '@pubkey-ui/core';", "import { Link } from 'react-router-dom';", "export function UserCompanyListFeature() {", - "const { deleteCompany, items, pagination, query, setSearch } =", - "useUserFindManyCompany({", + "const { items, pagination, query, setSearch } = useUserFindManyCompany({", "limit: 12,", "});", "return (", @@ -2527,6 +2688,7 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "name: '',", "location: '',", "phone: '',", + "ownerId: '',", "};", "const fields: UiFormField[] = [", "formFieldText('name', { label: 'name', required: true }),", @@ -3286,33 +3448,24 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "test-core-routes-admin.tsx": { "content": [ "import { IconBuilding } from '@tabler/icons-react';", - "import { AdminCompanyFeature } from '@proj/test-company-feature';", - "/* eslint-disable-next-line */", - "export interface TestCoreRoutesAdminProps {}", - "export function TestCoreRoutesAdmin(props: TestCoreRoutesAdminProps) {", - "return (", - "
", - "

Welcome to TestCoreRoutesAdmin!

", - "
", - ");", + "import { RouteObject, useRoutes } from 'react-router-dom';", + "const links = [];", + "const routes = [];", + "export default function () {", + "return useRoutes(routes);", "}", - "export default TestCoreRoutesAdmin;", ], "isBinary": false, "path": "libs/test/core/feature/src/lib/test-core-routes-admin.tsx", }, "test-core-routes-manager.tsx": { "content": [ - "/* eslint-disable-next-line */", - "export interface TestCoreRoutesManagerProps {}", - "export function TestCoreRoutesManager(props: TestCoreRoutesManagerProps) {", - "return (", - "
", - "

Welcome to TestCoreRoutesManager!

", - "
", - ");", + "import { RouteObject, useRoutes } from 'react-router-dom';", + "const links = [];", + "const routes = [];", + "export default function () {", + "return useRoutes(routes);", "}", - "export default TestCoreRoutesManager;", ], "isBinary": false, "path": "libs/test/core/feature/src/lib/test-core-routes-manager.tsx", @@ -3320,17 +3473,13 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "test-core-routes-user.tsx": { "content": [ "import { IconBuilding } from '@tabler/icons-react';", + "import { RouteObject, useRoutes } from 'react-router-dom';", "import { UserCompanyFeature } from '@proj/test-company-feature';", - "/* eslint-disable-next-line */", - "export interface TestCoreRoutesUserProps {}", - "export function TestCoreRoutesUser(props: TestCoreRoutesUserProps) {", - "return (", - "
", - "

Welcome to TestCoreRoutesUser!

", - "
", - ");", + "const links = [{ label: 'Companies', icon: IconBuilding, to: '/companies' }];", + "const routes = [{ path: '/companies/*', element: }];", + "export default function () {", + "return useRoutes(routes);", "}", - "export default TestCoreRoutesUser;", ], "isBinary": false, "path": "libs/test/core/feature/src/lib/test-core-routes-user.tsx", @@ -3414,8 +3563,183 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u }, "path": "libs/test/core", }, -} -`; + "user": { + "children": { + "feature": { + "children": { + ".babelrc": { + "content": [ + "{", + ""presets": [", + "[", + ""@nx/react/babel",", + "{", + ""runtime": "automatic",", + ""useBuiltIns": "usage"", + "}", + "]", + "],", + ""plugins": []", + "}", + ], + "isBinary": false, + "path": "libs/test/user/feature/.babelrc", + }, + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["plugin:@nx/react", "../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/user/feature/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-user-feature", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-user-feature\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/user/feature/README.md", + }, + "project.json": { + "content": [ + "{", + ""name": "test-user-feature",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/user/feature/src",", + ""projectType": "library",", + ""tags": [],", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "}", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/user/feature/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [], + "isBinary": false, + "path": "libs/test/user/feature/src/index.ts", + }, + "lib": { + "children": { + "admin-user-detail-feature.tsx": { + "content": [ + "import { AdminCompanyFeature } from '@proj/test-company-feature';", + "export function AdminUserDetailFeature() {", + "const { userId } = useParams<{ userId: string }>() as { userId: string };", + "const tabs = [", + "{", + "path: 'settings',", + "label: 'Settings',", + "element: ,", + "},", + "{", + "path: 'identities',", + "label: 'Identities',", + "element: ,", + "},", + "{", + "path: 'companies',", + "label: 'Companies',", + "element: ,", + "},", + "];", + "return ;", + "}", + ], + "isBinary": false, + "path": "libs/test/user/feature/src/lib/admin-user-detail-feature.tsx", + }, + }, + "path": "libs/test/user/feature/src/lib", + }, + }, + "path": "libs/test/user/feature/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""compilerOptions": {", + ""jsx": "react-jsx",", + ""allowJs": false,", + ""esModuleInterop": false,", + ""allowSyntheticDefaultImports": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "}", + "],", + ""extends": "../../../../tsconfig.base.json"", + "}", + ], + "isBinary": false, + "path": "libs/test/user/feature/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""types": [", + ""node",", + ""@nx/react/typings/cssmodule.d.ts",", + ""@nx/react/typings/image.d.ts"", + "]", + "},", + ""exclude": [", + ""jest.config.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.tsx",", + ""src/**/*.test.tsx",", + ""src/**/*.spec.js",", + ""src/**/*.test.js",", + ""src/**/*.spec.jsx",", + ""src/**/*.test.jsx"", + "],", + ""include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]", + "}", + ], + "isBinary": false, + "path": "libs/test/user/feature/tsconfig.lib.json", + }, + }, + "path": "libs/test/user/feature", + }, + }, + "path": "libs/test/user", + }, +} +`; exports[`web-crud generator should create crud with modelParentId 1`] = ` { @@ -3857,6 +4181,7 @@ exports[`web-crud generator should create crud with modelParentId 1`] = ` "UiError,", "UiLoader,", "UiPage,", + "UiTabRoute,", "UiTabRoutes,", "} from '@pubkey-ui/core';", "import { useManagerFindOneCompany } from '@proj/test-company-data-access';", @@ -3875,18 +4200,7 @@ exports[`web-crud generator should create crud with modelParentId 1`] = ` "if (!item) {", "return ;", "}", - "return (", - "}", - "leftAction={}", - "rightAction={", - "", - "", - "", - "}", - ">", - ",", "},", - "]}", - "/>", + "];", + "return (", + "}", + "leftAction={}", + "rightAction={", + "", + "", + "", + "}", + ">", + "", "", ");", "}", @@ -3921,8 +4245,7 @@ exports[`web-crud generator should create crud with modelParentId 1`] = ` "} from '@pubkey-ui/core';", "import { Link } from 'react-router-dom';", "export function ManagerCompanyListFeature() {", - "const { deleteCompany, items, pagination, query, setSearch } =", - "useManagerFindManyCompany({", + "const { items, pagination, query, setSearch } = useManagerFindManyCompany({", "limit: 12,", "});", "return (", @@ -4755,16 +5078,12 @@ exports[`web-crud generator should create crud with modelParentId 1`] = ` }, "test-core-routes-admin.tsx": { "content": [ - "/* eslint-disable-next-line */", - "export interface TestCoreRoutesAdminProps {}", - "export function TestCoreRoutesAdmin(props: TestCoreRoutesAdminProps) {", - "return (", - "
", - "

Welcome to TestCoreRoutesAdmin!

", - "
", - ");", + "import { RouteObject, useRoutes } from 'react-router-dom';", + "const links = [];", + "const routes = [];", + "export default function () {", + "return useRoutes(routes);", "}", - "export default TestCoreRoutesAdmin;", ], "isBinary": false, "path": "libs/test/core/feature/src/lib/test-core-routes-admin.tsx", @@ -4772,33 +5091,25 @@ exports[`web-crud generator should create crud with modelParentId 1`] = ` "test-core-routes-manager.tsx": { "content": [ "import { IconBuilding } from '@tabler/icons-react';", + "import { RouteObject, useRoutes } from 'react-router-dom';", "import { ManagerCompanyFeature } from '@proj/test-company-feature';", - "/* eslint-disable-next-line */", - "export interface TestCoreRoutesManagerProps {}", - "export function TestCoreRoutesManager(props: TestCoreRoutesManagerProps) {", - "return (", - "
", - "

Welcome to TestCoreRoutesManager!

", - "
", - ");", + "const links = [{ label: 'Companies', icon: IconBuilding, to: '/companies' }];", + "const routes = [{ path: '/companies/*', element: }];", + "export default function () {", + "return useRoutes(routes);", "}", - "export default TestCoreRoutesManager;", ], "isBinary": false, "path": "libs/test/core/feature/src/lib/test-core-routes-manager.tsx", }, "test-core-routes-user.tsx": { "content": [ - "/* eslint-disable-next-line */", - "export interface TestCoreRoutesUserProps {}", - "export function TestCoreRoutesUser(props: TestCoreRoutesUserProps) {", - "return (", - "
", - "

Welcome to TestCoreRoutesUser!

", - "
", - ");", + "import { RouteObject, useRoutes } from 'react-router-dom';", + "const links = [];", + "const routes = [];", + "export default function () {", + "return useRoutes(routes);", "}", - "export default TestCoreRoutesUser;", ], "isBinary": false, "path": "libs/test/core/feature/src/lib/test-core-routes-user.tsx", @@ -4882,5 +5193,174 @@ exports[`web-crud generator should create crud with modelParentId 1`] = ` }, "path": "libs/test/core", }, + "user": { + "children": { + "feature": { + "children": { + ".babelrc": { + "content": [ + "{", + ""presets": [", + "[", + ""@nx/react/babel",", + "{", + ""runtime": "automatic",", + ""useBuiltIns": "usage"", + "}", + "]", + "],", + ""plugins": []", + "}", + ], + "isBinary": false, + "path": "libs/test/user/feature/.babelrc", + }, + ".eslintrc.json": { + "content": [ + "{", + ""extends": ["plugin:@nx/react", "../../../../.eslintrc.json"],", + ""ignorePatterns": ["!**/*"],", + ""overrides": [", + "{", + ""files": ["*.ts", "*.tsx", "*.js", "*.jsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.ts", "*.tsx"],", + ""rules": {}", + "},", + "{", + ""files": ["*.js", "*.jsx"],", + ""rules": {}", + "}", + "]", + "}", + ], + "isBinary": false, + "path": "libs/test/user/feature/.eslintrc.json", + }, + "README.md": { + "content": [ + "# test-user-feature", + "This library was generated with [Nx](https://nx.dev).", + "## Running unit tests", + "Run \`nx test test-user-feature\` to execute the unit tests via [Jest](https://jestjs.io).", + ], + "isBinary": false, + "path": "libs/test/user/feature/README.md", + }, + "project.json": { + "content": [ + "{", + ""name": "test-user-feature",", + ""$schema": "../../../../node_modules/nx/schemas/project-schema.json",", + ""sourceRoot": "libs/test/user/feature/src",", + ""projectType": "library",", + ""tags": [],", + ""targets": {", + ""lint": {", + ""executor": "@nx/eslint:lint",", + ""outputs": ["{options.outputFile}"]", + "}", + "}", + "}", + ], + "isBinary": false, + "path": "libs/test/user/feature/project.json", + }, + "src": { + "children": { + "index.ts": { + "content": [], + "isBinary": false, + "path": "libs/test/user/feature/src/index.ts", + }, + "lib": { + "children": { + "admin-user-detail-feature.tsx": { + "content": [ + "export function AdminUserDetailFeature() {", + "const { userId } = useParams<{ userId: string }>() as { userId: string };", + "const tabs = [", + "{", + "path: 'settings',", + "label: 'Settings',", + "element: ,", + "},", + "{", + "path: 'identities',", + "label: 'Identities',", + "element: ,", + "},", + "];", + "return ;", + "}", + ], + "isBinary": false, + "path": "libs/test/user/feature/src/lib/admin-user-detail-feature.tsx", + }, + }, + "path": "libs/test/user/feature/src/lib", + }, + }, + "path": "libs/test/user/feature/src", + }, + "tsconfig.json": { + "content": [ + "{", + ""compilerOptions": {", + ""jsx": "react-jsx",", + ""allowJs": false,", + ""esModuleInterop": false,", + ""allowSyntheticDefaultImports": true", + "},", + ""files": [],", + ""include": [],", + ""references": [", + "{", + ""path": "./tsconfig.lib.json"", + "}", + "],", + ""extends": "../../../../tsconfig.base.json"", + "}", + ], + "isBinary": false, + "path": "libs/test/user/feature/tsconfig.json", + }, + "tsconfig.lib.json": { + "content": [ + "{", + ""extends": "./tsconfig.json",", + ""compilerOptions": {", + ""outDir": "../../../../dist/out-tsc",", + ""types": [", + ""node",", + ""@nx/react/typings/cssmodule.d.ts",", + ""@nx/react/typings/image.d.ts"", + "]", + "},", + ""exclude": [", + ""jest.config.ts",", + ""src/**/*.spec.ts",", + ""src/**/*.test.ts",", + ""src/**/*.spec.tsx",", + ""src/**/*.test.tsx",", + ""src/**/*.spec.js",", + ""src/**/*.test.js",", + ""src/**/*.spec.jsx",", + ""src/**/*.test.jsx"", + "],", + ""include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]", + "}", + ], + "isBinary": false, + "path": "libs/test/user/feature/tsconfig.lib.json", + }, + }, + "path": "libs/test/user/feature", + }, + }, + "path": "libs/test/user", + }, } `; diff --git a/libs/tools/src/generators/web-crud/web-crud-generator.spec.ts b/libs/tools/src/generators/web-crud/web-crud-generator.spec.ts index 671e0e0..0108ff2 100644 --- a/libs/tools/src/generators/web-crud/web-crud-generator.spec.ts +++ b/libs/tools/src/generators/web-crud/web-crud-generator.spec.ts @@ -1,12 +1,12 @@ import { readProjectConfiguration, Tree } from '@nx/devkit' import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing' +import { createMockApiApp } from '../../lib/api/create-mock-api-app' +import { getRecursiveFileContents } from '../../lib/utils/get-recursive-file-contents' import { createMockWebApp } from '../../lib/web' import { apiFeatureGenerator } from '../api-feature/api-feature-generator' import { webFeatureGenerator } from '../web-feature/web-feature-generator' -import { WebCrudGeneratorSchema } from './web-crud-schema' import { webCrudGenerator } from './web-crud-generator' -import { getRecursiveFileContents } from '../../lib/utils/get-recursive-file-contents' -import { createMockApiApp } from '../../lib/api/create-mock-api-app' +import { WebCrudGeneratorSchema } from './web-crud-schema' describe('web-crud generator', () => { let tree: Tree diff --git a/libs/tools/src/generators/web-feature/__snapshots__/web-feature-generator.spec.ts.snap b/libs/tools/src/generators/web-feature/__snapshots__/web-feature-generator.spec.ts.snap index 0b68496..2d7af8b 100644 --- a/libs/tools/src/generators/web-feature/__snapshots__/web-feature-generator.spec.ts.snap +++ b/libs/tools/src/generators/web-feature/__snapshots__/web-feature-generator.spec.ts.snap @@ -314,6 +314,7 @@ import { UiError, UiLoader, UiPage, + UiTabRoute, UiTabRoutes, } from '@pubkey-ui/core'; import { useAdminFindOneTest } from '@proj/web-test-data-access'; @@ -333,6 +334,19 @@ export function AdminTestDetailFeature() { return ; } + const tabs: UiTabRoute[] = [ + { + path: 'info', + label: 'Info', + element: , + }, + { + path: 'settings', + label: 'Settings', + element: , + }, + ]; + return ( } @@ -343,20 +357,7 @@ export function AdminTestDetailFeature() { } > - , - }, - { - path: 'settings', - label: 'Settings', - element: , - }, - ]} - /> + ); } @@ -378,10 +379,9 @@ import { import { Link } from 'react-router-dom'; export function AdminTestListFeature() { - const { deleteTest, items, pagination, query, setSearch } = - useAdminFindManyTest({ - limit: 10, - }); + const { items, pagination, query, setSearch } = useAdminFindManyTest({ + limit: 10, + }); return ( ; } + const tabs: UiTabRoute[] = [ + { + path: 'info', + label: 'Info', + element: , + }, + { + path: 'settings', + label: 'Settings', + element: , + }, + ]; + return ( } @@ -568,20 +582,7 @@ export function UserTestDetailFeature() { } > - , - }, - { - path: 'settings', - label: 'Settings', - element: , - }, - ]} - /> + ); } @@ -603,10 +604,9 @@ import { import { Link } from 'react-router-dom'; export function UserTestListFeature() { - const { deleteTest, items, pagination, query, setSearch } = - useUserFindManyTest({ - limit: 12, - }); + const { items, pagination, query, setSearch } = useUserFindManyTest({ + limit: 12, + }); return ( Create<%= model.className %>Input } from '@<%= npmScope %>/sdk' import { use<%= actor.className %>FindMany<%= model.className %> } from '@<%= npmScope %>/<%= app.fileName %>-<%= model.fileName %>-data-access' import { <%= actor.className %><%= model.className %>UiCreateForm } from '@<%= npmScope %>/<%= app.fileName %>-<%= model.fileName %>-ui' -import { toastError, UiBack, UiCard, UiPage } from '@pubkey-ui/core' +import { toastError, UiBack, UiCard<% if(ownerId && actor.className === 'Admin'){ %><% } else { %>, UiPage<% } %> } from '@pubkey-ui/core' import { useNavigate } from 'react-router-dom' +<% if(ownerId && actor.className === 'Admin'){ %>import { Group, Text } from '@mantine/core'<% } %> export function <%= actor.className %><%= model.className %>CreateFeature(<% if(ownerId && actor.className === 'Admin'){ %>{ <%= ownerId %> }: { <%= ownerId %>: string } <% } %>) { const navigate = useNavigate() @@ -23,10 +24,16 @@ export function <%= actor.className %><%= model.className %>CreateFeature(<% if( } return ( + <% if(ownerId && actor.className === 'Admin'){ %> + Create <%= model.className %>}> + <<%= actor.className %><%= model.className %>UiCreateForm submit={submit} /> + + <% } else { %> } title="Create <%= model.className %>"> <<%= actor.className %><%= model.className %>UiCreateForm submit={submit} /> + <% } %> ) } diff --git a/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-detail.feature.tsx.template b/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-detail.feature.tsx.template index cc01a19..2ab393a 100644 --- a/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-detail.feature.tsx.template +++ b/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-detail.feature.tsx.template @@ -1,5 +1,5 @@ import { Group } from '@mantine/core' -import { UiBack, UiDebugModal, UiError, UiLoader, UiPage, UiTabRoutes } from '@pubkey-ui/core' +import { UiBack, UiDebugModal, UiError, UiLoader, <% if(ownerId && actor.className === 'Admin'){ %>UiStack<% } else { %>UiPage<% } %>, UiTabRoute, UiTabRoutes } from '@pubkey-ui/core' import { use<%= actor.className %>FindOne<%= model.className %> } from '@<%= npmScope %>/<%= app.fileName %>-<%= model.fileName %>-data-access' import { <%= model.className %>UiItem } from '@<%= npmScope %>/<%= app.fileName %>-<%= model.fileName %>-ui' import { useParams } from 'react-router-dom' @@ -17,7 +17,28 @@ export function <%= actor.className %><%= model.className %>DetailFeature() { return } + const tabs: UiTabRoute[] = [ + { + path: 'info', + label: 'Info', + element: <<%= actor.className %><%= model.className %>DetailInfoTab <%= model.propertyName %>Id={<%= model.propertyName %>Id} />, + }, + { + path: 'settings', + label: 'Settings', + element: <<%= actor.className %><%= model.className %>DetailSettingsTab <%= model.propertyName %>Id={<%= model.propertyName %>Id} />, + }, + ] + return ( + <% if(ownerId && actor.className === 'Admin'){ %> + + + + <<%= model.className %>UiItem <%= model.propertyName %>={item} /> + + + <% } else { %> UiItem <%= model.propertyName %>={item} />} leftAction={} @@ -27,20 +48,12 @@ export function <%= actor.className %><%= model.className %>DetailFeature() { } > - <%= model.className %>DetailInfoTab <%= model.propertyName %>Id={<%= model.propertyName %>Id} />, - }, - { - path: 'settings', - label: 'Settings', - element: <<%= actor.className %><%= model.className %>DetailSettingsTab <%= model.propertyName %>Id={<%= model.propertyName %>Id} />, - }, - ]} - /> + <% } %> + + <% if(ownerId && actor.className === 'Admin'){ %> + + <% } else { %> + <% } %> ) } diff --git a/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-list.feature.tsx.template b/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-list.feature.tsx.template index f90e7c6..390edfc 100644 --- a/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-list.feature.tsx.template +++ b/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-list.feature.tsx.template @@ -6,7 +6,7 @@ import { UiBack, UiDebugModal, UiInfo, UiLoader, <% if(ownerId && actor.classNam import { Link } from 'react-router-dom' export function <%= actor.className %><%= model.className %>ListFeature(<% if(ownerId && actor.className === 'Admin'){ %>{ <%= ownerId %> }: { <%= ownerId %>: string } <% } %>) { - const { delete<%= model.className %>, items, pagination, query, setSearch } = use<%= actor.className %>FindMany<%= model.className %>({ + const { <% if(ownerId && actor.className === 'Admin'){ %>delete<%= model.className %>, <% } %> items, pagination, query, setSearch } = use<%= actor.className %>FindMany<%= model.className %>({ limit: <% if(actorAdmin){ %>10<% } else { %>12<% } %>, <% if(ownerId && actor.className === 'Admin'){ %><%= ownerId %>,<% } %> }) diff --git a/libs/tools/src/lib/web-crud/files/ui/lib/__actorFileName__-__modelFileName__-ui-create-form.tsx.template b/libs/tools/src/lib/web-crud/files/ui/lib/__actorFileName__-__modelFileName__-ui-create-form.tsx.template index 4864c98..eca385d 100644 --- a/libs/tools/src/lib/web-crud/files/ui/lib/__actorFileName__-__modelFileName__-ui-create-form.tsx.template +++ b/libs/tools/src/lib/web-crud/files/ui/lib/__actorFileName__-__modelFileName__-ui-create-form.tsx.template @@ -17,9 +17,6 @@ export function <%= actor.className %><%= model.className %>UiCreateForm({ submi <% for (let field of fields){ %> formFieldText('<%= field.name %>', { label: '<%= field.name %>', required: true, }), <% } %> - <% if(ownerId && actor.className === 'Admin'){ %> - formFieldText('<%= ownerId %>', { label: '<%= ownerId %>', required: true, }), - <% } %> ] return ( submit(res as <%= actor.className %>Create<%= model.className %>Input)}> diff --git a/libs/tools/src/lib/web-crud/generate-web-crud.ts b/libs/tools/src/lib/web-crud/generate-web-crud.ts index cac556c..b94b86a 100644 --- a/libs/tools/src/lib/web-crud/generate-web-crud.ts +++ b/libs/tools/src/lib/web-crud/generate-web-crud.ts @@ -1,11 +1,12 @@ import { generateFiles, type ProjectConfiguration, Tree } from '@nx/devkit' import { NormalizedApiCrudSchema } from '../api-crud/normalized-api-crud.schema' -import { addArrayItem } from '../utils/add-array-item' -import { addExports } from '../utils/add-export' -import { addNamedImport } from '../utils/add-named-import' +import { addArrayItem } from '../utils/ast/add-array-item' +import { addArrayItemInFunction } from '../utils/ast/add-array-item-in-function' +import { addExports } from '../utils/ast/add-export' +import { addNamedImport } from '../utils/ast/add-named-import' +import { updateSourceFile } from '../utils/ast/update-source-file' import { ensureNxProjectExists } from '../utils/ensure-nx-project-exists' -import { updateSourceFile } from '../utils/update-source-file' import { getWebCrudSubstitutions } from './get-web-crud-substitutions' const defaultIconMap: Record = { @@ -31,13 +32,14 @@ export function generateWebCrud(tree: Tree, options: NormalizedApiCrudSchema) { `${vars.app.fileName}-${vars.model.fileName}-feature`, `${vars.app.fileName}-${vars.model.fileName}-ui`, `${vars.app.fileName}-core-feature`, + `${vars.app.fileName}-user-feature`, ].map((project) => ensureNxProjectExists(tree, project)) - const [dataAccess, feature, ui, shellFeature] = projects + const [dataAccess, feature, ui, coreFeature, userFeature] = projects const requiredFiles = [ - `${shellFeature.sourceRoot}/lib/${options.app}-core-routes-${vars.actor.fileName}.tsx`, - `${shellFeature.sourceRoot}/lib/${options.app}-core-routes-${vars.actor.fileName}.tsx`, + `${coreFeature.sourceRoot}/lib/${options.app}-core-routes-${vars.actor.fileName}.tsx`, + `${coreFeature.sourceRoot}/lib/${options.app}-core-routes-${vars.actor.fileName}.tsx`, `${feature.sourceRoot}/index.ts`, ] for (const file of requiredFiles) { @@ -82,30 +84,50 @@ export function generateWebCrud(tree: Tree, options: NormalizedApiCrudSchema) { tree.write(routesFile, [`import { ${defaultIcon} } from '@tabler/icons-react'`, routesFileContent].join('\n')) } + const label = ucfirst(vars.plural.fileName) + const path = `${vars.plural.fileName}` const to = `${vars.actorAdmin ? '/admin/' : `/`}${vars.plural.fileName}` const link = { name: 'links', - content: `{ label: '${vars.plural.className}', icon: ${defaultIcon}, to: '${to}' },`, + content: `{ label: '${label}', icon: ${defaultIcon}, to: '${to}' },`, } const route = { name: 'routes', - content: `{ path: '/${vars.plural.fileName}/*', element: <${vars.actor.className}${vars.model.className}Feature /> },`, + content: `{ path: '/${path}/*', element: <${vars.actor.className}${vars.model.className}Feature /> },`, + } + const tabs = { + name: 'tabs', + content: `{ path: '${path}', label: '${label}', element: <${vars.actor.className}${vars.model.className}Feature ${vars.ownerId}={userId} /> },`, } - updateSourceFile(tree, routesFile, (source) => { - addArrayItem(source, link) - addArrayItem(source, route) - return source - }) - - updateSourceFile(tree, routesFile, (source) => { - addNamedImport( - source, - `@${vars.npmScope}/${vars.app.fileName}-${vars.model.fileName}-feature`, - `${vars.actor.className}${vars.model.className}Feature`, - ) - return source - }) + // If we add an owner, we want to add the admin link and route to the user detail feature + if (options.modelOwnerId && options.actor === 'admin') { + const userDetailFeature = `${userFeature.sourceRoot}/lib/admin-user-detail-feature.tsx` + if (tree.exists(userDetailFeature)) { + updateSourceFile(tree, userDetailFeature, (source) => { + addArrayItemInFunction(source, tabs, 'AdminUserDetailFeature') + addNamedImport( + source, + `@${vars.npmScope}/${vars.app.fileName}-${vars.model.fileName}-feature`, + `${vars.actor.className}${vars.model.className}Feature`, + ) + return source + }) + } else { + console.warn('File not found:', userDetailFeature) + } + } else { + updateSourceFile(tree, routesFile, (source) => { + addArrayItem(source, link) + addArrayItem(source, route) + addNamedImport( + source, + `@${vars.npmScope}/${vars.app.fileName}-${vars.model.fileName}-feature`, + `${vars.actor.className}${vars.model.className}Feature`, + ) + return source + }) + } // Generate the ui library generateFiles(tree, `${__dirname}/files/ui`, ui.sourceRoot, { ...vars }) @@ -122,3 +144,7 @@ export function generateWebCrud(tree: Tree, options: NormalizedApiCrudSchema) { `./lib/${vars.model.fileName}-ui-item`, ]) } + +function ucfirst(str: string) { + return str.charAt(0).toUpperCase() + str.slice(1) +} diff --git a/libs/tools/src/lib/web/create-mock-web-app.ts b/libs/tools/src/lib/web/create-mock-web-app.ts index ae06e92..be95db2 100644 --- a/libs/tools/src/lib/web/create-mock-web-app.ts +++ b/libs/tools/src/lib/web/create-mock-web-app.ts @@ -34,19 +34,44 @@ export async function createMockWebApp(tree: Tree, app: string) { style: 'css', }) + // Create the user feature lib + await libraryGenerator(tree, { + directory: `libs/${app}/user/feature`, + linter: Linter.EsLint, + name: `${app}-user-feature`, + projectNameAndRootFormat: 'as-provided', + skipFormat: true, + style: 'css', + }) + // Create the core feature lib await createMockComponent(tree, `${app}-core-feature`, `${app}-core-feature`) // Create the core routes libs await createMockComponent(tree, `${app}-core-feature`, `${app}-core-routes`) - await createMockComponent(tree, `${app}-core-feature`, `${app}-core-routes-admin`) - await createMockComponent(tree, `${app}-core-feature`, `${app}-core-routes-user`) - await createMockComponent(tree, `${app}-core-feature`, `${app}-core-routes-manager`) + await createMockComponent(tree, `${app}-core-feature`, `${app}-core-routes-admin`, getEmptyRoutesFile()) + await createMockComponent(tree, `${app}-core-feature`, `${app}-core-routes-user`, getEmptyRoutesFile()) + await createMockComponent(tree, `${app}-core-feature`, `${app}-core-routes-manager`, getEmptyRoutesFile()) + + // Create the admin-user-detail-feature + await createMockComponent( + tree, + `${app}-user-feature`, + `admin-user-detail-feature`, + `export function AdminUserDetailFeature() { + const { userId } = useParams<{ userId: string }>() as { userId: string } + const tabs = [ + { path: 'settings', label: 'Settings', element: }, + { path: 'identities', label: 'Identities', element: }, + ] + return +}`, + ) } -function createMockComponent(tree: Tree, project: string, name: string) { +async function createMockComponent(tree: Tree, project: string, name: string, content?: string) { const config = getProjects(tree).get(project) - return componentGenerator(tree, { + await componentGenerator(tree, { name, directory: `${config.sourceRoot}/lib/`, nameAndDirectoryFormat: 'as-provided', @@ -54,4 +79,20 @@ function createMockComponent(tree: Tree, project: string, name: string) { skipTests: true, skipFormat: true, }) + if (!content) { + return + } + const filename = `${config.sourceRoot}/lib/${name}.tsx` + if (content && tree.exists(filename)) { + tree.write(filename, content) + } +} + +function getEmptyRoutesFile(): string { + return [ + `import { RouteObject, useRoutes } from 'react-router-dom'`, + `const links = []`, + `const routes = []`, + `export default function() { return useRoutes(routes) }`, + ].join('\n') } diff --git a/libs/web/user/feature/src/lib/admin-user-detail-feature.tsx b/libs/web/user/feature/src/lib/admin-user-detail-feature.tsx index 66303b7..672db2d 100644 --- a/libs/web/user/feature/src/lib/admin-user-detail-feature.tsx +++ b/libs/web/user/feature/src/lib/admin-user-detail-feature.tsx @@ -1,7 +1,7 @@ import { Group } from '@mantine/core' import { useAdminFindOneUser } from '@pubkey-stack/web-user-data-access' import { UserUiAvatar } from '@pubkey-stack/web-user-ui' -import { UiBack, UiDebugModal, UiError, UiLoader, UiPage, UiStack, UiTabRoutes } from '@pubkey-ui/core' +import { UiBack, UiDebugModal, UiError, UiLoader, UiPage, UiStack, UiTabRoute, UiTabRoutes } from '@pubkey-ui/core' import { useParams } from 'react-router-dom' import { AdminUserDetailFeatureIdentities } from './admin-user-detail-feature-identities' import { AdminUserDetailFeatureSettings } from './admin-user-detail-feature-settings' @@ -17,6 +17,18 @@ export function AdminUserDetailFeature() { return } + const tabs: UiTabRoute[] = [ + { + path: 'settings', + label: 'Settings', + element: , + }, + { + path: 'identities', + label: 'Identities', + element: , + }, + ] return ( } @@ -32,20 +44,7 @@ export function AdminUserDetailFeature() { } > - , - }, - { - path: 'identities', - label: 'Identities', - element: , - }, - ]} - /> + ) From ee986fabb751d2d44aeb4738161c3d871e982d2d Mon Sep 17 00:00:00 2001 From: Bram Borggreve Date: Sat, 16 Mar 2024 06:41:07 +0000 Subject: [PATCH 07/12] refactor: re-structure input names --- api-schema.graphql | 134 ++++----- apps/api/src/main.ts | 2 +- libs/api/identity/data-access/src/index.ts | 14 +- .../lib/api-identity-data-admin.service.ts | 8 +- .../src/lib/api-identity-data-anon.service.ts | 8 +- .../src/lib/api-identity-data-user.service.ts | 16 +- ...nput.ts => identity-admin-create.input.ts} | 2 +- ...t.ts => identity-admin-find-many.input.ts} | 2 +- .../dto/identity-request-challenge-input.ts | 5 + ...ut.ts => identity-user-find-many.input.ts} | 2 +- ...y-input.ts => identity-user-link-input.ts} | 2 +- ....ts => identity-verify-challenge-input.ts} | 2 +- .../dto/request-identity-challenge.input.ts | 5 - .../src/lib/api-identity-admin.resolver.ts | 8 +- .../src/lib/api-identity-anon.resolver.ts | 8 +- .../src/lib/api-identity-user.resolver.ts | 16 +- libs/api/user/data-access/src/index.ts | 10 +- .../src/lib/api-user-data-admin.service.ts | 12 +- .../src/lib/api-user-data-user.service.ts | 8 +- ...er.input.ts => user-admin-create.input.ts} | 2 +- ...input.ts => user-admin-find-many.input.ts} | 2 +- ...er.input.ts => user-admin-update.input.ts} | 2 +- ....input.ts => user-user-find-many.input.ts} | 2 +- ...ser.input.ts => user-user-update.input.ts} | 2 +- .../lib/helpers/get-user-where-admin.input.ts | 4 +- .../lib/helpers/get-user-where-user.input.ts | 4 +- .../src/lib/api-user-admin.resolver.ts | 12 +- .../feature/src/lib/api-user-user.resolver.ts | 8 +- libs/sdk/src/generated/graphql-sdk.ts | 252 ++++++++-------- libs/sdk/src/graphql/feature-identity.graphql | 16 +- libs/sdk/src/graphql/feature-user.graphql | 10 +- .../api-crud-generator.spec.ts.snap | 282 +++++++++--------- .../api-feature-generator.spec.ts.snap | 78 +++-- .../api-feature/api-feature-generator.spec.ts | 12 +- .../web-crud-generator.spec.ts.snap | 34 +-- .../web-feature-generator.spec.ts.snap | 12 +- ...data-__actorFileName__.service.ts.template | 18 +- ...__modelFileName__-data.service.ts.template | 3 +- ..._actorFileName__-create.input.ts.template} | 2 +- ...torFileName__-find-many.input.ts.template} | 2 +- ..._actorFileName__-update.input.ts.template} | 2 +- ...-where-__actorFileName__.input.ts.template | 4 +- ...e__-__actorFileName__.resolver.ts.template | 12 +- .../src/lib/api-crud/generate-api-crud.ts | 8 +- .../src/lib/api-crud/generate-sdk-file.ts | 6 +- ...__-find-many-__modelFileName__.ts.template | 8 +- ...e__-find-one-__modelFileName__.ts.template | 4 +- ...odelFileName__-create.feature.tsx.template | 4 +- ...odelFileName__-ui-create-form.tsx.template | 11 +- ...odelFileName__-ui-update-form.tsx.template | 10 +- .../__modelFileName__-ui-item.tsx.template | 4 +- .../src/lib/web-crud/generate-web-crud.ts | 2 +- libs/web/auth/ui/src/lib/auth-ui-shell.tsx | 2 +- .../src/lib/use-admin-find-many-identity.ts | 6 +- .../src/lib/use-user-find-many-identity.ts | 4 +- .../src/lib/admin-identity-ui-create-form.tsx | 10 +- .../ui/src/lib/identity-ui-login-buttons.tsx | 2 +- .../lib/identity-ui-solana-login-button.tsx | 2 +- .../src/lib/use-admin-find-many-user.ts | 8 +- .../src/lib/use-admin-find-one-user.ts | 4 +- .../src/lib/use-user-find-many-user.ts | 6 +- .../data-access/src/lib/use-user-profile.ts | 4 +- .../src/lib/admin-user-create-feature.tsx | 4 +- .../ui/src/lib/admin-user-ui-create-form.tsx | 10 +- .../user/ui/src/lib/admin-user-ui-search.tsx | 2 +- .../ui/src/lib/admin-user-ui-update-form.tsx | 8 +- .../user/ui/src/lib/user-ui-autocomplete.tsx | 2 +- libs/web/user/ui/src/lib/user-ui-item.tsx | 6 +- libs/web/user/ui/src/lib/user-ui-search.tsx | 2 +- .../user/ui/src/lib/user-ui-update-form.tsx | 10 +- 70 files changed, 580 insertions(+), 610 deletions(-) rename libs/api/identity/data-access/src/lib/dto/{admin-create-identity.input.ts => identity-admin-create.input.ts} (86%) rename libs/api/identity/data-access/src/lib/dto/{admin-find-many-identity.input.ts => identity-admin-find-many.input.ts} (86%) create mode 100644 libs/api/identity/data-access/src/lib/dto/identity-request-challenge-input.ts rename libs/api/identity/data-access/src/lib/dto/{user-find-many-identity-input.ts => identity-user-find-many.input.ts} (70%) rename libs/api/identity/data-access/src/lib/dto/{link-identity-input.ts => identity-user-link-input.ts} (86%) rename libs/api/identity/data-access/src/lib/dto/{verify-identity-challenge-input.ts => identity-verify-challenge-input.ts} (89%) delete mode 100644 libs/api/identity/data-access/src/lib/dto/request-identity-challenge.input.ts rename libs/api/user/data-access/src/lib/dto/{admin-create-user.input.ts => user-admin-create.input.ts} (81%) rename libs/api/user/data-access/src/lib/dto/{admin-find-many-user.input.ts => user-admin-find-many.input.ts} (87%) rename libs/api/user/data-access/src/lib/dto/{admin-update-user.input.ts => user-admin-update.input.ts} (93%) rename libs/api/user/data-access/src/lib/dto/{user-find-many-user.input.ts => user-user-find-many.input.ts} (75%) rename libs/api/user/data-access/src/lib/dto/{user-update-user.input.ts => user-user-update.input.ts} (85%) rename libs/tools/src/lib/api-crud/files/data-access/lib/dto/{__actorFileName__-create-__modelFileName__.input.ts.template => __modelFileName__-__actorFileName__-create.input.ts.template} (90%) rename libs/tools/src/lib/api-crud/files/data-access/lib/dto/{__actorFileName__-find-many-__modelFileName__.input.ts.template => __modelFileName__-__actorFileName__-find-many.input.ts.template} (79%) rename libs/tools/src/lib/api-crud/files/data-access/lib/dto/{__actorFileName__-update-__modelFileName__.input.ts.template => __modelFileName__-__actorFileName__-update.input.ts.template} (74%) diff --git a/api-schema.graphql b/api-schema.graphql index 0a515cb..6adeb69 100644 --- a/api-schema.graphql +++ b/api-schema.graphql @@ -2,39 +2,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY) # ------------------------------------------------------ -input AdminCreateIdentityInput { - ownerId: String! - provider: IdentityProvider! - providerId: String! -} - -input AdminCreateUserInput { - password: String - username: String! -} - -input AdminFindManyIdentityInput { - ownerId: String - provider: IdentityProvider -} - -input AdminFindManyUserInput { - limit: Int = 10 - page: Int = 1 - role: UserRole - search: String - status: UserStatus -} - -input AdminUpdateUserInput { - avatarUrl: String - developer: Boolean - name: String - role: UserRole - status: UserStatus - username: String -} - type AppConfig { authDiscordEnabled: Boolean! authGithubEnabled: Boolean! @@ -65,6 +32,17 @@ type Identity { verified: Boolean } +input IdentityAdminCreateInput { + ownerId: String! + provider: IdentityProvider! + providerId: String! +} + +input IdentityAdminFindManyInput { + ownerId: String + provider: IdentityProvider +} + type IdentityChallenge { challenge: String! createdAt: DateTime! @@ -86,35 +64,52 @@ enum IdentityProvider { Twitter } -""" -The `JSON` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf). -""" -scalar JSON @specifiedBy(url: "http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf") +input IdentityRequestChallengeInput { + provider: IdentityProvider! + providerId: String! +} + +input IdentityUserFindManyInput { + username: String! +} -input LinkIdentityInput { +input IdentityUserLinkInput { provider: IdentityProvider! providerId: String! } +input IdentityVerifyChallengeInput { + challenge: String! + provider: IdentityProvider! + providerId: String! + signature: String! + useLedger: Boolean = false +} + +""" +The `JSON` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf). +""" +scalar JSON @specifiedBy(url: "http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf") + input LoginInput { password: String! username: String! } type Mutation { - adminCreateIdentity(input: AdminCreateIdentityInput!): Identity - adminCreateUser(input: AdminCreateUserInput!): User + adminCreateIdentity(input: IdentityAdminCreateInput!): Identity + adminCreateUser(input: UserAdminCreateInput!): User adminDeleteIdentity(identityId: String!): Boolean adminDeleteUser(userId: String!): Boolean - adminUpdateUser(input: AdminUpdateUserInput!, userId: String!): User - anonVerifyIdentityChallenge(input: VerifyIdentityChallengeInput!): IdentityChallenge + adminUpdateUser(input: UserAdminUpdateInput!, userId: String!): User + anonVerifyIdentityChallenge(input: IdentityVerifyChallengeInput!): IdentityChallenge login(input: LoginInput!): User logout: Boolean register(input: RegisterInput!): User userDeleteIdentity(identityId: String!): Boolean - userLinkIdentity(input: LinkIdentityInput!): Identity - userUpdateUser(input: UserUpdateUserInput!): User - userVerifyIdentityChallenge(input: VerifyIdentityChallengeInput!): IdentityChallenge + userLinkIdentity(input: IdentityUserLinkInput!): Identity + userUpdateUser(input: UserUserUpdateInput!): User + userVerifyIdentityChallenge(input: IdentityVerifyChallengeInput!): IdentityChallenge } type PagingMeta { @@ -128,17 +123,17 @@ type PagingMeta { } type Query { - adminFindManyIdentity(input: AdminFindManyIdentityInput!): [Identity!] - adminFindManyUser(input: AdminFindManyUserInput!): UserPaging! + adminFindManyIdentity(input: IdentityAdminFindManyInput!): [Identity!] + adminFindManyUser(input: UserAdminFindManyInput!): UserPaging! adminFindOneUser(userId: String!): User - anonRequestIdentityChallenge(input: RequestIdentityChallengeInput!): IdentityChallenge + anonRequestIdentityChallenge(input: IdentityRequestChallengeInput!): IdentityChallenge appConfig: AppConfig! me: User uptime: Float! - userFindManyIdentity(input: UserFindManyIdentityInput!): [Identity!] - userFindManyUser(input: UserFindManyUserInput!): UserPaging! + userFindManyIdentity(input: IdentityUserFindManyInput!): [Identity!] + userFindManyUser(input: UserUserFindManyInput!): UserPaging! userFindOneUser(username: String!): User - userRequestIdentityChallenge(input: RequestIdentityChallengeInput!): IdentityChallenge + userRequestIdentityChallenge(input: IdentityRequestChallengeInput!): IdentityChallenge } input RegisterInput { @@ -146,11 +141,6 @@ input RegisterInput { username: String! } -input RequestIdentityChallengeInput { - provider: IdentityProvider! - providerId: String! -} - type User { avatarUrl: String createdAt: DateTime @@ -165,14 +155,26 @@ type User { username: String } -input UserFindManyIdentityInput { +input UserAdminCreateInput { + password: String username: String! } -input UserFindManyUserInput { +input UserAdminFindManyInput { limit: Int = 10 page: Int = 1 + role: UserRole search: String + status: UserStatus +} + +input UserAdminUpdateInput { + avatarUrl: String + developer: Boolean + name: String + role: UserRole + status: UserStatus + username: String } type UserPaging { @@ -191,16 +193,14 @@ enum UserStatus { Inactive } -input UserUpdateUserInput { +input UserUserFindManyInput { + limit: Int = 10 + page: Int = 1 + search: String +} + +input UserUserUpdateInput { avatarUrl: String developer: Boolean name: String } - -input VerifyIdentityChallengeInput { - challenge: String! - provider: IdentityProvider! - providerId: String! - signature: String! - useLedger: Boolean = false -} diff --git a/apps/api/src/main.ts b/apps/api/src/main.ts index c3f7e85..6cab088 100644 --- a/apps/api/src/main.ts +++ b/apps/api/src/main.ts @@ -21,7 +21,7 @@ async function bootstrap() { ) const host = `http://${core.config.host}:${core.config.port}` await app.listen(core.config.port, core.config.host) - Logger.log(`🚀 RestAPI is running on: ${host}/${core.config.prefix}.`) + Logger.log(`🚀 RestAPI is running on: ${host}${core.config.prefix}.`) Logger.log(`🚀 GraphQL is running on: ${host}/graphql.`) Logger.log(`🔋 API_URL: ${core.config.apiUrl}`) Logger.log(`🔋 WEB_URL: ${core.config.webUrl}`) diff --git a/libs/api/identity/data-access/src/index.ts b/libs/api/identity/data-access/src/index.ts index 9a32a3b..40e3559 100644 --- a/libs/api/identity/data-access/src/index.ts +++ b/libs/api/identity/data-access/src/index.ts @@ -1,13 +1,13 @@ export * from './lib/api-identity-data-admin.service' +export * from './lib/api-identity-data-user.service' export * from './lib/api-identity.data-access.module' export * from './lib/api-identity.service' -export * from './lib/api-identity-data-user.service' -export * from './lib/dto/admin-create-identity.input' -export * from './lib/dto/admin-find-many-identity.input' -export * from './lib/dto/link-identity-input' -export * from './lib/dto/request-identity-challenge.input' -export * from './lib/dto/user-find-many-identity-input' -export * from './lib/dto/verify-identity-challenge-input' +export * from './lib/dto/identity-admin-create.input' +export * from './lib/dto/identity-admin-find-many.input' +export * from './lib/dto/identity-request-challenge-input' +export * from './lib/dto/identity-user-find-many.input' +export * from './lib/dto/identity-user-link-input' +export * from './lib/dto/identity-verify-challenge-input' export * from './lib/entity/identity-challenge.entity' export * from './lib/entity/identity-provider.enum' export * from './lib/entity/identity.entity' diff --git a/libs/api/identity/data-access/src/lib/api-identity-data-admin.service.ts b/libs/api/identity/data-access/src/lib/api-identity-data-admin.service.ts index 94f36aa..21f2bcb 100644 --- a/libs/api/identity/data-access/src/lib/api-identity-data-admin.service.ts +++ b/libs/api/identity/data-access/src/lib/api-identity-data-admin.service.ts @@ -1,14 +1,14 @@ import { Injectable } from '@nestjs/common' import { Identity as PrismaIdentity } from '@prisma/client' import { ApiCoreService } from '@pubkey-stack/api-core-data-access' -import { AdminCreateIdentityInput } from './dto/admin-create-identity.input' -import { AdminFindManyIdentityInput } from './dto/admin-find-many-identity.input' +import { IdentityAdminCreateInput } from './dto/identity-admin-create.input' +import { IdentityAdminFindManyInput } from './dto/identity-admin-find-many.input' @Injectable() export class ApiIdentityDataAdminService { constructor(private readonly core: ApiCoreService) {} - async createIdentity(input: AdminCreateIdentityInput): Promise { + async createIdentity(input: IdentityAdminCreateInput): Promise { const found = await this.core.data.identity.findUnique({ where: { provider_providerId: { providerId: input.providerId, provider: input.provider } }, }) @@ -40,7 +40,7 @@ export class ApiIdentityDataAdminService { return true } - async findManyIdentity(input: AdminFindManyIdentityInput): Promise { + async findManyIdentity(input: IdentityAdminFindManyInput): Promise { const items = await this.core.data.identity.findMany({ where: { ownerId: input.ownerId ? input.ownerId : undefined, diff --git a/libs/api/identity/data-access/src/lib/api-identity-data-anon.service.ts b/libs/api/identity/data-access/src/lib/api-identity-data-anon.service.ts index 22c6d84..dcd7463 100644 --- a/libs/api/identity/data-access/src/lib/api-identity-data-anon.service.ts +++ b/libs/api/identity/data-access/src/lib/api-identity-data-anon.service.ts @@ -9,8 +9,8 @@ import { slugifyId, } from '@pubkey-stack/api-core-data-access' import { ApiIdentitySolanaService } from './api-identity-solana.service' -import { RequestIdentityChallengeInput } from './dto/request-identity-challenge.input' -import { VerifyIdentityChallengeInput } from './dto/verify-identity-challenge-input' +import { IdentityRequestChallengeInput } from './dto/identity-request-challenge-input' +import { IdentityVerifyChallengeInput } from './dto/identity-verify-challenge-input' import { sha256 } from './helpers/sha256' @Injectable() @@ -22,7 +22,7 @@ export class ApiIdentityDataAnonService { private readonly solana: ApiIdentitySolanaService, ) {} - async requestIdentityChallenge(ctx: BaseContext, { provider, providerId }: RequestIdentityChallengeInput) { + async requestIdentityChallenge(ctx: BaseContext, { provider, providerId }: IdentityRequestChallengeInput) { // Make sure we can link the given provider this.solana.ensureLinkProvider(provider) // Make sure the providerId is valid @@ -69,7 +69,7 @@ export class ApiIdentityDataAnonService { async verifyIdentityChallenge( ctx: BaseContext, - { provider, providerId, challenge, signature, useLedger }: VerifyIdentityChallengeInput, + { provider, providerId, challenge, signature, useLedger }: IdentityVerifyChallengeInput, ) { // Make sure we can link the given provider this.solana.ensureLinkProvider(provider) diff --git a/libs/api/identity/data-access/src/lib/api-identity-data-user.service.ts b/libs/api/identity/data-access/src/lib/api-identity-data-user.service.ts index 5c66e97..14ec800 100644 --- a/libs/api/identity/data-access/src/lib/api-identity-data-user.service.ts +++ b/libs/api/identity/data-access/src/lib/api-identity-data-user.service.ts @@ -3,10 +3,10 @@ import { Identity as PrismaIdentity } from '@prisma/client' import { ApiCoreService, BaseContext, getRequestDetails } from '@pubkey-stack/api-core-data-access' import { verifySignature } from '@pubkeyapp/solana-verify-wallet' import { ApiIdentitySolanaService } from './api-identity-solana.service' -import { LinkIdentityInput } from './dto/link-identity-input' -import { RequestIdentityChallengeInput } from './dto/request-identity-challenge.input' -import { UserFindManyIdentityInput } from './dto/user-find-many-identity-input' -import { VerifyIdentityChallengeInput } from './dto/verify-identity-challenge-input' +import { IdentityRequestChallengeInput } from './dto/identity-request-challenge-input' +import { IdentityUserFindManyInput } from './dto/identity-user-find-many.input' +import { IdentityUserLinkInput } from './dto/identity-user-link-input' +import { IdentityVerifyChallengeInput } from './dto/identity-verify-challenge-input' import { sha256 } from './helpers/sha256' @Injectable() @@ -32,7 +32,7 @@ export class ApiIdentityDataUserService { return true } - async findManyIdentity(input: UserFindManyIdentityInput): Promise { + async findManyIdentity(input: IdentityUserFindManyInput): Promise { const items = await this.core.data.identity.findMany({ where: { owner: { username: input.username } }, orderBy: [{ provider: 'asc' }, { providerId: 'asc' }], @@ -44,7 +44,7 @@ export class ApiIdentityDataUserService { async requestIdentityChallenge( ctx: BaseContext, userId: string, - { provider, providerId }: RequestIdentityChallengeInput, + { provider, providerId }: IdentityRequestChallengeInput, ) { // Make sure we can link the given provider this.solana.ensureLinkProvider(provider) @@ -73,7 +73,7 @@ export class ApiIdentityDataUserService { async verifyIdentityChallenge( ctx: BaseContext, userId: string, - { provider, providerId, challenge, signature, useLedger }: VerifyIdentityChallengeInput, + { provider, providerId, challenge, signature, useLedger }: IdentityVerifyChallengeInput, ) { // Make sure we can link the given provider this.solana.ensureLinkProvider(provider) @@ -124,7 +124,7 @@ export class ApiIdentityDataUserService { return updated } - async linkIdentity(userId: string, { provider, providerId }: LinkIdentityInput) { + async linkIdentity(userId: string, { provider, providerId }: IdentityUserLinkInput) { // Make sure we can link the given provider this.solana.ensureLinkProvider(provider) // Make sure the identity does not exist diff --git a/libs/api/identity/data-access/src/lib/dto/admin-create-identity.input.ts b/libs/api/identity/data-access/src/lib/dto/identity-admin-create.input.ts similarity index 86% rename from libs/api/identity/data-access/src/lib/dto/admin-create-identity.input.ts rename to libs/api/identity/data-access/src/lib/dto/identity-admin-create.input.ts index b9eddda..115525c 100644 --- a/libs/api/identity/data-access/src/lib/dto/admin-create-identity.input.ts +++ b/libs/api/identity/data-access/src/lib/dto/identity-admin-create.input.ts @@ -2,7 +2,7 @@ import { Field, InputType } from '@nestjs/graphql' import { IdentityProvider } from '../entity/identity-provider.enum' @InputType() -export class AdminCreateIdentityInput { +export class IdentityAdminCreateInput { @Field(() => IdentityProvider) provider!: IdentityProvider @Field() diff --git a/libs/api/identity/data-access/src/lib/dto/admin-find-many-identity.input.ts b/libs/api/identity/data-access/src/lib/dto/identity-admin-find-many.input.ts similarity index 86% rename from libs/api/identity/data-access/src/lib/dto/admin-find-many-identity.input.ts rename to libs/api/identity/data-access/src/lib/dto/identity-admin-find-many.input.ts index 63be328..21d9417 100644 --- a/libs/api/identity/data-access/src/lib/dto/admin-find-many-identity.input.ts +++ b/libs/api/identity/data-access/src/lib/dto/identity-admin-find-many.input.ts @@ -2,7 +2,7 @@ import { Field, InputType } from '@nestjs/graphql' import { IdentityProvider } from '../entity/identity-provider.enum' @InputType() -export class AdminFindManyIdentityInput { +export class IdentityAdminFindManyInput { @Field({ nullable: true }) ownerId?: string diff --git a/libs/api/identity/data-access/src/lib/dto/identity-request-challenge-input.ts b/libs/api/identity/data-access/src/lib/dto/identity-request-challenge-input.ts new file mode 100644 index 0000000..c3c6dfd --- /dev/null +++ b/libs/api/identity/data-access/src/lib/dto/identity-request-challenge-input.ts @@ -0,0 +1,5 @@ +import { InputType } from '@nestjs/graphql' +import { IdentityUserLinkInput } from './identity-user-link-input' + +@InputType() +export class IdentityRequestChallengeInput extends IdentityUserLinkInput {} diff --git a/libs/api/identity/data-access/src/lib/dto/user-find-many-identity-input.ts b/libs/api/identity/data-access/src/lib/dto/identity-user-find-many.input.ts similarity index 70% rename from libs/api/identity/data-access/src/lib/dto/user-find-many-identity-input.ts rename to libs/api/identity/data-access/src/lib/dto/identity-user-find-many.input.ts index 935cc08..2e89472 100644 --- a/libs/api/identity/data-access/src/lib/dto/user-find-many-identity-input.ts +++ b/libs/api/identity/data-access/src/lib/dto/identity-user-find-many.input.ts @@ -1,7 +1,7 @@ import { Field, InputType } from '@nestjs/graphql' @InputType() -export class UserFindManyIdentityInput { +export class IdentityUserFindManyInput { @Field() username!: string } diff --git a/libs/api/identity/data-access/src/lib/dto/link-identity-input.ts b/libs/api/identity/data-access/src/lib/dto/identity-user-link-input.ts similarity index 86% rename from libs/api/identity/data-access/src/lib/dto/link-identity-input.ts rename to libs/api/identity/data-access/src/lib/dto/identity-user-link-input.ts index 24c7693..42f6fd4 100644 --- a/libs/api/identity/data-access/src/lib/dto/link-identity-input.ts +++ b/libs/api/identity/data-access/src/lib/dto/identity-user-link-input.ts @@ -2,7 +2,7 @@ import { Field, InputType } from '@nestjs/graphql' import { IdentityProvider } from '../entity/identity-provider.enum' @InputType() -export class LinkIdentityInput { +export class IdentityUserLinkInput { @Field(() => IdentityProvider) provider!: IdentityProvider @Field() diff --git a/libs/api/identity/data-access/src/lib/dto/verify-identity-challenge-input.ts b/libs/api/identity/data-access/src/lib/dto/identity-verify-challenge-input.ts similarity index 89% rename from libs/api/identity/data-access/src/lib/dto/verify-identity-challenge-input.ts rename to libs/api/identity/data-access/src/lib/dto/identity-verify-challenge-input.ts index 467542f..b55a9d6 100644 --- a/libs/api/identity/data-access/src/lib/dto/verify-identity-challenge-input.ts +++ b/libs/api/identity/data-access/src/lib/dto/identity-verify-challenge-input.ts @@ -2,7 +2,7 @@ import { Field, InputType } from '@nestjs/graphql' import { IdentityProvider } from '../entity/identity-provider.enum' @InputType() -export class VerifyIdentityChallengeInput { +export class IdentityVerifyChallengeInput { @Field(() => IdentityProvider) provider!: IdentityProvider @Field() diff --git a/libs/api/identity/data-access/src/lib/dto/request-identity-challenge.input.ts b/libs/api/identity/data-access/src/lib/dto/request-identity-challenge.input.ts deleted file mode 100644 index 7e47d0c..0000000 --- a/libs/api/identity/data-access/src/lib/dto/request-identity-challenge.input.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { InputType } from '@nestjs/graphql' -import { LinkIdentityInput } from './link-identity-input' - -@InputType() -export class RequestIdentityChallengeInput extends LinkIdentityInput {} diff --git a/libs/api/identity/feature/src/lib/api-identity-admin.resolver.ts b/libs/api/identity/feature/src/lib/api-identity-admin.resolver.ts index ca260e7..9bc1db0 100644 --- a/libs/api/identity/feature/src/lib/api-identity-admin.resolver.ts +++ b/libs/api/identity/feature/src/lib/api-identity-admin.resolver.ts @@ -2,8 +2,8 @@ import { UseGuards } from '@nestjs/common' import { Args, Mutation, Query, Resolver } from '@nestjs/graphql' import { ApiAuthGraphQLAdminGuard } from '@pubkey-stack/api-auth-data-access' import { - AdminCreateIdentityInput, - AdminFindManyIdentityInput, + IdentityAdminCreateInput, + IdentityAdminFindManyInput, ApiIdentityService, Identity, } from '@pubkey-stack/api-identity-data-access' @@ -14,7 +14,7 @@ export class ApiIdentityAdminResolver { constructor(private readonly service: ApiIdentityService) {} @Mutation(() => Identity, { nullable: true }) - adminCreateIdentity(@Args('input') input: AdminCreateIdentityInput) { + adminCreateIdentity(@Args('input') input: IdentityAdminCreateInput) { return this.service.admin.createIdentity(input) } @Mutation(() => Boolean, { nullable: true }) @@ -22,7 +22,7 @@ export class ApiIdentityAdminResolver { return this.service.admin.deleteIdentity(identityId) } @Query(() => [Identity], { nullable: true }) - adminFindManyIdentity(@Args('input') input: AdminFindManyIdentityInput) { + adminFindManyIdentity(@Args('input') input: IdentityAdminFindManyInput) { return this.service.admin.findManyIdentity(input) } } diff --git a/libs/api/identity/feature/src/lib/api-identity-anon.resolver.ts b/libs/api/identity/feature/src/lib/api-identity-anon.resolver.ts index 45de04b..fc56270 100644 --- a/libs/api/identity/feature/src/lib/api-identity-anon.resolver.ts +++ b/libs/api/identity/feature/src/lib/api-identity-anon.resolver.ts @@ -3,8 +3,8 @@ import { BaseContext } from '@pubkey-stack/api-core-data-access' import { ApiIdentityService, IdentityChallenge, - RequestIdentityChallengeInput, - VerifyIdentityChallengeInput, + IdentityRequestChallengeInput, + IdentityVerifyChallengeInput, } from '@pubkey-stack/api-identity-data-access' @Resolver() @@ -12,12 +12,12 @@ export class ApiIdentityAnonResolver { constructor(private readonly service: ApiIdentityService) {} @Query(() => IdentityChallenge, { nullable: true }) - anonRequestIdentityChallenge(@Context() ctx: BaseContext, @Args('input') input: RequestIdentityChallengeInput) { + anonRequestIdentityChallenge(@Context() ctx: BaseContext, @Args('input') input: IdentityRequestChallengeInput) { return this.service.anon.requestIdentityChallenge(ctx, input) } @Mutation(() => IdentityChallenge, { nullable: true }) - anonVerifyIdentityChallenge(@Context() ctx: BaseContext, @Args('input') input: VerifyIdentityChallengeInput) { + anonVerifyIdentityChallenge(@Context() ctx: BaseContext, @Args('input') input: IdentityVerifyChallengeInput) { return this.service.anon.verifyIdentityChallenge(ctx, input) } } diff --git a/libs/api/identity/feature/src/lib/api-identity-user.resolver.ts b/libs/api/identity/feature/src/lib/api-identity-user.resolver.ts index 91b32c1..d7092ae 100644 --- a/libs/api/identity/feature/src/lib/api-identity-user.resolver.ts +++ b/libs/api/identity/feature/src/lib/api-identity-user.resolver.ts @@ -6,10 +6,10 @@ import { ApiIdentityService, Identity, IdentityChallenge, - LinkIdentityInput, - RequestIdentityChallengeInput, - UserFindManyIdentityInput, - VerifyIdentityChallengeInput, + IdentityRequestChallengeInput, + IdentityUserFindManyInput, + IdentityUserLinkInput, + IdentityVerifyChallengeInput, } from '@pubkey-stack/api-identity-data-access' @Resolver() @@ -26,13 +26,13 @@ export class ApiIdentityUserResolver { userRequestIdentityChallenge( @Context() ctx: BaseContext, @CtxUserId() userId: string, - @Args('input') input: RequestIdentityChallengeInput, + @Args('input') input: IdentityRequestChallengeInput, ) { return this.service.user.requestIdentityChallenge(ctx, userId, input) } @Mutation(() => Identity, { nullable: true }) - userLinkIdentity(@CtxUserId() userId: string, @Args('input') input: LinkIdentityInput) { + userLinkIdentity(@CtxUserId() userId: string, @Args('input') input: IdentityUserLinkInput) { return this.service.user.linkIdentity(userId, input) } @@ -40,13 +40,13 @@ export class ApiIdentityUserResolver { userVerifyIdentityChallenge( @Context() ctx: BaseContext, @CtxUserId() userId: string, - @Args('input') input: VerifyIdentityChallengeInput, + @Args('input') input: IdentityVerifyChallengeInput, ) { return this.service.user.verifyIdentityChallenge(ctx, userId, input) } @Query(() => [Identity], { nullable: true }) - userFindManyIdentity(@Args('input') input: UserFindManyIdentityInput) { + userFindManyIdentity(@Args('input') input: IdentityUserFindManyInput) { return this.service.user.findManyIdentity(input) } } diff --git a/libs/api/user/data-access/src/index.ts b/libs/api/user/data-access/src/index.ts index c37b392..d9257fa 100644 --- a/libs/api/user/data-access/src/index.ts +++ b/libs/api/user/data-access/src/index.ts @@ -1,10 +1,10 @@ export * from './lib/api-user.data-access.module' export * from './lib/api-user.service' -export * from './lib/dto/admin-create-user.input' -export * from './lib/dto/admin-find-many-user.input' -export * from './lib/dto/admin-update-user.input' -export * from './lib/dto/user-find-many-user.input' -export * from './lib/dto/user-update-user.input' +export * from './lib/dto/user-admin-create.input' +export * from './lib/dto/user-admin-find-many.input' +export * from './lib/dto/user-admin-update.input' +export * from './lib/dto/user-user-find-many.input' +export * from './lib/dto/user-user-update.input' export * from './lib/entity/user-role.enum' export * from './lib/entity/user-status.enum' export * from './lib/entity/user.entity' diff --git a/libs/api/user/data-access/src/lib/api-user-data-admin.service.ts b/libs/api/user/data-access/src/lib/api-user-data-admin.service.ts index 6c7231e..44c7ebd 100644 --- a/libs/api/user/data-access/src/lib/api-user-data-admin.service.ts +++ b/libs/api/user/data-access/src/lib/api-user-data-admin.service.ts @@ -1,9 +1,9 @@ import { Injectable, Logger } from '@nestjs/common' import { User as PrismaUser } from '@prisma/client' import { ApiCoreService, hashPassword, slugifyId } from '@pubkey-stack/api-core-data-access' -import { AdminCreateUserInput } from './dto/admin-create-user.input' -import { AdminFindManyUserInput } from './dto/admin-find-many-user.input' -import { AdminUpdateUserInput } from './dto/admin-update-user.input' +import { UserAdminCreateInput } from './dto/user-admin-create.input' +import { UserAdminFindManyInput } from './dto/user-admin-find-many.input' +import { UserAdminUpdateInput } from './dto/user-admin-update.input' import { UserPaging } from './entity/user.entity' import { getUserWhereAdminInput } from './helpers/get-user-where-admin.input' @@ -12,7 +12,7 @@ export class ApiUserDataAdminService { private readonly logger = new Logger(ApiUserDataAdminService.name) constructor(private readonly core: ApiCoreService) {} - async createUser(input: AdminCreateUserInput): Promise { + async createUser(input: UserAdminCreateInput): Promise { const username = slugifyId(input.username) if (!username.length) { throw new Error(`Username ${input.username} is not valid`) @@ -42,7 +42,7 @@ export class ApiUserDataAdminService { return !!deleted } - async findManyUser(input: AdminFindManyUserInput): Promise { + async findManyUser(input: UserAdminFindManyInput): Promise { return this.core.data.user .paginate({ orderBy: { createdAt: 'desc' }, @@ -63,7 +63,7 @@ export class ApiUserDataAdminService { return found } - async updateUser(userId: string, input: AdminUpdateUserInput): Promise { + async updateUser(userId: string, input: UserAdminUpdateInput): Promise { const exists = await this.findOneUser(userId) if (!exists) { diff --git a/libs/api/user/data-access/src/lib/api-user-data-user.service.ts b/libs/api/user/data-access/src/lib/api-user-data-user.service.ts index 2537bd7..91f793c 100644 --- a/libs/api/user/data-access/src/lib/api-user-data-user.service.ts +++ b/libs/api/user/data-access/src/lib/api-user-data-user.service.ts @@ -1,7 +1,7 @@ import { Injectable, Logger } from '@nestjs/common' import { ApiCoreService } from '@pubkey-stack/api-core-data-access' -import { UserFindManyUserInput } from './dto/user-find-many-user.input' -import { UserUpdateUserInput } from './dto/user-update-user.input' +import { UserUserFindManyInput } from './dto/user-user-find-many.input' +import { UserUserUpdateInput } from './dto/user-user-update.input' import { UserPaging } from './entity/user.entity' import { getUserWhereUserInput } from './helpers/get-user-where-user.input' @@ -10,7 +10,7 @@ export class ApiUserDataUserService { private readonly logger = new Logger(ApiUserDataUserService.name) constructor(private readonly core: ApiCoreService) {} - async findManyUser(input: UserFindManyUserInput): Promise { + async findManyUser(input: UserUserFindManyInput): Promise { return this.core.data.user .paginate({ orderBy: { createdAt: 'desc' }, @@ -20,7 +20,7 @@ export class ApiUserDataUserService { .then(([data, meta]) => ({ data, meta })) } - async updateUser(userId: string, input: UserUpdateUserInput) { + async updateUser(userId: string, input: UserUserUpdateInput) { return this.core.data.user.update({ where: { id: userId }, data: input }) } diff --git a/libs/api/user/data-access/src/lib/dto/admin-create-user.input.ts b/libs/api/user/data-access/src/lib/dto/user-admin-create.input.ts similarity index 81% rename from libs/api/user/data-access/src/lib/dto/admin-create-user.input.ts rename to libs/api/user/data-access/src/lib/dto/user-admin-create.input.ts index 2031708..3cd92b8 100644 --- a/libs/api/user/data-access/src/lib/dto/admin-create-user.input.ts +++ b/libs/api/user/data-access/src/lib/dto/user-admin-create.input.ts @@ -1,7 +1,7 @@ import { Field, InputType } from '@nestjs/graphql' @InputType() -export class AdminCreateUserInput { +export class UserAdminCreateInput { @Field() username!: string @Field({ nullable: true }) diff --git a/libs/api/user/data-access/src/lib/dto/admin-find-many-user.input.ts b/libs/api/user/data-access/src/lib/dto/user-admin-find-many.input.ts similarity index 87% rename from libs/api/user/data-access/src/lib/dto/admin-find-many-user.input.ts rename to libs/api/user/data-access/src/lib/dto/user-admin-find-many.input.ts index 198995b..d7432c1 100644 --- a/libs/api/user/data-access/src/lib/dto/admin-find-many-user.input.ts +++ b/libs/api/user/data-access/src/lib/dto/user-admin-find-many.input.ts @@ -4,7 +4,7 @@ import { UserRole } from '../entity/user-role.enum' import { UserStatus } from '../entity/user-status.enum' @InputType() -export class AdminFindManyUserInput extends PagingInput() { +export class UserAdminFindManyInput extends PagingInput() { @Field({ nullable: true }) search?: string @Field(() => UserRole, { nullable: true }) diff --git a/libs/api/user/data-access/src/lib/dto/admin-update-user.input.ts b/libs/api/user/data-access/src/lib/dto/user-admin-update.input.ts similarity index 93% rename from libs/api/user/data-access/src/lib/dto/admin-update-user.input.ts rename to libs/api/user/data-access/src/lib/dto/user-admin-update.input.ts index ad98699..0d37d8c 100644 --- a/libs/api/user/data-access/src/lib/dto/admin-update-user.input.ts +++ b/libs/api/user/data-access/src/lib/dto/user-admin-update.input.ts @@ -3,7 +3,7 @@ import { UserRole } from '../entity/user-role.enum' import { UserStatus } from '../entity/user-status.enum' @InputType() -export class AdminUpdateUserInput { +export class UserAdminUpdateInput { @Field(() => UserRole, { nullable: true }) role?: UserRole @Field(() => UserStatus, { nullable: true }) diff --git a/libs/api/user/data-access/src/lib/dto/user-find-many-user.input.ts b/libs/api/user/data-access/src/lib/dto/user-user-find-many.input.ts similarity index 75% rename from libs/api/user/data-access/src/lib/dto/user-find-many-user.input.ts rename to libs/api/user/data-access/src/lib/dto/user-user-find-many.input.ts index 9069ad7..889eea1 100644 --- a/libs/api/user/data-access/src/lib/dto/user-find-many-user.input.ts +++ b/libs/api/user/data-access/src/lib/dto/user-user-find-many.input.ts @@ -2,7 +2,7 @@ import { Field, InputType } from '@nestjs/graphql' import { PagingInput } from '@pubkey-stack/api-core-data-access' @InputType() -export class UserFindManyUserInput extends PagingInput() { +export class UserUserFindManyInput extends PagingInput() { @Field({ nullable: true }) search?: string } diff --git a/libs/api/user/data-access/src/lib/dto/user-update-user.input.ts b/libs/api/user/data-access/src/lib/dto/user-user-update.input.ts similarity index 85% rename from libs/api/user/data-access/src/lib/dto/user-update-user.input.ts rename to libs/api/user/data-access/src/lib/dto/user-user-update.input.ts index e06d8d2..fd88dd7 100644 --- a/libs/api/user/data-access/src/lib/dto/user-update-user.input.ts +++ b/libs/api/user/data-access/src/lib/dto/user-user-update.input.ts @@ -1,7 +1,7 @@ import { Field, InputType } from '@nestjs/graphql' @InputType() -export class UserUpdateUserInput { +export class UserUserUpdateInput { @Field({ nullable: true }) avatarUrl?: string @Field({ nullable: true }) diff --git a/libs/api/user/data-access/src/lib/helpers/get-user-where-admin.input.ts b/libs/api/user/data-access/src/lib/helpers/get-user-where-admin.input.ts index 92b1e37..a87f75a 100644 --- a/libs/api/user/data-access/src/lib/helpers/get-user-where-admin.input.ts +++ b/libs/api/user/data-access/src/lib/helpers/get-user-where-admin.input.ts @@ -1,7 +1,7 @@ import { Prisma } from '@prisma/client' -import { AdminFindManyUserInput } from '../dto/admin-find-many-user.input' +import { UserAdminFindManyInput } from '../dto/user-admin-find-many.input' -export function getUserWhereAdminInput(input: AdminFindManyUserInput): Prisma.UserWhereInput { +export function getUserWhereAdminInput(input: UserAdminFindManyInput): Prisma.UserWhereInput { const where: Prisma.UserWhereInput = {} if (input.search) { diff --git a/libs/api/user/data-access/src/lib/helpers/get-user-where-user.input.ts b/libs/api/user/data-access/src/lib/helpers/get-user-where-user.input.ts index 9146c35..0ac4abb 100644 --- a/libs/api/user/data-access/src/lib/helpers/get-user-where-user.input.ts +++ b/libs/api/user/data-access/src/lib/helpers/get-user-where-user.input.ts @@ -1,7 +1,7 @@ import { Prisma, UserStatus } from '@prisma/client' -import { UserFindManyUserInput } from '../dto/user-find-many-user.input' +import { UserUserFindManyInput } from '../dto/user-user-find-many.input' -export function getUserWhereUserInput(input: UserFindManyUserInput): Prisma.UserWhereInput { +export function getUserWhereUserInput(input: UserUserFindManyInput): Prisma.UserWhereInput { const where: Prisma.UserWhereInput = { status: { in: [UserStatus.Active], diff --git a/libs/api/user/feature/src/lib/api-user-admin.resolver.ts b/libs/api/user/feature/src/lib/api-user-admin.resolver.ts index 4b3f9f5..495bed0 100644 --- a/libs/api/user/feature/src/lib/api-user-admin.resolver.ts +++ b/libs/api/user/feature/src/lib/api-user-admin.resolver.ts @@ -2,9 +2,9 @@ import { UseGuards } from '@nestjs/common' import { Args, Mutation, Query, Resolver } from '@nestjs/graphql' import { ApiAuthGraphQLAdminGuard } from '@pubkey-stack/api-auth-data-access' import { - AdminCreateUserInput, - AdminFindManyUserInput, - AdminUpdateUserInput, + UserAdminCreateInput, + UserAdminFindManyInput, + UserAdminUpdateInput, ApiUserService, User, UserPaging, @@ -16,7 +16,7 @@ export class ApiUserAdminResolver { constructor(private readonly service: ApiUserService) {} @Mutation(() => User, { nullable: true }) - adminCreateUser(@Args('input') input: AdminCreateUserInput) { + adminCreateUser(@Args('input') input: UserAdminCreateInput) { return this.service.admin.createUser(input) } @@ -26,7 +26,7 @@ export class ApiUserAdminResolver { } @Query(() => UserPaging) - adminFindManyUser(@Args('input') input: AdminFindManyUserInput) { + adminFindManyUser(@Args('input') input: UserAdminFindManyInput) { return this.service.admin.findManyUser(input) } @@ -36,7 +36,7 @@ export class ApiUserAdminResolver { } @Mutation(() => User, { nullable: true }) - adminUpdateUser(@Args('userId') userId: string, @Args('input') input: AdminUpdateUserInput) { + adminUpdateUser(@Args('userId') userId: string, @Args('input') input: UserAdminUpdateInput) { return this.service.admin.updateUser(userId, input) } } diff --git a/libs/api/user/feature/src/lib/api-user-user.resolver.ts b/libs/api/user/feature/src/lib/api-user-user.resolver.ts index 099f57c..e62b486 100644 --- a/libs/api/user/feature/src/lib/api-user-user.resolver.ts +++ b/libs/api/user/feature/src/lib/api-user-user.resolver.ts @@ -4,9 +4,9 @@ import { ApiAuthGraphQLUserGuard, CtxUserId } from '@pubkey-stack/api-auth-data- import { ApiUserService, User, - UserFindManyUserInput, + UserUserFindManyInput, UserPaging, - UserUpdateUserInput, + UserUserUpdateInput, } from '@pubkey-stack/api-user-data-access' @Resolver() @@ -15,7 +15,7 @@ export class ApiUserUserResolver { constructor(private readonly service: ApiUserService) {} @Query(() => UserPaging) - userFindManyUser(@Args('input') input: UserFindManyUserInput) { + userFindManyUser(@Args('input') input: UserUserFindManyInput) { return this.service.user.findManyUser(input) } @@ -25,7 +25,7 @@ export class ApiUserUserResolver { } @Mutation(() => User, { nullable: true }) - userUpdateUser(@CtxUserId() userId: string, @Args('input') input: UserUpdateUserInput) { + userUpdateUser(@CtxUserId() userId: string, @Args('input') input: UserUserUpdateInput) { return this.service.user.updateUser(userId as string, input) } } diff --git a/libs/sdk/src/generated/graphql-sdk.ts b/libs/sdk/src/generated/graphql-sdk.ts index 9c2c6bf..e06a3dc 100644 --- a/libs/sdk/src/generated/graphql-sdk.ts +++ b/libs/sdk/src/generated/graphql-sdk.ts @@ -24,39 +24,6 @@ export type Scalars = { JSON: { input: any; output: any } } -export type AdminCreateIdentityInput = { - ownerId: Scalars['String']['input'] - provider: IdentityProvider - providerId: Scalars['String']['input'] -} - -export type AdminCreateUserInput = { - password?: InputMaybe - username: Scalars['String']['input'] -} - -export type AdminFindManyIdentityInput = { - ownerId?: InputMaybe - provider?: InputMaybe -} - -export type AdminFindManyUserInput = { - limit?: InputMaybe - page?: InputMaybe - role?: InputMaybe - search?: InputMaybe - status?: InputMaybe -} - -export type AdminUpdateUserInput = { - avatarUrl?: InputMaybe - developer?: InputMaybe - name?: InputMaybe - role?: InputMaybe - status?: InputMaybe - username?: InputMaybe -} - export type AppConfig = { __typename?: 'AppConfig' authDiscordEnabled: Scalars['Boolean']['output'] @@ -84,6 +51,17 @@ export type Identity = { verified?: Maybe } +export type IdentityAdminCreateInput = { + ownerId: Scalars['String']['input'] + provider: IdentityProvider + providerId: Scalars['String']['input'] +} + +export type IdentityAdminFindManyInput = { + ownerId?: InputMaybe + provider?: InputMaybe +} + export type IdentityChallenge = { __typename?: 'IdentityChallenge' challenge: Scalars['String']['output'] @@ -106,9 +84,26 @@ export enum IdentityProvider { Twitter = 'Twitter', } -export type LinkIdentityInput = { +export type IdentityRequestChallengeInput = { + provider: IdentityProvider + providerId: Scalars['String']['input'] +} + +export type IdentityUserFindManyInput = { + username: Scalars['String']['input'] +} + +export type IdentityUserLinkInput = { + provider: IdentityProvider + providerId: Scalars['String']['input'] +} + +export type IdentityVerifyChallengeInput = { + challenge: Scalars['String']['input'] provider: IdentityProvider providerId: Scalars['String']['input'] + signature: Scalars['String']['input'] + useLedger?: InputMaybe } export type LoginInput = { @@ -134,11 +129,11 @@ export type Mutation = { } export type MutationAdminCreateIdentityArgs = { - input: AdminCreateIdentityInput + input: IdentityAdminCreateInput } export type MutationAdminCreateUserArgs = { - input: AdminCreateUserInput + input: UserAdminCreateInput } export type MutationAdminDeleteIdentityArgs = { @@ -150,12 +145,12 @@ export type MutationAdminDeleteUserArgs = { } export type MutationAdminUpdateUserArgs = { - input: AdminUpdateUserInput + input: UserAdminUpdateInput userId: Scalars['String']['input'] } export type MutationAnonVerifyIdentityChallengeArgs = { - input: VerifyIdentityChallengeInput + input: IdentityVerifyChallengeInput } export type MutationLoginArgs = { @@ -171,15 +166,15 @@ export type MutationUserDeleteIdentityArgs = { } export type MutationUserLinkIdentityArgs = { - input: LinkIdentityInput + input: IdentityUserLinkInput } export type MutationUserUpdateUserArgs = { - input: UserUpdateUserInput + input: UserUserUpdateInput } export type MutationUserVerifyIdentityChallengeArgs = { - input: VerifyIdentityChallengeInput + input: IdentityVerifyChallengeInput } export type PagingMeta = { @@ -209,11 +204,11 @@ export type Query = { } export type QueryAdminFindManyIdentityArgs = { - input: AdminFindManyIdentityInput + input: IdentityAdminFindManyInput } export type QueryAdminFindManyUserArgs = { - input: AdminFindManyUserInput + input: UserAdminFindManyInput } export type QueryAdminFindOneUserArgs = { @@ -221,15 +216,15 @@ export type QueryAdminFindOneUserArgs = { } export type QueryAnonRequestIdentityChallengeArgs = { - input: RequestIdentityChallengeInput + input: IdentityRequestChallengeInput } export type QueryUserFindManyIdentityArgs = { - input: UserFindManyIdentityInput + input: IdentityUserFindManyInput } export type QueryUserFindManyUserArgs = { - input: UserFindManyUserInput + input: UserUserFindManyInput } export type QueryUserFindOneUserArgs = { @@ -237,7 +232,7 @@ export type QueryUserFindOneUserArgs = { } export type QueryUserRequestIdentityChallengeArgs = { - input: RequestIdentityChallengeInput + input: IdentityRequestChallengeInput } export type RegisterInput = { @@ -245,11 +240,6 @@ export type RegisterInput = { username: Scalars['String']['input'] } -export type RequestIdentityChallengeInput = { - provider: IdentityProvider - providerId: Scalars['String']['input'] -} - export type User = { __typename?: 'User' avatarUrl?: Maybe @@ -265,14 +255,26 @@ export type User = { username?: Maybe } -export type UserFindManyIdentityInput = { +export type UserAdminCreateInput = { + password?: InputMaybe username: Scalars['String']['input'] } -export type UserFindManyUserInput = { +export type UserAdminFindManyInput = { limit?: InputMaybe page?: InputMaybe + role?: InputMaybe search?: InputMaybe + status?: InputMaybe +} + +export type UserAdminUpdateInput = { + avatarUrl?: InputMaybe + developer?: InputMaybe + name?: InputMaybe + role?: InputMaybe + status?: InputMaybe + username?: InputMaybe } export type UserPaging = { @@ -292,20 +294,18 @@ export enum UserStatus { Inactive = 'Inactive', } -export type UserUpdateUserInput = { +export type UserUserFindManyInput = { + limit?: InputMaybe + page?: InputMaybe + search?: InputMaybe +} + +export type UserUserUpdateInput = { avatarUrl?: InputMaybe developer?: InputMaybe name?: InputMaybe } -export type VerifyIdentityChallengeInput = { - challenge: Scalars['String']['input'] - provider: IdentityProvider - providerId: Scalars['String']['input'] - signature: Scalars['String']['input'] - useLedger?: InputMaybe -} - export type LoginMutationVariables = Exact<{ input: LoginInput }> @@ -442,7 +442,7 @@ export type IdentityChallengeDetailsFragment = { } export type AdminFindManyIdentityQueryVariables = Exact<{ - input: AdminFindManyIdentityInput + input: IdentityAdminFindManyInput }> export type AdminFindManyIdentityQuery = { @@ -489,7 +489,7 @@ export type AdminFindManyIdentityQuery = { } export type AdminCreateIdentityMutationVariables = Exact<{ - input: AdminCreateIdentityInput + input: IdentityAdminCreateInput }> export type AdminCreateIdentityMutation = { @@ -516,7 +516,7 @@ export type AdminDeleteIdentityMutationVariables = Exact<{ export type AdminDeleteIdentityMutation = { __typename?: 'Mutation'; deleted?: boolean | null } export type UserFindManyIdentityQueryVariables = Exact<{ - input: UserFindManyIdentityInput + input: IdentityUserFindManyInput }> export type UserFindManyIdentityQuery = { @@ -543,7 +543,7 @@ export type UserDeleteIdentityMutationVariables = Exact<{ export type UserDeleteIdentityMutation = { __typename?: 'Mutation'; deleted?: boolean | null } export type UserRequestIdentityChallengeQueryVariables = Exact<{ - input: RequestIdentityChallengeInput + input: IdentityRequestChallengeInput }> export type UserRequestIdentityChallengeQuery = { @@ -564,7 +564,7 @@ export type UserRequestIdentityChallengeQuery = { } export type UserVerifyIdentityChallengeMutationVariables = Exact<{ - input: VerifyIdentityChallengeInput + input: IdentityVerifyChallengeInput }> export type UserVerifyIdentityChallengeMutation = { @@ -585,7 +585,7 @@ export type UserVerifyIdentityChallengeMutation = { } export type UserLinkIdentityMutationVariables = Exact<{ - input: LinkIdentityInput + input: IdentityUserLinkInput }> export type UserLinkIdentityMutation = { @@ -606,7 +606,7 @@ export type UserLinkIdentityMutation = { } export type AnonRequestIdentityChallengeQueryVariables = Exact<{ - input: RequestIdentityChallengeInput + input: IdentityRequestChallengeInput }> export type AnonRequestIdentityChallengeQuery = { @@ -627,7 +627,7 @@ export type AnonRequestIdentityChallengeQuery = { } export type AnonVerifyIdentityChallengeMutationVariables = Exact<{ - input: VerifyIdentityChallengeInput + input: IdentityVerifyChallengeInput }> export type AnonVerifyIdentityChallengeMutation = { @@ -662,7 +662,7 @@ export type UserDetailsFragment = { } export type AdminCreateUserMutationVariables = Exact<{ - input: AdminCreateUserInput + input: UserAdminCreateInput }> export type AdminCreateUserMutation = { @@ -689,7 +689,7 @@ export type AdminDeleteUserMutationVariables = Exact<{ export type AdminDeleteUserMutation = { __typename?: 'Mutation'; deleted?: boolean | null } export type AdminFindManyUserQueryVariables = Exact<{ - input: AdminFindManyUserInput + input: UserAdminFindManyInput }> export type AdminFindManyUserQuery = { @@ -758,7 +758,7 @@ export type AdminFindOneUserQuery = { export type AdminUpdateUserMutationVariables = Exact<{ userId: Scalars['String']['input'] - input: AdminUpdateUserInput + input: UserAdminUpdateInput }> export type AdminUpdateUserMutation = { @@ -779,7 +779,7 @@ export type AdminUpdateUserMutation = { } export type UserFindManyUserQueryVariables = Exact<{ - input: UserFindManyUserInput + input: UserUserFindManyInput }> export type UserFindManyUserQuery = { @@ -834,7 +834,7 @@ export type UserFindOneUserQuery = { } export type UserUpdateUserMutationVariables = Exact<{ - input: UserUpdateUserInput + input: UserUserUpdateInput }> export type UserUpdateUserMutation = { @@ -961,7 +961,7 @@ export const AppConfigDocument = gql` ${AppConfigDetailsFragmentDoc} ` export const AdminFindManyIdentityDocument = gql` - query adminFindManyIdentity($input: AdminFindManyIdentityInput!) { + query adminFindManyIdentity($input: IdentityAdminFindManyInput!) { items: adminFindManyIdentity(input: $input) { ...IdentityDetails challenges { @@ -977,7 +977,7 @@ export const AdminFindManyIdentityDocument = gql` ${UserDetailsFragmentDoc} ` export const AdminCreateIdentityDocument = gql` - mutation adminCreateIdentity($input: AdminCreateIdentityInput!) { + mutation adminCreateIdentity($input: IdentityAdminCreateInput!) { created: adminCreateIdentity(input: $input) { ...IdentityDetails } @@ -990,7 +990,7 @@ export const AdminDeleteIdentityDocument = gql` } ` export const UserFindManyIdentityDocument = gql` - query userFindManyIdentity($input: UserFindManyIdentityInput!) { + query userFindManyIdentity($input: IdentityUserFindManyInput!) { items: userFindManyIdentity(input: $input) { ...IdentityDetails } @@ -1003,7 +1003,7 @@ export const UserDeleteIdentityDocument = gql` } ` export const UserRequestIdentityChallengeDocument = gql` - query userRequestIdentityChallenge($input: RequestIdentityChallengeInput!) { + query userRequestIdentityChallenge($input: IdentityRequestChallengeInput!) { challenge: userRequestIdentityChallenge(input: $input) { ...IdentityChallengeDetails } @@ -1011,7 +1011,7 @@ export const UserRequestIdentityChallengeDocument = gql` ${IdentityChallengeDetailsFragmentDoc} ` export const UserVerifyIdentityChallengeDocument = gql` - mutation userVerifyIdentityChallenge($input: VerifyIdentityChallengeInput!) { + mutation userVerifyIdentityChallenge($input: IdentityVerifyChallengeInput!) { verified: userVerifyIdentityChallenge(input: $input) { ...IdentityChallengeDetails } @@ -1019,7 +1019,7 @@ export const UserVerifyIdentityChallengeDocument = gql` ${IdentityChallengeDetailsFragmentDoc} ` export const UserLinkIdentityDocument = gql` - mutation userLinkIdentity($input: LinkIdentityInput!) { + mutation userLinkIdentity($input: IdentityUserLinkInput!) { linked: userLinkIdentity(input: $input) { ...IdentityDetails } @@ -1027,7 +1027,7 @@ export const UserLinkIdentityDocument = gql` ${IdentityDetailsFragmentDoc} ` export const AnonRequestIdentityChallengeDocument = gql` - query anonRequestIdentityChallenge($input: RequestIdentityChallengeInput!) { + query anonRequestIdentityChallenge($input: IdentityRequestChallengeInput!) { challenge: anonRequestIdentityChallenge(input: $input) { ...IdentityChallengeDetails } @@ -1035,7 +1035,7 @@ export const AnonRequestIdentityChallengeDocument = gql` ${IdentityChallengeDetailsFragmentDoc} ` export const AnonVerifyIdentityChallengeDocument = gql` - mutation anonVerifyIdentityChallenge($input: VerifyIdentityChallengeInput!) { + mutation anonVerifyIdentityChallenge($input: IdentityVerifyChallengeInput!) { verified: anonVerifyIdentityChallenge(input: $input) { ...IdentityChallengeDetails } @@ -1043,7 +1043,7 @@ export const AnonVerifyIdentityChallengeDocument = gql` ${IdentityChallengeDetailsFragmentDoc} ` export const AdminCreateUserDocument = gql` - mutation adminCreateUser($input: AdminCreateUserInput!) { + mutation adminCreateUser($input: UserAdminCreateInput!) { created: adminCreateUser(input: $input) { ...UserDetails } @@ -1056,7 +1056,7 @@ export const AdminDeleteUserDocument = gql` } ` export const AdminFindManyUserDocument = gql` - query adminFindManyUser($input: AdminFindManyUserInput!) { + query adminFindManyUser($input: UserAdminFindManyInput!) { paging: adminFindManyUser(input: $input) { data { ...UserDetails @@ -1082,7 +1082,7 @@ export const AdminFindOneUserDocument = gql` ${UserDetailsFragmentDoc} ` export const AdminUpdateUserDocument = gql` - mutation adminUpdateUser($userId: String!, $input: AdminUpdateUserInput!) { + mutation adminUpdateUser($userId: String!, $input: UserAdminUpdateInput!) { updated: adminUpdateUser(userId: $userId, input: $input) { ...UserDetails } @@ -1090,7 +1090,7 @@ export const AdminUpdateUserDocument = gql` ${UserDetailsFragmentDoc} ` export const UserFindManyUserDocument = gql` - query userFindManyUser($input: UserFindManyUserInput!) { + query userFindManyUser($input: UserUserFindManyInput!) { paging: userFindManyUser(input: $input) { data { ...UserDetails @@ -1112,7 +1112,7 @@ export const UserFindOneUserDocument = gql` ${UserDetailsFragmentDoc} ` export const UserUpdateUserDocument = gql` - mutation userUpdateUser($input: UserUpdateUserInput!) { + mutation userUpdateUser($input: UserUserUpdateInput!) { updated: userUpdateUser(input: $input) { ...UserDetails } @@ -1645,7 +1645,7 @@ export const UserRoleSchema = z.nativeEnum(UserRole) export const UserStatusSchema = z.nativeEnum(UserStatus) -export function AdminCreateIdentityInputSchema(): z.ZodObject> { +export function IdentityAdminCreateInputSchema(): z.ZodObject> { return z.object({ ownerId: z.string(), provider: IdentityProviderSchema, @@ -1653,45 +1653,40 @@ export function AdminCreateIdentityInputSchema(): z.ZodObject> { +export function IdentityAdminFindManyInputSchema(): z.ZodObject> { return z.object({ - password: z.string().nullish(), - username: z.string(), + ownerId: z.string().nullish(), + provider: IdentityProviderSchema.nullish(), }) } -export function AdminFindManyIdentityInputSchema(): z.ZodObject> { +export function IdentityRequestChallengeInputSchema(): z.ZodObject> { return z.object({ - ownerId: z.string().nullish(), - provider: IdentityProviderSchema.nullish(), + provider: IdentityProviderSchema, + providerId: z.string(), }) } -export function AdminFindManyUserInputSchema(): z.ZodObject> { +export function IdentityUserFindManyInputSchema(): z.ZodObject> { return z.object({ - limit: z.number().nullish(), - page: z.number().nullish(), - role: UserRoleSchema.nullish(), - search: z.string().nullish(), - status: UserStatusSchema.nullish(), + username: z.string(), }) } -export function AdminUpdateUserInputSchema(): z.ZodObject> { +export function IdentityUserLinkInputSchema(): z.ZodObject> { return z.object({ - avatarUrl: z.string().nullish(), - developer: z.boolean().nullish(), - name: z.string().nullish(), - role: UserRoleSchema.nullish(), - status: UserStatusSchema.nullish(), - username: z.string().nullish(), + provider: IdentityProviderSchema, + providerId: z.string(), }) } -export function LinkIdentityInputSchema(): z.ZodObject> { +export function IdentityVerifyChallengeInputSchema(): z.ZodObject> { return z.object({ + challenge: z.string(), provider: IdentityProviderSchema, providerId: z.string(), + signature: z.string(), + useLedger: z.boolean().nullish(), }) } @@ -1709,41 +1704,46 @@ export function RegisterInputSchema(): z.ZodObject> { }) } -export function RequestIdentityChallengeInputSchema(): z.ZodObject> { - return z.object({ - provider: IdentityProviderSchema, - providerId: z.string(), - }) -} - -export function UserFindManyIdentityInputSchema(): z.ZodObject> { +export function UserAdminCreateInputSchema(): z.ZodObject> { return z.object({ + password: z.string().nullish(), username: z.string(), }) } -export function UserFindManyUserInputSchema(): z.ZodObject> { +export function UserAdminFindManyInputSchema(): z.ZodObject> { return z.object({ limit: z.number().nullish(), page: z.number().nullish(), + role: UserRoleSchema.nullish(), search: z.string().nullish(), + status: UserStatusSchema.nullish(), }) } -export function UserUpdateUserInputSchema(): z.ZodObject> { +export function UserAdminUpdateInputSchema(): z.ZodObject> { return z.object({ avatarUrl: z.string().nullish(), developer: z.boolean().nullish(), name: z.string().nullish(), + role: UserRoleSchema.nullish(), + status: UserStatusSchema.nullish(), + username: z.string().nullish(), }) } -export function VerifyIdentityChallengeInputSchema(): z.ZodObject> { +export function UserUserFindManyInputSchema(): z.ZodObject> { return z.object({ - challenge: z.string(), - provider: IdentityProviderSchema, - providerId: z.string(), - signature: z.string(), - useLedger: z.boolean().nullish(), + limit: z.number().nullish(), + page: z.number().nullish(), + search: z.string().nullish(), + }) +} + +export function UserUserUpdateInputSchema(): z.ZodObject> { + return z.object({ + avatarUrl: z.string().nullish(), + developer: z.boolean().nullish(), + name: z.string().nullish(), }) } diff --git a/libs/sdk/src/graphql/feature-identity.graphql b/libs/sdk/src/graphql/feature-identity.graphql index 0db05c5..38ab2ba 100644 --- a/libs/sdk/src/graphql/feature-identity.graphql +++ b/libs/sdk/src/graphql/feature-identity.graphql @@ -24,7 +24,7 @@ fragment IdentityChallengeDetails on IdentityChallenge { verified } -query adminFindManyIdentity($input: AdminFindManyIdentityInput!) { +query adminFindManyIdentity($input: IdentityAdminFindManyInput!) { items: adminFindManyIdentity(input: $input) { ...IdentityDetails challenges { @@ -36,7 +36,7 @@ query adminFindManyIdentity($input: AdminFindManyIdentityInput!) { } } -mutation adminCreateIdentity($input: AdminCreateIdentityInput!) { +mutation adminCreateIdentity($input: IdentityAdminCreateInput!) { created: adminCreateIdentity(input: $input) { ...IdentityDetails } @@ -46,7 +46,7 @@ mutation adminDeleteIdentity($identityId: String!) { deleted: adminDeleteIdentity(identityId: $identityId) } -query userFindManyIdentity($input: UserFindManyIdentityInput!) { +query userFindManyIdentity($input: IdentityUserFindManyInput!) { items: userFindManyIdentity(input: $input) { ...IdentityDetails } @@ -56,31 +56,31 @@ mutation userDeleteIdentity($identityId: String!) { deleted: userDeleteIdentity(identityId: $identityId) } -query userRequestIdentityChallenge($input: RequestIdentityChallengeInput!) { +query userRequestIdentityChallenge($input: IdentityRequestChallengeInput!) { challenge: userRequestIdentityChallenge(input: $input) { ...IdentityChallengeDetails } } -mutation userVerifyIdentityChallenge($input: VerifyIdentityChallengeInput!) { +mutation userVerifyIdentityChallenge($input: IdentityVerifyChallengeInput!) { verified: userVerifyIdentityChallenge(input: $input) { ...IdentityChallengeDetails } } -mutation userLinkIdentity($input: LinkIdentityInput!) { +mutation userLinkIdentity($input: IdentityUserLinkInput!) { linked: userLinkIdentity(input: $input) { ...IdentityDetails } } -query anonRequestIdentityChallenge($input: RequestIdentityChallengeInput!) { +query anonRequestIdentityChallenge($input: IdentityRequestChallengeInput!) { challenge: anonRequestIdentityChallenge(input: $input) { ...IdentityChallengeDetails } } -mutation anonVerifyIdentityChallenge($input: VerifyIdentityChallengeInput!) { +mutation anonVerifyIdentityChallenge($input: IdentityVerifyChallengeInput!) { verified: anonVerifyIdentityChallenge(input: $input) { ...IdentityChallengeDetails } diff --git a/libs/sdk/src/graphql/feature-user.graphql b/libs/sdk/src/graphql/feature-user.graphql index cb0777a..3cd3146 100644 --- a/libs/sdk/src/graphql/feature-user.graphql +++ b/libs/sdk/src/graphql/feature-user.graphql @@ -11,7 +11,7 @@ fragment UserDetails on User { username } -mutation adminCreateUser($input: AdminCreateUserInput!) { +mutation adminCreateUser($input: UserAdminCreateInput!) { created: adminCreateUser(input: $input) { ...UserDetails } @@ -21,7 +21,7 @@ mutation adminDeleteUser($userId: String!) { deleted: adminDeleteUser(userId: $userId) } -query adminFindManyUser($input: AdminFindManyUserInput!) { +query adminFindManyUser($input: UserAdminFindManyInput!) { paging: adminFindManyUser(input: $input) { data { ...UserDetails @@ -41,13 +41,13 @@ query adminFindOneUser($userId: String!) { } } -mutation adminUpdateUser($userId: String!, $input: AdminUpdateUserInput!) { +mutation adminUpdateUser($userId: String!, $input: UserAdminUpdateInput!) { updated: adminUpdateUser(userId: $userId, input: $input) { ...UserDetails } } -query userFindManyUser($input: UserFindManyUserInput!) { +query userFindManyUser($input: UserUserFindManyInput!) { paging: userFindManyUser(input: $input) { data { ...UserDetails @@ -64,7 +64,7 @@ query userFindOneUser($username: String!) { } } -mutation userUpdateUser($input: UserUpdateUserInput!) { +mutation userUpdateUser($input: UserUserUpdateInput!) { updated: userUpdateUser(input: $input) { ...UserDetails } diff --git a/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap b/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap index 37f923f..518cb9d 100644 --- a/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap +++ b/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap @@ -90,9 +90,9 @@ exports[`api-crud generator should create crud with modelOwnerId 1`] = ` "export * from './lib/test-company.data-access.module';", "export * from './lib/test-company.service';", "export * from './lib/entity/company.entity';", - "export * from './lib/dto/admin-create-company.input';", - "export * from './lib/dto/admin-find-many-company.input';", - "export * from './lib/dto/admin-update-company.input';", + "export * from './lib/dto/company-admin-create.input';", + "export * from './lib/dto/company-admin-find-many.input';", + "export * from './lib/dto/company-admin-update.input';", ], "isBinary": false, "path": "libs/test/company/data-access/src/index.ts", @@ -101,11 +101,11 @@ exports[`api-crud generator should create crud with modelOwnerId 1`] = ` "children": { "dto": { "children": { - "admin-create-company.input.ts": { + "company-admin-create.input.ts": { "content": [ "import { Field, InputType } from '@nestjs/graphql';", "@InputType()", - "export class AdminCreateCompanyInput {", + "export class CompanyAdminCreateInput {", "@Field()", "name!: string;", "@Field()", @@ -117,14 +117,14 @@ exports[`api-crud generator should create crud with modelOwnerId 1`] = ` "}", ], "isBinary": false, - "path": "libs/test/company/data-access/src/lib/dto/admin-create-company.input.ts", + "path": "libs/test/company/data-access/src/lib/dto/company-admin-create.input.ts", }, - "admin-find-many-company.input.ts": { + "company-admin-find-many.input.ts": { "content": [ "import { Field, InputType } from '@nestjs/graphql';", "import { PagingInput } from '@proj/test-core-data-access';", "@InputType()", - "export class AdminFindManyCompanyInput extends PagingInput() {", + "export class CompanyAdminFindManyInput extends PagingInput() {", "@Field()", "ownerId!: string;", "@Field({ nullable: true })", @@ -132,13 +132,13 @@ exports[`api-crud generator should create crud with modelOwnerId 1`] = ` "}", ], "isBinary": false, - "path": "libs/test/company/data-access/src/lib/dto/admin-find-many-company.input.ts", + "path": "libs/test/company/data-access/src/lib/dto/company-admin-find-many.input.ts", }, - "admin-update-company.input.ts": { + "company-admin-update.input.ts": { "content": [ "import { Field, InputType } from '@nestjs/graphql';", "@InputType()", - "export class AdminUpdateCompanyInput {", + "export class CompanyAdminUpdateInput {", "@Field({ nullable: true })", "name?: string;", "@Field({ nullable: true })", @@ -148,7 +148,7 @@ exports[`api-crud generator should create crud with modelOwnerId 1`] = ` "}", ], "isBinary": false, - "path": "libs/test/company/data-access/src/lib/dto/admin-update-company.input.ts", + "path": "libs/test/company/data-access/src/lib/dto/company-admin-update.input.ts", }, }, "path": "libs/test/company/data-access/src/lib/dto", @@ -218,23 +218,23 @@ exports[`api-crud generator should create crud with modelOwnerId 1`] = ` "test-company-data-admin.service.ts": { "content": [ "import { Injectable } from '@nestjs/common';", - "import { AdminCreateCompanyInput } from './dto/admin-create-company.input';", - "import { AdminFindManyCompanyInput } from './dto/admin-find-many-company.input';", - "import { AdminUpdateCompanyInput } from './dto/admin-update-company.input';", + "import { CompanyAdminCreateInput } from './dto/company-admin-create.input';", + "import { CompanyAdminFindManyInput } from './dto/company-admin-find-many.input';", + "import { CompanyAdminUpdateInput } from './dto/company-admin-update.input';", "import { CompanyPaging } from './entity/company.entity';", "import { getCompanyWhereAdminInput } from './helpers/get-company-where-admin.input';", "import { TestCompanyDataService } from './test-company-data.service';", "@Injectable()", "export class TestCompanyDataAdminService {", "constructor(private readonly data: TestCompanyDataService) {}", - "async createCompany(input: AdminCreateCompanyInput) {", + "async createCompany(input: CompanyAdminCreateInput) {", "return this.data.create(input);", "}", "async deleteCompany(companyId: string) {", "return this.data.delete(companyId);", "}", "async findManyCompany(", - "input: AdminFindManyCompanyInput", + "input: CompanyAdminFindManyInput", "): Promise {", "return this.data.findMany({", "orderBy: { createdAt: 'desc' },", @@ -246,7 +246,7 @@ exports[`api-crud generator should create crud with modelOwnerId 1`] = ` "async findOneCompany(companyId: string) {", "return this.data.findOne(companyId);", "}", - "async updateCompany(companyId: string, input: AdminUpdateCompanyInput) {", + "async updateCompany(companyId: string, input: CompanyAdminUpdateInput) {", "return this.data.update(companyId, input);", "}", "}", @@ -260,7 +260,7 @@ exports[`api-crud generator should create crud with modelOwnerId 1`] = ` "import { Prisma } from '@prisma/client';", "import {", "TestCoreService,", - "type PagingInputFields,", + "PagingInputFields,", "} from '@proj/test-core-data-access';", "import { CompanyPaging } from './entity/company.entity';", "@Injectable()", @@ -270,6 +270,7 @@ exports[`api-crud generator should create crud with modelOwnerId 1`] = ` "return this.core.data.company.create({ data: input });", "}", "async delete(companyId: string) {", + "await this.findOne(companyId);", "const deleted = await this.core.data.company.delete({", "where: { id: companyId },", "});", @@ -519,18 +520,18 @@ exports[`api-crud generator should create crud with modelOwnerId 1`] = ` "import { Mutation, Query, Args } from '@nestjs/graphql';", "import { UseGuards } from '@nestjs/common';", "import {", - "AdminCreateCompanyInput,", - "AdminFindManyCompanyInput,", + "CompanyAdminCreateInput,", + "CompanyAdminFindManyInput,", "Company,", "CompanyPaging,", - "AdminUpdateCompanyInput,", + "CompanyAdminUpdateInput,", "} from '@proj/test-company-data-access';", "@Resolver()", "@UseGuards(TestAuthGraphQLAdminGuard)", "export class TestCompanyAdminResolver {", "constructor(private readonly service: TestCompanyService) {}", "@Mutation(() => Company, { nullable: true })", - "adminCreateCompany(@Args('input') input: AdminCreateCompanyInput) {", + "adminCreateCompany(@Args('input') input: CompanyAdminCreateInput) {", "return this.service.admin.createCompany(input);", "}", "@Mutation(() => Boolean, { nullable: true })", @@ -538,7 +539,7 @@ exports[`api-crud generator should create crud with modelOwnerId 1`] = ` "return this.service.admin.deleteCompany(companyId);", "}", "@Query(() => CompanyPaging)", - "adminFindManyCompany(@Args('input') input: AdminFindManyCompanyInput) {", + "adminFindManyCompany(@Args('input') input: CompanyAdminFindManyInput) {", "return this.service.admin.findManyCompany(input);", "}", "@Query(() => Company, { nullable: true })", @@ -548,7 +549,7 @@ exports[`api-crud generator should create crud with modelOwnerId 1`] = ` "@Mutation(() => Company, { nullable: true })", "adminUpdateCompany(", "@Args('companyId') companyId: string,", - "@Args('input') input: AdminUpdateCompanyInput", + "@Args('input') input: CompanyAdminUpdateInput", ") {", "return this.service.admin.updateCompany(companyId, input);", "}", @@ -1161,7 +1162,7 @@ exports[`api-crud generator should create crud with modelOwnerId 1`] = ` "ownerId", "updatedAt", "}", - "query adminFindManyCompany($input: AdminFindManyCompanyInput!) {", + "query adminFindManyCompany($input: CompanyAdminFindManyInput!) {", "paging: adminFindManyCompany(input: $input) {", "data {", "...CompanyDetails", @@ -1176,14 +1177,14 @@ exports[`api-crud generator should create crud with modelOwnerId 1`] = ` "...CompanyDetails", "}", "}", - "mutation adminCreateCompany($input: AdminCreateCompanyInput!) {", + "mutation adminCreateCompany($input: CompanyAdminCreateInput!) {", "created: adminCreateCompany(input: $input) {", "...CompanyDetails", "}", "}", "mutation adminUpdateCompany(", "$companyId: String!", - "$input: AdminUpdateCompanyInput!", + "$input: CompanyAdminUpdateInput!", ") {", "updated: adminUpdateCompany(companyId: $companyId, input: $input) {", "...CompanyDetails", @@ -1393,12 +1394,12 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "export * from './lib/test-company.data-access.module';", "export * from './lib/test-company.service';", "export * from './lib/entity/company.entity';", - "export * from './lib/dto/user-create-company.input';", - "export * from './lib/dto/user-find-many-company.input';", - "export * from './lib/dto/user-update-company.input';", - "export * from './lib/dto/admin-create-company.input';", - "export * from './lib/dto/admin-find-many-company.input';", - "export * from './lib/dto/admin-update-company.input';", + "export * from './lib/dto/company-user-create.input';", + "export * from './lib/dto/company-user-find-many.input';", + "export * from './lib/dto/company-user-update.input';", + "export * from './lib/dto/company-admin-create.input';", + "export * from './lib/dto/company-admin-find-many.input';", + "export * from './lib/dto/company-admin-update.input';", ], "isBinary": false, "path": "libs/test/company/data-access/src/index.ts", @@ -1407,11 +1408,11 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "children": { "dto": { "children": { - "admin-create-company.input.ts": { + "company-admin-create.input.ts": { "content": [ "import { Field, InputType } from '@nestjs/graphql';", "@InputType()", - "export class AdminCreateCompanyInput {", + "export class CompanyAdminCreateInput {", "@Field()", "name!: string;", "@Field()", @@ -1423,14 +1424,14 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "}", ], "isBinary": false, - "path": "libs/test/company/data-access/src/lib/dto/admin-create-company.input.ts", + "path": "libs/test/company/data-access/src/lib/dto/company-admin-create.input.ts", }, - "admin-find-many-company.input.ts": { + "company-admin-find-many.input.ts": { "content": [ "import { Field, InputType } from '@nestjs/graphql';", "import { PagingInput } from '@proj/test-core-data-access';", "@InputType()", - "export class AdminFindManyCompanyInput extends PagingInput() {", + "export class CompanyAdminFindManyInput extends PagingInput() {", "@Field()", "ownerId!: string;", "@Field({ nullable: true })", @@ -1438,13 +1439,13 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "}", ], "isBinary": false, - "path": "libs/test/company/data-access/src/lib/dto/admin-find-many-company.input.ts", + "path": "libs/test/company/data-access/src/lib/dto/company-admin-find-many.input.ts", }, - "admin-update-company.input.ts": { + "company-admin-update.input.ts": { "content": [ "import { Field, InputType } from '@nestjs/graphql';", "@InputType()", - "export class AdminUpdateCompanyInput {", + "export class CompanyAdminUpdateInput {", "@Field({ nullable: true })", "name?: string;", "@Field({ nullable: true })", @@ -1454,13 +1455,13 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "}", ], "isBinary": false, - "path": "libs/test/company/data-access/src/lib/dto/admin-update-company.input.ts", + "path": "libs/test/company/data-access/src/lib/dto/company-admin-update.input.ts", }, - "user-create-company.input.ts": { + "company-user-create.input.ts": { "content": [ "import { Field, InputType } from '@nestjs/graphql';", "@InputType()", - "export class UserCreateCompanyInput {", + "export class CompanyUserCreateInput {", "@Field()", "name!: string;", "@Field()", @@ -1470,26 +1471,26 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "}", ], "isBinary": false, - "path": "libs/test/company/data-access/src/lib/dto/user-create-company.input.ts", + "path": "libs/test/company/data-access/src/lib/dto/company-user-create.input.ts", }, - "user-find-many-company.input.ts": { + "company-user-find-many.input.ts": { "content": [ "import { Field, InputType } from '@nestjs/graphql';", "import { PagingInput } from '@proj/test-core-data-access';", "@InputType()", - "export class UserFindManyCompanyInput extends PagingInput() {", + "export class CompanyUserFindManyInput extends PagingInput() {", "@Field({ nullable: true })", "search?: string;", "}", ], "isBinary": false, - "path": "libs/test/company/data-access/src/lib/dto/user-find-many-company.input.ts", + "path": "libs/test/company/data-access/src/lib/dto/company-user-find-many.input.ts", }, - "user-update-company.input.ts": { + "company-user-update.input.ts": { "content": [ "import { Field, InputType } from '@nestjs/graphql';", "@InputType()", - "export class UserUpdateCompanyInput {", + "export class CompanyUserUpdateInput {", "@Field({ nullable: true })", "name?: string;", "@Field({ nullable: true })", @@ -1499,7 +1500,7 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "}", ], "isBinary": false, - "path": "libs/test/company/data-access/src/lib/dto/user-update-company.input.ts", + "path": "libs/test/company/data-access/src/lib/dto/company-user-update.input.ts", }, }, "path": "libs/test/company/data-access/src/lib/dto", @@ -1592,23 +1593,23 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "test-company-data-admin.service.ts": { "content": [ "import { Injectable } from '@nestjs/common';", - "import { AdminCreateCompanyInput } from './dto/admin-create-company.input';", - "import { AdminFindManyCompanyInput } from './dto/admin-find-many-company.input';", - "import { AdminUpdateCompanyInput } from './dto/admin-update-company.input';", + "import { CompanyAdminCreateInput } from './dto/company-admin-create.input';", + "import { CompanyAdminFindManyInput } from './dto/company-admin-find-many.input';", + "import { CompanyAdminUpdateInput } from './dto/company-admin-update.input';", "import { CompanyPaging } from './entity/company.entity';", "import { getCompanyWhereAdminInput } from './helpers/get-company-where-admin.input';", "import { TestCompanyDataService } from './test-company-data.service';", "@Injectable()", "export class TestCompanyDataAdminService {", "constructor(private readonly data: TestCompanyDataService) {}", - "async createCompany(input: AdminCreateCompanyInput) {", + "async createCompany(input: CompanyAdminCreateInput) {", "return this.data.create(input);", "}", "async deleteCompany(companyId: string) {", "return this.data.delete(companyId);", "}", "async findManyCompany(", - "input: AdminFindManyCompanyInput", + "input: CompanyAdminFindManyInput", "): Promise {", "return this.data.findMany({", "orderBy: { createdAt: 'desc' },", @@ -1620,7 +1621,7 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "async findOneCompany(companyId: string) {", "return this.data.findOne(companyId);", "}", - "async updateCompany(companyId: string, input: AdminUpdateCompanyInput) {", + "async updateCompany(companyId: string, input: CompanyAdminUpdateInput) {", "return this.data.update(companyId, input);", "}", "}", @@ -1631,16 +1632,16 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "test-company-data-user.service.ts": { "content": [ "import { Injectable } from '@nestjs/common';", - "import { UserCreateCompanyInput } from './dto/user-create-company.input';", - "import { UserFindManyCompanyInput } from './dto/user-find-many-company.input';", - "import { UserUpdateCompanyInput } from './dto/user-update-company.input';", + "import { CompanyUserCreateInput } from './dto/company-user-create.input';", + "import { CompanyUserFindManyInput } from './dto/company-user-find-many.input';", + "import { CompanyUserUpdateInput } from './dto/company-user-update.input';", "import { CompanyPaging } from './entity/company.entity';", "import { getCompanyWhereUserInput } from './helpers/get-company-where-user.input';", "import { TestCompanyDataService } from './test-company-data.service';", "@Injectable()", "export class TestCompanyDataUserService {", "constructor(private readonly data: TestCompanyDataService) {}", - "async createCompany(ownerId: string, input: UserCreateCompanyInput) {", + "async createCompany(ownerId: string, input: CompanyUserCreateInput) {", "return this.data.create({ ...input, ownerId });", "}", "async deleteCompany(ownerId: string, companyId: string) {", @@ -1652,7 +1653,7 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "}", "async findManyCompany(", "ownerId: string,", - "input: UserFindManyCompanyInput", + "input: CompanyUserFindManyInput", "): Promise {", "return this.data.findMany({", "orderBy: { createdAt: 'desc' },", @@ -1671,7 +1672,7 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "async updateCompany(", "ownerId: string,", "companyId: string,", - "input: UserUpdateCompanyInput", + "input: CompanyUserUpdateInput", ") {", "const found = await this.data.findOne(companyId);", "if (found.ownerId !== ownerId) {", @@ -1690,7 +1691,7 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "import { Prisma } from '@prisma/client';", "import {", "TestCoreService,", - "type PagingInputFields,", + "PagingInputFields,", "} from '@proj/test-core-data-access';", "import { CompanyPaging } from './entity/company.entity';", "@Injectable()", @@ -1700,6 +1701,7 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "return this.core.data.company.create({ data: input });", "}", "async delete(companyId: string) {", + "await this.findOne(companyId);", "const deleted = await this.core.data.company.delete({", "where: { id: companyId },", "});", @@ -1953,18 +1955,18 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "import { Mutation, Query, Args } from '@nestjs/graphql';", "import { UseGuards } from '@nestjs/common';", "import {", - "AdminCreateCompanyInput,", - "AdminFindManyCompanyInput,", + "CompanyAdminCreateInput,", + "CompanyAdminFindManyInput,", "Company,", "CompanyPaging,", - "AdminUpdateCompanyInput,", + "CompanyAdminUpdateInput,", "} from '@proj/test-company-data-access';", "@Resolver()", "@UseGuards(TestAuthGraphQLAdminGuard)", "export class TestCompanyAdminResolver {", "constructor(private readonly service: TestCompanyService) {}", "@Mutation(() => Company, { nullable: true })", - "adminCreateCompany(@Args('input') input: AdminCreateCompanyInput) {", + "adminCreateCompany(@Args('input') input: CompanyAdminCreateInput) {", "return this.service.admin.createCompany(input);", "}", "@Mutation(() => Boolean, { nullable: true })", @@ -1972,7 +1974,7 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "return this.service.admin.deleteCompany(companyId);", "}", "@Query(() => CompanyPaging)", - "adminFindManyCompany(@Args('input') input: AdminFindManyCompanyInput) {", + "adminFindManyCompany(@Args('input') input: CompanyAdminFindManyInput) {", "return this.service.admin.findManyCompany(input);", "}", "@Query(() => Company, { nullable: true })", @@ -1982,7 +1984,7 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "@Mutation(() => Company, { nullable: true })", "adminUpdateCompany(", "@Args('companyId') companyId: string,", - "@Args('input') input: AdminUpdateCompanyInput", + "@Args('input') input: CompanyAdminUpdateInput", ") {", "return this.service.admin.updateCompany(companyId, input);", "}", @@ -2002,11 +2004,11 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "import { Mutation, Query, Args } from '@nestjs/graphql';", "import { UseGuards } from '@nestjs/common';", "import {", - "UserCreateCompanyInput,", - "UserFindManyCompanyInput,", + "CompanyUserCreateInput,", + "CompanyUserFindManyInput,", "Company,", "CompanyPaging,", - "UserUpdateCompanyInput,", + "CompanyUserUpdateInput,", "} from '@proj/test-company-data-access';", "@Resolver()", "@UseGuards(TestAuthGraphQLUserGuard)", @@ -2015,7 +2017,7 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "@Mutation(() => Company, { nullable: true })", "userCreateCompany(", "@CtxUserId() ownerId: string,", - "@Args('input') input: UserCreateCompanyInput", + "@Args('input') input: CompanyUserCreateInput", ") {", "return this.service.user.createCompany(ownerId, input);", "}", @@ -2029,7 +2031,7 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "@Query(() => CompanyPaging)", "userFindManyCompany(", "@CtxUserId() ownerId: string,", - "@Args('input') input: UserFindManyCompanyInput", + "@Args('input') input: CompanyUserFindManyInput", ") {", "return this.service.user.findManyCompany(ownerId, input);", "}", @@ -2044,7 +2046,7 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "userUpdateCompany(", "@CtxUserId() ownerId: string,", "@Args('companyId') companyId: string,", - "@Args('input') input: UserUpdateCompanyInput", + "@Args('input') input: CompanyUserUpdateInput", ") {", "return this.service.user.updateCompany(ownerId, companyId, input);", "}", @@ -2662,7 +2664,7 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "ownerId", "updatedAt", "}", - "query userFindManyCompany($input: UserFindManyCompanyInput!) {", + "query userFindManyCompany($input: CompanyUserFindManyInput!) {", "paging: userFindManyCompany(input: $input) {", "data {", "...CompanyDetails", @@ -2677,14 +2679,14 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "...CompanyDetails", "}", "}", - "mutation userCreateCompany($input: UserCreateCompanyInput!) {", + "mutation userCreateCompany($input: CompanyUserCreateInput!) {", "created: userCreateCompany(input: $input) {", "...CompanyDetails", "}", "}", "mutation userUpdateCompany(", "$companyId: String!", - "$input: UserUpdateCompanyInput!", + "$input: CompanyUserUpdateInput!", ") {", "updated: userUpdateCompany(companyId: $companyId, input: $input) {", "...CompanyDetails", @@ -2693,7 +2695,7 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "mutation userDeleteCompany($companyId: String!) {", "deleted: userDeleteCompany(companyId: $companyId)", "}", - "query adminFindManyCompany($input: AdminFindManyCompanyInput!) {", + "query adminFindManyCompany($input: CompanyAdminFindManyInput!) {", "paging: adminFindManyCompany(input: $input) {", "data {", "...CompanyDetails", @@ -2708,14 +2710,14 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "...CompanyDetails", "}", "}", - "mutation adminCreateCompany($input: AdminCreateCompanyInput!) {", + "mutation adminCreateCompany($input: CompanyAdminCreateInput!) {", "created: adminCreateCompany(input: $input) {", "...CompanyDetails", "}", "}", "mutation adminUpdateCompany(", "$companyId: String!", - "$input: AdminUpdateCompanyInput!", + "$input: CompanyAdminUpdateInput!", ") {", "updated: adminUpdateCompany(companyId: $companyId, input: $input) {", "...CompanyDetails", @@ -2925,9 +2927,9 @@ exports[`api-crud generator should create crud with modelParentId 1`] = ` "export * from './lib/test-company.data-access.module';", "export * from './lib/test-company.service';", "export * from './lib/entity/company.entity';", - "export * from './lib/dto/admin-create-company.input';", - "export * from './lib/dto/admin-find-many-company.input';", - "export * from './lib/dto/admin-update-company.input';", + "export * from './lib/dto/company-admin-create.input';", + "export * from './lib/dto/company-admin-find-many.input';", + "export * from './lib/dto/company-admin-update.input';", ], "isBinary": false, "path": "libs/test/company/data-access/src/index.ts", @@ -2936,11 +2938,11 @@ exports[`api-crud generator should create crud with modelParentId 1`] = ` "children": { "dto": { "children": { - "admin-create-company.input.ts": { + "company-admin-create.input.ts": { "content": [ "import { Field, InputType } from '@nestjs/graphql';", "@InputType()", - "export class AdminCreateCompanyInput {", + "export class CompanyAdminCreateInput {", "@Field()", "name!: string;", "@Field()", @@ -2950,14 +2952,14 @@ exports[`api-crud generator should create crud with modelParentId 1`] = ` "}", ], "isBinary": false, - "path": "libs/test/company/data-access/src/lib/dto/admin-create-company.input.ts", + "path": "libs/test/company/data-access/src/lib/dto/company-admin-create.input.ts", }, - "admin-find-many-company.input.ts": { + "company-admin-find-many.input.ts": { "content": [ "import { Field, InputType } from '@nestjs/graphql';", "import { PagingInput } from '@proj/test-core-data-access';", "@InputType()", - "export class AdminFindManyCompanyInput extends PagingInput() {", + "export class CompanyAdminFindManyInput extends PagingInput() {", "@Field()", "ownerId!: string;", "@Field({ nullable: true })", @@ -2965,13 +2967,13 @@ exports[`api-crud generator should create crud with modelParentId 1`] = ` "}", ], "isBinary": false, - "path": "libs/test/company/data-access/src/lib/dto/admin-find-many-company.input.ts", + "path": "libs/test/company/data-access/src/lib/dto/company-admin-find-many.input.ts", }, - "admin-update-company.input.ts": { + "company-admin-update.input.ts": { "content": [ "import { Field, InputType } from '@nestjs/graphql';", "@InputType()", - "export class AdminUpdateCompanyInput {", + "export class CompanyAdminUpdateInput {", "@Field({ nullable: true })", "name?: string;", "@Field({ nullable: true })", @@ -2981,7 +2983,7 @@ exports[`api-crud generator should create crud with modelParentId 1`] = ` "}", ], "isBinary": false, - "path": "libs/test/company/data-access/src/lib/dto/admin-update-company.input.ts", + "path": "libs/test/company/data-access/src/lib/dto/company-admin-update.input.ts", }, }, "path": "libs/test/company/data-access/src/lib/dto", @@ -3051,23 +3053,23 @@ exports[`api-crud generator should create crud with modelParentId 1`] = ` "test-company-data-admin.service.ts": { "content": [ "import { Injectable } from '@nestjs/common';", - "import { AdminCreateCompanyInput } from './dto/admin-create-company.input';", - "import { AdminFindManyCompanyInput } from './dto/admin-find-many-company.input';", - "import { AdminUpdateCompanyInput } from './dto/admin-update-company.input';", + "import { CompanyAdminCreateInput } from './dto/company-admin-create.input';", + "import { CompanyAdminFindManyInput } from './dto/company-admin-find-many.input';", + "import { CompanyAdminUpdateInput } from './dto/company-admin-update.input';", "import { CompanyPaging } from './entity/company.entity';", "import { getCompanyWhereAdminInput } from './helpers/get-company-where-admin.input';", "import { TestCompanyDataService } from './test-company-data.service';", "@Injectable()", "export class TestCompanyDataAdminService {", "constructor(private readonly data: TestCompanyDataService) {}", - "async createCompany(input: AdminCreateCompanyInput) {", + "async createCompany(input: CompanyAdminCreateInput) {", "return this.data.create(input);", "}", "async deleteCompany(companyId: string) {", "return this.data.delete(companyId);", "}", "async findManyCompany(", - "input: AdminFindManyCompanyInput", + "input: CompanyAdminFindManyInput", "): Promise {", "return this.data.findMany({", "orderBy: { createdAt: 'desc' },", @@ -3079,7 +3081,7 @@ exports[`api-crud generator should create crud with modelParentId 1`] = ` "async findOneCompany(companyId: string) {", "return this.data.findOne(companyId);", "}", - "async updateCompany(companyId: string, input: AdminUpdateCompanyInput) {", + "async updateCompany(companyId: string, input: CompanyAdminUpdateInput) {", "return this.data.update(companyId, input);", "}", "}", @@ -3093,7 +3095,7 @@ exports[`api-crud generator should create crud with modelParentId 1`] = ` "import { Prisma } from '@prisma/client';", "import {", "TestCoreService,", - "type PagingInputFields,", + "PagingInputFields,", "} from '@proj/test-core-data-access';", "import { CompanyPaging } from './entity/company.entity';", "@Injectable()", @@ -3103,6 +3105,7 @@ exports[`api-crud generator should create crud with modelParentId 1`] = ` "return this.core.data.company.create({ data: input });", "}", "async delete(companyId: string) {", + "await this.findOne(companyId);", "const deleted = await this.core.data.company.delete({", "where: { id: companyId },", "});", @@ -3352,18 +3355,18 @@ exports[`api-crud generator should create crud with modelParentId 1`] = ` "import { Mutation, Query, Args } from '@nestjs/graphql';", "import { UseGuards } from '@nestjs/common';", "import {", - "AdminCreateCompanyInput,", - "AdminFindManyCompanyInput,", + "CompanyAdminCreateInput,", + "CompanyAdminFindManyInput,", "Company,", "CompanyPaging,", - "AdminUpdateCompanyInput,", + "CompanyAdminUpdateInput,", "} from '@proj/test-company-data-access';", "@Resolver()", "@UseGuards(TestAuthGraphQLAdminGuard)", "export class TestCompanyAdminResolver {", "constructor(private readonly service: TestCompanyService) {}", "@Mutation(() => Company, { nullable: true })", - "adminCreateCompany(@Args('input') input: AdminCreateCompanyInput) {", + "adminCreateCompany(@Args('input') input: CompanyAdminCreateInput) {", "return this.service.admin.createCompany(input);", "}", "@Mutation(() => Boolean, { nullable: true })", @@ -3371,7 +3374,7 @@ exports[`api-crud generator should create crud with modelParentId 1`] = ` "return this.service.admin.deleteCompany(companyId);", "}", "@Query(() => CompanyPaging)", - "adminFindManyCompany(@Args('input') input: AdminFindManyCompanyInput) {", + "adminFindManyCompany(@Args('input') input: CompanyAdminFindManyInput) {", "return this.service.admin.findManyCompany(input);", "}", "@Query(() => Company, { nullable: true })", @@ -3381,7 +3384,7 @@ exports[`api-crud generator should create crud with modelParentId 1`] = ` "@Mutation(() => Company, { nullable: true })", "adminUpdateCompany(", "@Args('companyId') companyId: string,", - "@Args('input') input: AdminUpdateCompanyInput", + "@Args('input') input: CompanyAdminUpdateInput", ") {", "return this.service.admin.updateCompany(companyId, input);", "}", @@ -3993,7 +3996,7 @@ exports[`api-crud generator should create crud with modelParentId 1`] = ` "phone", "updatedAt", "}", - "query adminFindManyCompany($input: AdminFindManyCompanyInput!) {", + "query adminFindManyCompany($input: CompanyAdminFindManyInput!) {", "paging: adminFindManyCompany(input: $input) {", "data {", "...CompanyDetails", @@ -4008,14 +4011,14 @@ exports[`api-crud generator should create crud with modelParentId 1`] = ` "...CompanyDetails", "}", "}", - "mutation adminCreateCompany($input: AdminCreateCompanyInput!) {", + "mutation adminCreateCompany($input: CompanyAdminCreateInput!) {", "created: adminCreateCompany(input: $input) {", "...CompanyDetails", "}", "}", "mutation adminUpdateCompany(", "$companyId: String!", - "$input: AdminUpdateCompanyInput!", + "$input: CompanyAdminUpdateInput!", ") {", "updated: adminUpdateCompany(companyId: $companyId, input: $input) {", "...CompanyDetails", @@ -4225,9 +4228,9 @@ exports[`api-crud generator should run successfully 1`] = ` "export * from './lib/test-company.data-access.module';", "export * from './lib/test-company.service';", "export * from './lib/entity/company.entity';", - "export * from './lib/dto/admin-create-company.input';", - "export * from './lib/dto/admin-find-many-company.input';", - "export * from './lib/dto/admin-update-company.input';", + "export * from './lib/dto/company-admin-create.input';", + "export * from './lib/dto/company-admin-find-many.input';", + "export * from './lib/dto/company-admin-update.input';", ], "isBinary": false, "path": "libs/test/company/data-access/src/index.ts", @@ -4236,11 +4239,11 @@ exports[`api-crud generator should run successfully 1`] = ` "children": { "dto": { "children": { - "admin-create-company.input.ts": { + "company-admin-create.input.ts": { "content": [ "import { Field, InputType } from '@nestjs/graphql';", "@InputType()", - "export class AdminCreateCompanyInput {", + "export class CompanyAdminCreateInput {", "@Field()", "name!: string;", "@Field()", @@ -4250,26 +4253,26 @@ exports[`api-crud generator should run successfully 1`] = ` "}", ], "isBinary": false, - "path": "libs/test/company/data-access/src/lib/dto/admin-create-company.input.ts", + "path": "libs/test/company/data-access/src/lib/dto/company-admin-create.input.ts", }, - "admin-find-many-company.input.ts": { + "company-admin-find-many.input.ts": { "content": [ "import { Field, InputType } from '@nestjs/graphql';", "import { PagingInput } from '@proj/test-core-data-access';", "@InputType()", - "export class AdminFindManyCompanyInput extends PagingInput() {", + "export class CompanyAdminFindManyInput extends PagingInput() {", "@Field({ nullable: true })", "search?: string;", "}", ], "isBinary": false, - "path": "libs/test/company/data-access/src/lib/dto/admin-find-many-company.input.ts", + "path": "libs/test/company/data-access/src/lib/dto/company-admin-find-many.input.ts", }, - "admin-update-company.input.ts": { + "company-admin-update.input.ts": { "content": [ "import { Field, InputType } from '@nestjs/graphql';", "@InputType()", - "export class AdminUpdateCompanyInput {", + "export class CompanyAdminUpdateInput {", "@Field({ nullable: true })", "name?: string;", "@Field({ nullable: true })", @@ -4279,7 +4282,7 @@ exports[`api-crud generator should run successfully 1`] = ` "}", ], "isBinary": false, - "path": "libs/test/company/data-access/src/lib/dto/admin-update-company.input.ts", + "path": "libs/test/company/data-access/src/lib/dto/company-admin-update.input.ts", }, }, "path": "libs/test/company/data-access/src/lib/dto", @@ -4342,23 +4345,23 @@ exports[`api-crud generator should run successfully 1`] = ` "test-company-data-admin.service.ts": { "content": [ "import { Injectable } from '@nestjs/common';", - "import { AdminCreateCompanyInput } from './dto/admin-create-company.input';", - "import { AdminFindManyCompanyInput } from './dto/admin-find-many-company.input';", - "import { AdminUpdateCompanyInput } from './dto/admin-update-company.input';", + "import { CompanyAdminCreateInput } from './dto/company-admin-create.input';", + "import { CompanyAdminFindManyInput } from './dto/company-admin-find-many.input';", + "import { CompanyAdminUpdateInput } from './dto/company-admin-update.input';", "import { CompanyPaging } from './entity/company.entity';", "import { getCompanyWhereAdminInput } from './helpers/get-company-where-admin.input';", "import { TestCompanyDataService } from './test-company-data.service';", "@Injectable()", "export class TestCompanyDataAdminService {", "constructor(private readonly data: TestCompanyDataService) {}", - "async createCompany(input: AdminCreateCompanyInput) {", + "async createCompany(input: CompanyAdminCreateInput) {", "return this.data.create(input);", "}", "async deleteCompany(companyId: string) {", "return this.data.delete(companyId);", "}", "async findManyCompany(", - "input: AdminFindManyCompanyInput", + "input: CompanyAdminFindManyInput", "): Promise {", "return this.data.findMany({", "orderBy: { createdAt: 'desc' },", @@ -4370,7 +4373,7 @@ exports[`api-crud generator should run successfully 1`] = ` "async findOneCompany(companyId: string) {", "return this.data.findOne(companyId);", "}", - "async updateCompany(companyId: string, input: AdminUpdateCompanyInput) {", + "async updateCompany(companyId: string, input: CompanyAdminUpdateInput) {", "return this.data.update(companyId, input);", "}", "}", @@ -4384,7 +4387,7 @@ exports[`api-crud generator should run successfully 1`] = ` "import { Prisma } from '@prisma/client';", "import {", "TestCoreService,", - "type PagingInputFields,", + "PagingInputFields,", "} from '@proj/test-core-data-access';", "import { CompanyPaging } from './entity/company.entity';", "@Injectable()", @@ -4394,6 +4397,7 @@ exports[`api-crud generator should run successfully 1`] = ` "return this.core.data.company.create({ data: input });", "}", "async delete(companyId: string) {", + "await this.findOne(companyId);", "const deleted = await this.core.data.company.delete({", "where: { id: companyId },", "});", @@ -4643,18 +4647,18 @@ exports[`api-crud generator should run successfully 1`] = ` "import { Mutation, Query, Args } from '@nestjs/graphql';", "import { UseGuards } from '@nestjs/common';", "import {", - "AdminCreateCompanyInput,", - "AdminFindManyCompanyInput,", + "CompanyAdminCreateInput,", + "CompanyAdminFindManyInput,", "Company,", "CompanyPaging,", - "AdminUpdateCompanyInput,", + "CompanyAdminUpdateInput,", "} from '@proj/test-company-data-access';", "@Resolver()", "@UseGuards(TestAuthGraphQLAdminGuard)", "export class TestCompanyAdminResolver {", "constructor(private readonly service: TestCompanyService) {}", "@Mutation(() => Company, { nullable: true })", - "adminCreateCompany(@Args('input') input: AdminCreateCompanyInput) {", + "adminCreateCompany(@Args('input') input: CompanyAdminCreateInput) {", "return this.service.admin.createCompany(input);", "}", "@Mutation(() => Boolean, { nullable: true })", @@ -4662,7 +4666,7 @@ exports[`api-crud generator should run successfully 1`] = ` "return this.service.admin.deleteCompany(companyId);", "}", "@Query(() => CompanyPaging)", - "adminFindManyCompany(@Args('input') input: AdminFindManyCompanyInput) {", + "adminFindManyCompany(@Args('input') input: CompanyAdminFindManyInput) {", "return this.service.admin.findManyCompany(input);", "}", "@Query(() => Company, { nullable: true })", @@ -4672,7 +4676,7 @@ exports[`api-crud generator should run successfully 1`] = ` "@Mutation(() => Company, { nullable: true })", "adminUpdateCompany(", "@Args('companyId') companyId: string,", - "@Args('input') input: AdminUpdateCompanyInput", + "@Args('input') input: CompanyAdminUpdateInput", ") {", "return this.service.admin.updateCompany(companyId, input);", "}", @@ -5284,7 +5288,7 @@ exports[`api-crud generator should run successfully 1`] = ` "phone", "updatedAt", "}", - "query adminFindManyCompany($input: AdminFindManyCompanyInput!) {", + "query adminFindManyCompany($input: CompanyAdminFindManyInput!) {", "paging: adminFindManyCompany(input: $input) {", "data {", "...CompanyDetails", @@ -5299,14 +5303,14 @@ exports[`api-crud generator should run successfully 1`] = ` "...CompanyDetails", "}", "}", - "mutation adminCreateCompany($input: AdminCreateCompanyInput!) {", + "mutation adminCreateCompany($input: CompanyAdminCreateInput!) {", "created: adminCreateCompany(input: $input) {", "...CompanyDetails", "}", "}", "mutation adminUpdateCompany(", "$companyId: String!", - "$input: AdminUpdateCompanyInput!", + "$input: CompanyAdminUpdateInput!", ") {", "updated: adminUpdateCompany(companyId: $companyId, input: $input) {", "...CompanyDetails", diff --git a/libs/tools/src/generators/api-feature/__snapshots__/api-feature-generator.spec.ts.snap b/libs/tools/src/generators/api-feature/__snapshots__/api-feature-generator.spec.ts.snap index 859c925..23d3a99 100644 --- a/libs/tools/src/generators/api-feature/__snapshots__/api-feature-generator.spec.ts.snap +++ b/libs/tools/src/generators/api-feature/__snapshots__/api-feature-generator.spec.ts.snap @@ -4,20 +4,20 @@ exports[`api-feature generator should generate the feature libraries with crud f "export * from './lib/api-test.data-access.module'; export * from './lib/api-test.service'; export * from './lib/entity/test.entity'; -export * from './lib/dto/admin-create-test.input'; -export * from './lib/dto/admin-find-many-test.input'; -export * from './lib/dto/admin-update-test.input'; -export * from './lib/dto/user-create-test.input'; -export * from './lib/dto/user-find-many-test.input'; -export * from './lib/dto/user-update-test.input'; +export * from './lib/dto/test-admin-create.input'; +export * from './lib/dto/test-admin-find-many.input'; +export * from './lib/dto/test-admin-update.input'; +export * from './lib/dto/test-user-create.input'; +export * from './lib/dto/test-user-find-many.input'; +export * from './lib/dto/test-user-update.input'; " `; exports[`api-feature generator should generate the feature libraries with crud for admin and user 4`] = ` "import { Injectable } from '@nestjs/common'; -import { AdminCreateTestInput } from './dto/admin-create-test.input'; -import { AdminFindManyTestInput } from './dto/admin-find-many-test.input'; -import { AdminUpdateTestInput } from './dto/admin-update-test.input'; +import { TestAdminCreateInput } from './dto/test-admin-create.input'; +import { TestAdminFindManyInput } from './dto/test-admin-find-many.input'; +import { TestAdminUpdateInput } from './dto/test-admin-update.input'; import { TestPaging } from './entity/test.entity'; import { getTestWhereAdminInput } from './helpers/get-test-where-admin.input'; import { ApiTestDataService } from './api-test-data.service'; @@ -26,7 +26,7 @@ import { ApiTestDataService } from './api-test-data.service'; export class ApiTestDataAdminService { constructor(private readonly data: ApiTestDataService) {} - async createTest(input: AdminCreateTestInput) { + async createTest(input: TestAdminCreateInput) { return this.data.create(input); } @@ -34,7 +34,7 @@ export class ApiTestDataAdminService { return this.data.delete(testId); } - async findManyTest(input: AdminFindManyTestInput): Promise { + async findManyTest(input: TestAdminFindManyInput): Promise { return this.data.findMany({ orderBy: { createdAt: 'desc' }, where: getTestWhereAdminInput(input), @@ -47,7 +47,7 @@ export class ApiTestDataAdminService { return this.data.findOne(testId); } - async updateTest(testId: string, input: AdminUpdateTestInput) { + async updateTest(testId: string, input: TestAdminUpdateInput) { return this.data.update(testId, input); } } @@ -56,9 +56,9 @@ export class ApiTestDataAdminService { exports[`api-feature generator should generate the feature libraries with crud for admin and user 5`] = ` "import { Injectable } from '@nestjs/common'; -import { UserCreateTestInput } from './dto/user-create-test.input'; -import { UserFindManyTestInput } from './dto/user-find-many-test.input'; -import { UserUpdateTestInput } from './dto/user-update-test.input'; +import { TestUserCreateInput } from './dto/test-user-create.input'; +import { TestUserFindManyInput } from './dto/test-user-find-many.input'; +import { TestUserUpdateInput } from './dto/test-user-update.input'; import { TestPaging } from './entity/test.entity'; import { getTestWhereUserInput } from './helpers/get-test-where-user.input'; import { ApiTestDataService } from './api-test-data.service'; @@ -67,7 +67,7 @@ import { ApiTestDataService } from './api-test-data.service'; export class ApiTestDataUserService { constructor(private readonly data: ApiTestDataService) {} - async createTest(input: UserCreateTestInput) { + async createTest(input: TestUserCreateInput) { return this.data.create(input); } @@ -75,7 +75,7 @@ export class ApiTestDataUserService { return this.data.delete(testId); } - async findManyTest(input: UserFindManyTestInput): Promise { + async findManyTest(input: TestUserFindManyInput): Promise { return this.data.findMany({ orderBy: { createdAt: 'desc' }, where: getTestWhereUserInput(input), @@ -88,7 +88,7 @@ export class ApiTestDataUserService { return this.data.findOne(testId); } - async updateTest(testId: string, input: UserUpdateTestInput) { + async updateTest(testId: string, input: TestUserUpdateInput) { return this.data.update(testId, input); } } @@ -98,10 +98,7 @@ export class ApiTestDataUserService { exports[`api-feature generator should generate the feature libraries with crud for admin and user 6`] = ` "import { Injectable } from '@nestjs/common'; import { Prisma } from '@prisma/client'; -import { - ApiCoreService, - type PagingInputFields, -} from '@proj/api-core-data-access'; +import { ApiCoreService, PagingInputFields } from '@proj/api-core-data-access'; import { TestPaging } from './entity/test.entity'; @Injectable() @@ -113,6 +110,7 @@ export class ApiTestDataService { } async delete(testId: string) { + await this.findOne(testId); const deleted = await this.core.data.test.delete({ where: { id: testId } }); return !!deleted; } @@ -188,7 +186,7 @@ exports[`api-feature generator should generate the feature libraries with crud f "import { Field, InputType } from '@nestjs/graphql'; @InputType() -export class AdminCreateTestInput { +export class TestAdminCreateInput { @Field() name!: string; } @@ -200,7 +198,7 @@ exports[`api-feature generator should generate the feature libraries with crud f import { PagingInput } from '@proj/api-core-data-access'; @InputType() -export class AdminFindManyTestInput extends PagingInput() { +export class TestAdminFindManyInput extends PagingInput() { @Field({ nullable: true }) search?: string; } @@ -211,7 +209,7 @@ exports[`api-feature generator should generate the feature libraries with crud f "import { Field, InputType } from '@nestjs/graphql'; @InputType() -export class AdminUpdateTestInput { +export class TestAdminUpdateInput { @Field({ nullable: true }) name?: string; } @@ -222,7 +220,7 @@ exports[`api-feature generator should generate the feature libraries with crud f "import { Field, InputType } from '@nestjs/graphql'; @InputType() -export class UserCreateTestInput { +export class TestUserCreateInput { @Field() name!: string; } @@ -234,7 +232,7 @@ exports[`api-feature generator should generate the feature libraries with crud f import { PagingInput } from '@proj/api-core-data-access'; @InputType() -export class UserFindManyTestInput extends PagingInput() { +export class TestUserFindManyInput extends PagingInput() { @Field({ nullable: true }) search?: string; } @@ -245,7 +243,7 @@ exports[`api-feature generator should generate the feature libraries with crud f "import { Field, InputType } from '@nestjs/graphql'; @InputType() -export class UserUpdateTestInput { +export class TestUserUpdateInput { @Field({ nullable: true }) name?: string; } @@ -328,11 +326,11 @@ import { ApiAuthGraphQLAdminGuard } from '@proj/api-auth-data-access'; import { Mutation, Query, Args } from '@nestjs/graphql'; import { UseGuards } from '@nestjs/common'; import { - AdminCreateTestInput, - AdminFindManyTestInput, + TestAdminCreateInput, + TestAdminFindManyInput, Test, TestPaging, - AdminUpdateTestInput, + TestAdminUpdateInput, } from '@proj/api-test-data-access'; @Resolver() @@ -341,7 +339,7 @@ export class ApiTestAdminResolver { constructor(private readonly service: ApiTestService) {} @Mutation(() => Test, { nullable: true }) - adminCreateTest(@Args('input') input: AdminCreateTestInput) { + adminCreateTest(@Args('input') input: TestAdminCreateInput) { return this.service.admin.createTest(input); } @@ -351,7 +349,7 @@ export class ApiTestAdminResolver { } @Query(() => TestPaging) - adminFindManyTest(@Args('input') input: AdminFindManyTestInput) { + adminFindManyTest(@Args('input') input: TestAdminFindManyInput) { return this.service.admin.findManyTest(input); } @@ -363,7 +361,7 @@ export class ApiTestAdminResolver { @Mutation(() => Test, { nullable: true }) adminUpdateTest( @Args('testId') testId: string, - @Args('input') input: AdminUpdateTestInput + @Args('input') input: TestAdminUpdateInput ) { return this.service.admin.updateTest(testId, input); } @@ -378,11 +376,11 @@ import { ApiAuthGraphQLUserGuard } from '@proj/api-auth-data-access'; import { Mutation, Query, Args } from '@nestjs/graphql'; import { UseGuards } from '@nestjs/common'; import { - UserCreateTestInput, - UserFindManyTestInput, + TestUserCreateInput, + TestUserFindManyInput, Test, TestPaging, - UserUpdateTestInput, + TestUserUpdateInput, } from '@proj/api-test-data-access'; @Resolver() @@ -391,7 +389,7 @@ export class ApiTestUserResolver { constructor(private readonly service: ApiTestService) {} @Mutation(() => Test, { nullable: true }) - userCreateTest(@Args('input') input: UserCreateTestInput) { + userCreateTest(@Args('input') input: TestUserCreateInput) { return this.service.user.createTest(input); } @@ -401,7 +399,7 @@ export class ApiTestUserResolver { } @Query(() => TestPaging) - userFindManyTest(@Args('input') input: UserFindManyTestInput) { + userFindManyTest(@Args('input') input: TestUserFindManyInput) { return this.service.user.findManyTest(input); } @@ -413,7 +411,7 @@ export class ApiTestUserResolver { @Mutation(() => Test, { nullable: true }) userUpdateTest( @Args('testId') testId: string, - @Args('input') input: UserUpdateTestInput + @Args('input') input: TestUserUpdateInput ) { return this.service.user.updateTest(testId, input); } diff --git a/libs/tools/src/generators/api-feature/api-feature-generator.spec.ts b/libs/tools/src/generators/api-feature/api-feature-generator.spec.ts index 0b91582..0a187fd 100644 --- a/libs/tools/src/generators/api-feature/api-feature-generator.spec.ts +++ b/libs/tools/src/generators/api-feature/api-feature-generator.spec.ts @@ -82,12 +82,12 @@ describe('api-feature generator', () => { "libs/api/test/data-access/src/lib/api-test-data.service.ts", "libs/api/test/data-access/src/lib/api-test.data-access.module.ts", "libs/api/test/data-access/src/lib/api-test.service.ts", - "libs/api/test/data-access/src/lib/dto/admin-create-test.input.ts", - "libs/api/test/data-access/src/lib/dto/admin-find-many-test.input.ts", - "libs/api/test/data-access/src/lib/dto/admin-update-test.input.ts", - "libs/api/test/data-access/src/lib/dto/user-create-test.input.ts", - "libs/api/test/data-access/src/lib/dto/user-find-many-test.input.ts", - "libs/api/test/data-access/src/lib/dto/user-update-test.input.ts", + "libs/api/test/data-access/src/lib/dto/test-admin-create.input.ts", + "libs/api/test/data-access/src/lib/dto/test-admin-find-many.input.ts", + "libs/api/test/data-access/src/lib/dto/test-admin-update.input.ts", + "libs/api/test/data-access/src/lib/dto/test-user-create.input.ts", + "libs/api/test/data-access/src/lib/dto/test-user-find-many.input.ts", + "libs/api/test/data-access/src/lib/dto/test-user-update.input.ts", "libs/api/test/data-access/src/lib/entity/test.entity.ts", "libs/api/test/data-access/src/lib/helpers/get-test-where-admin.input.ts", "libs/api/test/data-access/src/lib/helpers/get-test-where-user.input.ts", diff --git a/libs/tools/src/generators/web-crud/__snapshots__/web-crud-generator.spec.ts.snap b/libs/tools/src/generators/web-crud/__snapshots__/web-crud-generator.spec.ts.snap index b3b29f0..ebafcca 100644 --- a/libs/tools/src/generators/web-crud/__snapshots__/web-crud-generator.spec.ts.snap +++ b/libs/tools/src/generators/web-crud/__snapshots__/web-crud-generator.spec.ts.snap @@ -842,15 +842,9 @@ exports[`web-crud generator should create crud with modelOwnerId 1`] = ` }, "company-ui-item.tsx": { "content": [ - "import {", - "AvatarProps,", - "Group,", - "type GroupProps,", - "Stack,", - "Text,", - "} from '@mantine/core';", + "import { AvatarProps, Group, GroupProps, Stack, Text } from '@mantine/core';", "import { Company } from '@proj/sdk';", - "import { UiAnchor, type UiAnchorProps } from '@pubkey-ui/core';", + "import { UiAnchor, UiAnchorProps } from '@pubkey-ui/core';", "import { CompanyUiAvatar } from './company-ui-avatar';", "export function CompanyUiItem({", "anchorProps,", @@ -888,7 +882,6 @@ exports[`web-crud generator should create crud with modelOwnerId 1`] = ` "import { Button, Group } from '@mantine/core';", "import { ManagerCreateCompanyInput } from '@proj/sdk';", "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", - "import { ReactNode } from 'react';", "export function ManagerCompanyUiCreateForm({", "submit,", "}: {", @@ -2678,7 +2671,6 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "import { Button, Group } from '@mantine/core';", "import { AdminCreateCompanyInput } from '@proj/sdk';", "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", - "import { ReactNode } from 'react';", "export function AdminCompanyUiCreateForm({", "submit,", "}: {", @@ -2952,15 +2944,9 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u }, "company-ui-item.tsx": { "content": [ - "import {", - "AvatarProps,", - "Group,", - "type GroupProps,", - "Stack,", - "Text,", - "} from '@mantine/core';", + "import { AvatarProps, Group, GroupProps, Stack, Text } from '@mantine/core';", "import { Company } from '@proj/sdk';", - "import { UiAnchor, type UiAnchorProps } from '@pubkey-ui/core';", + "import { UiAnchor, UiAnchorProps } from '@pubkey-ui/core';", "import { CompanyUiAvatar } from './company-ui-avatar';", "export function CompanyUiItem({", "anchorProps,", @@ -2998,7 +2984,6 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "import { Button, Group } from '@mantine/core';", "import { UserCreateCompanyInput } from '@proj/sdk';", "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", - "import { ReactNode } from 'react';", "export function UserCompanyUiCreateForm({", "submit,", "}: {", @@ -4583,15 +4568,9 @@ exports[`web-crud generator should create crud with modelParentId 1`] = ` }, "company-ui-item.tsx": { "content": [ - "import {", - "AvatarProps,", - "Group,", - "type GroupProps,", - "Stack,", - "Text,", - "} from '@mantine/core';", + "import { AvatarProps, Group, GroupProps, Stack, Text } from '@mantine/core';", "import { Company } from '@proj/sdk';", - "import { UiAnchor, type UiAnchorProps } from '@pubkey-ui/core';", + "import { UiAnchor, UiAnchorProps } from '@pubkey-ui/core';", "import { CompanyUiAvatar } from './company-ui-avatar';", "export function CompanyUiItem({", "anchorProps,", @@ -4629,7 +4608,6 @@ exports[`web-crud generator should create crud with modelParentId 1`] = ` "import { Button, Group } from '@mantine/core';", "import { ManagerCreateCompanyInput } from '@proj/sdk';", "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", - "import { ReactNode } from 'react';", "export function ManagerCompanyUiCreateForm({", "submit,", "}: {", diff --git a/libs/tools/src/generators/web-feature/__snapshots__/web-feature-generator.spec.ts.snap b/libs/tools/src/generators/web-feature/__snapshots__/web-feature-generator.spec.ts.snap index 2d7af8b..33e8038 100644 --- a/libs/tools/src/generators/web-feature/__snapshots__/web-feature-generator.spec.ts.snap +++ b/libs/tools/src/generators/web-feature/__snapshots__/web-feature-generator.spec.ts.snap @@ -684,7 +684,6 @@ exports[`web-feature generator should run successfully with crud 23`] = ` "import { Button, Group } from '@mantine/core'; import { AdminCreateTestInput } from '@proj/sdk'; import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core'; -import { ReactNode } from 'react'; export function AdminTestUiCreateForm({ submit, @@ -937,15 +936,9 @@ export function TestUiInfo({ test }: { test?: Test }) { `; exports[`web-feature generator should run successfully with crud 30`] = ` -"import { - AvatarProps, - Group, - type GroupProps, - Stack, - Text, -} from '@mantine/core'; +"import { AvatarProps, Group, GroupProps, Stack, Text } from '@mantine/core'; import { Test } from '@proj/sdk'; -import { UiAnchor, type UiAnchorProps } from '@pubkey-ui/core'; +import { UiAnchor, UiAnchorProps } from '@pubkey-ui/core'; import { TestUiAvatar } from './test-ui-avatar'; export function TestUiItem({ @@ -983,7 +976,6 @@ exports[`web-feature generator should run successfully with crud 31`] = ` "import { Button, Group } from '@mantine/core'; import { UserCreateTestInput } from '@proj/sdk'; import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core'; -import { ReactNode } from 'react'; export function UserTestUiCreateForm({ submit, diff --git a/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data-__actorFileName__.service.ts.template b/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data-__actorFileName__.service.ts.template index 0a2b26d..9198623 100644 --- a/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data-__actorFileName__.service.ts.template +++ b/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data-__actorFileName__.service.ts.template @@ -1,7 +1,7 @@ import { Injectable } from '@nestjs/common' -import { <%= actor.className %>Create<%= model.className %>Input } from './dto/<%= actor.fileName %>-create-<%= model.fileName %>.input' -import { <%= actor.className %>FindMany<%= model.className %>Input } from './dto/<%= actor.fileName %>-find-many-<%= model.fileName %>.input' -import { <%= actor.className %>Update<%= model.className %>Input } from './dto/<%= actor.fileName %>-update-<%= model.fileName %>.input' +import { <%= model.className %><%= actor.className %>CreateInput } from './dto/<%= model.fileName %>-<%= actor.fileName %>-create.input' +import { <%= model.className %><%= actor.className %>FindManyInput } from './dto/<%= model.fileName %>-<%= actor.fileName %>-find-many.input' +import { <%= model.className %><%= actor.className %>UpdateInput } from './dto/<%= model.fileName %>-<%= actor.fileName %>-update.input' import { <%= model.className %>Paging } from './entity/<%= model.fileName %>.entity' import { get<%= model.className %>Where<%= actor.className %>Input } from './helpers/get-<%= model.fileName %>-where-<%= actor.fileName %>.input' import { <%= app.className %><%= model.className %>DataService } from './<%= app.fileName %>-<%= model.fileName %>-data.service' @@ -11,7 +11,7 @@ import { <%= app.className %><%= model.className %>DataService } from './<%= app export class <%= app.className %><%= model.className %>Data<%= actor.className %>Service { constructor(private readonly data: <%= app.className %><%= model.className %>DataService) {} - async create<%= model.className %>(<% if(ownerId && actor.className !== 'Admin'){ %><%= ownerId %>: string, <% } %>input: <%= actor.className %>Create<%= model.className %>Input) { + async create<%= model.className %>(<% if(ownerId && actor.className !== 'Admin'){ %><%= ownerId %>: string, <% } %>input: <%= model.className %><%= actor.className %>CreateInput) { return this.data.create(<% if(ownerId && actor.className !== 'Admin'){ %>{...input, <%= ownerId %> }<% } else { %>input<% } %>) } @@ -20,12 +20,11 @@ export class <%= app.className %><%= model.className %>Data<%= actor.className % const found = await this.data.findOne(<%= model.propertyName %>Id) if (found.<%= ownerId %> !== <%= ownerId %>) { throw new Error('You are not authorized to delete this <%= model.className %>') - } - <% } %> + }<% } %> return this.data.delete(<%= model.propertyName %>Id) } - async findMany<%= model.className %>(<% if(ownerId && actor.className !== 'Admin'){ %><%= ownerId %>: string, <% } %>input: <%= actor.className %>FindMany<%= model.className %>Input): Promise<<%= model.className %>Paging> { + async findMany<%= model.className %>(<% if(ownerId && actor.className !== 'Admin'){ %><%= ownerId %>: string, <% } %>input: <%= model.className %><%= actor.className %>FindManyInput): Promise<<%= model.className %>Paging> { return this.data.findMany({ orderBy: { createdAt: 'desc' }, where: get<%= model.className %>Where<%= actor.className %>Input(<% if(ownerId && actor.className !== 'Admin'){ %><%= ownerId %>, <% } %>input), @@ -46,13 +45,12 @@ export class <%= app.className %><%= model.className %>Data<%= actor.className % <% } %> } - async update<%= model.className %>(<% if(ownerId && actor.className !== 'Admin'){ %><%= ownerId %>: string, <% } %><%= model.propertyName %>Id: string, input: <%= actor.className %>Update<%= model.className %>Input) { + async update<%= model.className %>(<% if(ownerId && actor.className !== 'Admin'){ %><%= ownerId %>: string, <% } %><%= model.propertyName %>Id: string, input: <%= model.className %><%= actor.className %>UpdateInput) { <% if(ownerId && actor.className !== 'Admin'){ %> const found = await this.data.findOne(<%= model.propertyName %>Id) if (found.<%= ownerId %> !== <%= ownerId %>) { throw new Error('You are not authorized to update this <%= model.className %>') - } - <% } %> + }<% } %> return this.data.update(<%= model.propertyName %>Id, input) } } diff --git a/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data.service.ts.template b/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data.service.ts.template index 1dc48ab..e38c29d 100644 --- a/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data.service.ts.template +++ b/libs/tools/src/lib/api-crud/files/data-access/lib/__appFileName__-__modelFileName__-data.service.ts.template @@ -1,6 +1,6 @@ import { Injectable } from '@nestjs/common' import { Prisma } from '@prisma/client' -import { <%= app.className %>CoreService, type PagingInputFields } from '@<%= npmScope %>/<%= app.fileName %>-core-data-access' +import { <%= app.className %>CoreService, PagingInputFields } from '@<%= npmScope %>/<%= app.fileName %>-core-data-access' import { <%= model.className %>Paging } from './entity/<%= model.fileName %>.entity' @Injectable() @@ -12,6 +12,7 @@ export class <%= app.className %><%= model.className %>DataService { } async delete(<%= model.propertyName %>Id: string) { + await this.findOne(<%= model.propertyName %>Id) const deleted = await this.core.data.<%= model.propertyName %>.delete({ where: { id: <%= model.propertyName %>Id } }) return !!deleted } diff --git a/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__actorFileName__-create-__modelFileName__.input.ts.template b/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__modelFileName__-__actorFileName__-create.input.ts.template similarity index 90% rename from libs/tools/src/lib/api-crud/files/data-access/lib/dto/__actorFileName__-create-__modelFileName__.input.ts.template rename to libs/tools/src/lib/api-crud/files/data-access/lib/dto/__modelFileName__-__actorFileName__-create.input.ts.template index cc712da..57c8837 100644 --- a/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__actorFileName__-create-__modelFileName__.input.ts.template +++ b/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__modelFileName__-__actorFileName__-create.input.ts.template @@ -2,7 +2,7 @@ import { Field, InputType } from '@nestjs/graphql' <% if(parent && parent.className !== 'User'){ %> import { <%= parent.className %> } from '@<%= npmScope %>/<%= app.fileName %>-<%= parent.fileName %>-data-access' <% } %> @InputType() -export class <%= actor.className %>Create<%= model.className %>Input { +export class <%= model.className %><%= actor.className %>CreateInput { <% for (let field of fields){ %> @Field(<% if(field.optional){ %>{ nullable: true }<% } %>) <%= field.name %><% if(field.optional){ %>?<% } else { %>!<% } %>: <%= field.type %> diff --git a/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__actorFileName__-find-many-__modelFileName__.input.ts.template b/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__modelFileName__-__actorFileName__-find-many.input.ts.template similarity index 79% rename from libs/tools/src/lib/api-crud/files/data-access/lib/dto/__actorFileName__-find-many-__modelFileName__.input.ts.template rename to libs/tools/src/lib/api-crud/files/data-access/lib/dto/__modelFileName__-__actorFileName__-find-many.input.ts.template index a2044b9..1fb70bf 100644 --- a/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__actorFileName__-find-many-__modelFileName__.input.ts.template +++ b/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__modelFileName__-__actorFileName__-find-many.input.ts.template @@ -2,7 +2,7 @@ import { Field, InputType } from '@nestjs/graphql' import { PagingInput } from '@<%= npmScope %>/<%= app.fileName %>-core-data-access' @InputType() -export class <%= actor.className %>FindMany<%= model.className %>Input extends PagingInput() { +export class <%= model.className %><%= actor.className %>FindManyInput extends PagingInput() { <% if(!parent && ownerId && actor.className === 'Admin'){ %> @Field() <%= ownerId %>!: string diff --git a/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__actorFileName__-update-__modelFileName__.input.ts.template b/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__modelFileName__-__actorFileName__-update.input.ts.template similarity index 74% rename from libs/tools/src/lib/api-crud/files/data-access/lib/dto/__actorFileName__-update-__modelFileName__.input.ts.template rename to libs/tools/src/lib/api-crud/files/data-access/lib/dto/__modelFileName__-__actorFileName__-update.input.ts.template index 08874e7..f41bcfa 100644 --- a/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__actorFileName__-update-__modelFileName__.input.ts.template +++ b/libs/tools/src/lib/api-crud/files/data-access/lib/dto/__modelFileName__-__actorFileName__-update.input.ts.template @@ -1,7 +1,7 @@ import { Field, InputType } from '@nestjs/graphql' @InputType() -export class <%= actor.className %>Update<%= model.className %>Input { +export class <%= model.className %><%= actor.className %>UpdateInput { <% for (let field of fields){ %> @Field({ nullable: true }) <%= field.name %>?: <%= field.type %> diff --git a/libs/tools/src/lib/api-crud/files/data-access/lib/helpers/get-__modelFileName__-where-__actorFileName__.input.ts.template b/libs/tools/src/lib/api-crud/files/data-access/lib/helpers/get-__modelFileName__-where-__actorFileName__.input.ts.template index 258fd25..3a66c4a 100644 --- a/libs/tools/src/lib/api-crud/files/data-access/lib/helpers/get-__modelFileName__-where-__actorFileName__.input.ts.template +++ b/libs/tools/src/lib/api-crud/files/data-access/lib/helpers/get-__modelFileName__-where-__actorFileName__.input.ts.template @@ -1,7 +1,7 @@ import { Prisma } from '@prisma/client' -import { <%= actor.className %>FindMany<%= model.className %>Input } from '../dto/<%= actor.fileName %>-find-many-<%= model.fileName %>.input' +import { <%= model.className %><%= actor.className %>FindManyInput } from '../dto/<%= model.fileName %>-<%= actor.fileName %>-find-many.input' -export function get<%= model.className %>Where<%= actor.className %>Input(<% if(ownerId && actor.className !== 'Admin'){ %><%= ownerId %>: string, <% } %>input: <%= actor.className %>FindMany<%= model.className %>Input): Prisma.<%= model.className %>WhereInput { +export function get<%= model.className %>Where<%= actor.className %>Input(<% if(ownerId && actor.className !== 'Admin'){ %><%= ownerId %>: string, <% } %>input: <%= model.className %><%= actor.className %>FindManyInput): Prisma.<%= model.className %>WhereInput { const where: Prisma.<%= model.className %>WhereInput = { <% if(parent){ %><%= parentId %>: input.<%= parentId %><% } %> <% if(owner && actor.className !== 'Admin'){ %><%= ownerId %>: <%= ownerId %><% } %> diff --git a/libs/tools/src/lib/api-crud/files/feature/lib/__appFileName__-__modelFileName__-__actorFileName__.resolver.ts.template b/libs/tools/src/lib/api-crud/files/feature/lib/__appFileName__-__modelFileName__-__actorFileName__.resolver.ts.template index 7a156ce..4ab35f2 100644 --- a/libs/tools/src/lib/api-crud/files/feature/lib/__appFileName__-__modelFileName__-__actorFileName__.resolver.ts.template +++ b/libs/tools/src/lib/api-crud/files/feature/lib/__appFileName__-__modelFileName__-__actorFileName__.resolver.ts.template @@ -4,11 +4,11 @@ import { <%= app.className %>AuthGraphQL<%= actor.className %>Guard<% if(ownerId import { Mutation, Query, Args } from '@nestjs/graphql' import { UseGuards } from '@nestjs/common' import { - <%= actor.className %>Create<%= model.className %>Input, - <%= actor.className %>FindMany<%= model.className %>Input, + <%= model.className %><%= actor.className %>CreateInput, + <%= model.className %><%= actor.className %>FindManyInput, <%= model.className %>, <%= model.className %>Paging, - <%= actor.className %>Update<%= model.className %>Input, + <%= model.className %><%= actor.className %>UpdateInput, } from '@<%= npmScope %>/<%= app.fileName %>-<%= model.fileName %>-data-access' @Resolver() @@ -19,7 +19,7 @@ export class <%= app.className %><%= model.className %><%= actor.className %>Res @Mutation(() => <%= model.className %>, { nullable: true }) <%= actor.propertyName %>Create<%= model.className %>( <% if(ownerId && actor.className !== 'Admin'){ %>@CtxUserId() <%= ownerId %>: string,<% } %> - @Args('input') input: <%= actor.className %>Create<%= model.className %>Input) { + @Args('input') input: <%= model.className %><%= actor.className %>CreateInput) { return this.service.<%= actor.propertyName %>.create<%= model.className %>(<% if(ownerId && actor.className !== 'Admin'){ %><%= ownerId %>, <% } %>input) } @@ -33,7 +33,7 @@ export class <%= app.className %><%= model.className %><%= actor.className %>Res @Query(() => <%= model.className %>Paging) <%= actor.propertyName %>FindMany<%= model.className %>( <% if(ownerId && actor.className !== 'Admin'){ %>@CtxUserId() <%= ownerId %>: string,<% } %> - @Args('input') input: <%= actor.className %>FindMany<%= model.className %>Input) { + @Args('input') input: <%= model.className %><%= actor.className %>FindManyInput) { return this.service.<%= actor.propertyName %>.findMany<%= model.className %>(<% if(ownerId && actor.className !== 'Admin'){ %><%= ownerId %>, <% } %>input) } @@ -47,7 +47,7 @@ export class <%= app.className %><%= model.className %><%= actor.className %>Res @Mutation(() => <%= model.className %>, { nullable: true }) <%= actor.propertyName %>Update<%= model.className %>( <% if(ownerId && actor.className !== 'Admin'){ %>@CtxUserId() <%= ownerId %>: string,<% } %> - @Args('<%= model.propertyName %>Id') <%= model.propertyName %>Id: string, @Args('input') input: <%= actor.className %>Update<%= model.className %>Input) { + @Args('<%= model.propertyName %>Id') <%= model.propertyName %>Id: string, @Args('input') input: <%= model.className %><%= actor.className %>UpdateInput) { return this.service.<%= actor.propertyName %>.update<%= model.className %>(<% if(ownerId && actor.className !== 'Admin'){ %><%= ownerId %>, <% } %><%= model.propertyName %>Id, input) } } diff --git a/libs/tools/src/lib/api-crud/generate-api-crud.ts b/libs/tools/src/lib/api-crud/generate-api-crud.ts index 9ce8fc2..d04fe21 100644 --- a/libs/tools/src/lib/api-crud/generate-api-crud.ts +++ b/libs/tools/src/lib/api-crud/generate-api-crud.ts @@ -1,4 +1,4 @@ -import { generateFiles, getProjects, type ProjectConfiguration, Tree } from '@nx/devkit' +import { generateFiles, getProjects, ProjectConfiguration, Tree } from '@nx/devkit' import { addExports } from '../utils/ast/add-export' import { ensureNxProjectExists } from '../utils/ensure-nx-project-exists' import { addServiceToClassConstructor } from './add-service-to-class-constructor' @@ -76,9 +76,9 @@ export function generateApiCrud(tree: Tree, options: NormalizedApiCrudSchema) { const dataAccessExports: string[] = [ // Add exports here `./lib/entity/${vars.model.fileName}.entity`, - `./lib/dto/${vars.actorFileName}-create-${vars.modelFileName}.input`, - `./lib/dto/${vars.actorFileName}-find-many-${vars.modelFileName}.input`, - `./lib/dto/${vars.actorFileName}-update-${vars.modelFileName}.input`, + `./lib/dto/${vars.modelFileName}-${vars.actorFileName}-create.input`, + `./lib/dto/${vars.modelFileName}-${vars.actorFileName}-find-many.input`, + `./lib/dto/${vars.modelFileName}-${vars.actorFileName}-update.input`, ] // Add the exports to the barrel file diff --git a/libs/tools/src/lib/api-crud/generate-sdk-file.ts b/libs/tools/src/lib/api-crud/generate-sdk-file.ts index fc1e9e6..e4750f7 100644 --- a/libs/tools/src/lib/api-crud/generate-sdk-file.ts +++ b/libs/tools/src/lib/api-crud/generate-sdk-file.ts @@ -50,7 +50,7 @@ function sdkTemplateActor(name: string, actor: string) { const { className, propertyName } = names(name) const { className: classNameActor, propertyName: propertyNameActor } = names(actor) return ` -query ${propertyNameActor}FindMany${className}($input: ${classNameActor}FindMany${className}Input!) { +query ${propertyNameActor}FindMany${className}($input: ${className}${classNameActor}FindManyInput!) { paging: ${propertyNameActor}FindMany${className}(input: $input) { data { ...${className}Details @@ -67,13 +67,13 @@ query ${propertyNameActor}FindOne${className}($${propertyName}Id: String!) { } } -mutation ${propertyNameActor}Create${className}($input: ${classNameActor}Create${className}Input!) { +mutation ${propertyNameActor}Create${className}($input: ${className}${classNameActor}CreateInput!) { created: ${propertyNameActor}Create${className}(input: $input) { ...${className}Details } } -mutation ${propertyNameActor}Update${className}($${propertyName}Id: String!, $input: ${classNameActor}Update${className}Input!) { +mutation ${propertyNameActor}Update${className}($${propertyName}Id: String!, $input: ${className}${classNameActor}UpdateInput!) { updated: ${propertyNameActor}Update${className}(${propertyName}Id: $${propertyName}Id, input: $input) { ...${className}Details } diff --git a/libs/tools/src/lib/web-crud/files/data-access/lib/use-__actorFileName__-find-many-__modelFileName__.ts.template b/libs/tools/src/lib/web-crud/files/data-access/lib/use-__actorFileName__-find-many-__modelFileName__.ts.template index 7d73703..764ba08 100644 --- a/libs/tools/src/lib/web-crud/files/data-access/lib/use-__actorFileName__-find-many-__modelFileName__.ts.template +++ b/libs/tools/src/lib/web-crud/files/data-access/lib/use-__actorFileName__-find-many-__modelFileName__.ts.template @@ -1,16 +1,16 @@ -import { <%= actor.className %>Create<%= model.className %>Input, <%= actor.className %>FindMany<%= model.className %>Input } from '@<%= npmScope %>/sdk' +import { <%= model.className %><%= actor.className %>CreateInput, <%= model.className %><%= actor.className %>FindManyInput } from '@<%= npmScope %>/sdk' import { useSdk } from '@<%= npmScope %>/<%= app.fileName %>-core-data-access' import { toastError, toastSuccess } from '@pubkey-ui/core' import { useQuery } from '@tanstack/react-query' import { useState } from 'react' -export function use<%= actor.className %>FindMany<%= model.className %>(props: Partial<<%= actor.className %>FindMany<%= model.className %>Input><% if(ownerId && actor.className === 'Admin'){ %> & { <%= ownerId %>: string } <% } else { %> = {} <% } %> ) { +export function use<%= actor.className %>FindMany<%= model.className %>(props: Partial<<%= model.className %><%= actor.className %>FindManyInput><% if(ownerId && actor.className === 'Admin'){ %> & { <%= ownerId %>: string } <% } else { %> = {} <% } %> ) { const sdk = useSdk() const [limit, setLimit] = useState(props?.limit ?? 10) const [page, setPage] = useState(props?.page ?? 1) const [search, setSearch] = useState(props?.search ?? '') - const input: <%= actor.className %>FindMany<%= model.className %>Input = { page, limit, search<% if(ownerId && actor.className === 'Admin'){ %>, <%= ownerId %>: props.<%= ownerId %> <% } %> } + const input: <%= model.className %><%= actor.className %>FindManyInput = { page, limit, search<% if(ownerId && actor.className === 'Admin'){ %>, <%= ownerId %>: props.<%= ownerId %> <% } %> } const query = useQuery({ queryKey: ['<%= actor.propertyName %>', 'find-many-<%= model.fileName %>', input], queryFn: () => sdk.<%= actor.propertyName %>FindMany<%= model.className %>({ input }).then((res) => res.data), @@ -29,7 +29,7 @@ export function use<%= actor.className %>FindMany<%= model.className %>(props: P total, }, setSearch, - create<%= model.className %>: (input: <%= actor.className %>Create<%= model.className %>Input) => + create<%= model.className %>: (input: <%= model.className %><%= actor.className %>CreateInput) => sdk .<%= actor.propertyName %>Create<%= model.className %>({ input<% if(ownerId && actor.className === 'Admin'){ %>: { ...input, <%= ownerId %>: props.<%= ownerId %> } <% } %> }) .then((res) => res.data) diff --git a/libs/tools/src/lib/web-crud/files/data-access/lib/use-__actorFileName__-find-one-__modelFileName__.ts.template b/libs/tools/src/lib/web-crud/files/data-access/lib/use-__actorFileName__-find-one-__modelFileName__.ts.template index 0316c9d..07b994e 100644 --- a/libs/tools/src/lib/web-crud/files/data-access/lib/use-__actorFileName__-find-one-__modelFileName__.ts.template +++ b/libs/tools/src/lib/web-crud/files/data-access/lib/use-__actorFileName__-find-one-__modelFileName__.ts.template @@ -1,4 +1,4 @@ -import { <%= actor.className %>Update<%= model.className %>Input } from '@<%= npmScope %>/sdk' +import { <%= model.className %><%= actor.className %>UpdateInput } from '@<%= npmScope %>/sdk' import { useSdk } from '@<%= npmScope %>/<%= app.fileName %>-core-data-access' import { toastError, toastSuccess } from '@pubkey-ui/core' import { useQuery } from '@tanstack/react-query' @@ -15,7 +15,7 @@ export function use<%= actor.className %>FindOne<%= model.className %>({ <%= mod return { item, query, - update<%= model.className %>: async (input: <%= actor.className %>Update<%= model.className %>Input) => + update<%= model.className %>: async (input: <%= model.className %><%= actor.className %>UpdateInput) => sdk .<%= actor.propertyName %>Update<%= model.className %>({ <%= model.propertyName %>Id, input }) .then((res) => res.data) diff --git a/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-create.feature.tsx.template b/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-create.feature.tsx.template index 4bfe6b1..e541fde 100644 --- a/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-create.feature.tsx.template +++ b/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-create.feature.tsx.template @@ -1,4 +1,4 @@ -import { <%= actor.className %>Create<%= model.className %>Input } from '@<%= npmScope %>/sdk' +import { <%= model.className %><%= actor.className %>CreateInput } from '@<%= npmScope %>/sdk' import { use<%= actor.className %>FindMany<%= model.className %> } from '@<%= npmScope %>/<%= app.fileName %>-<%= model.fileName %>-data-access' import { <%= actor.className %><%= model.className %>UiCreateForm } from '@<%= npmScope %>/<%= app.fileName %>-<%= model.fileName %>-ui' import { toastError, UiBack, UiCard<% if(ownerId && actor.className === 'Admin'){ %><% } else { %>, UiPage<% } %> } from '@pubkey-ui/core' @@ -9,7 +9,7 @@ export function <%= actor.className %><%= model.className %>CreateFeature(<% if( const navigate = useNavigate() const { create<%= model.className %> } = use<%= actor.className %>FindMany<%= model.className %>(<% if(ownerId && actor.className === 'Admin'){ %>{ <%= ownerId %> }<% } %>) - async function submit(input: <%= actor.className %>Create<%= model.className %>Input) { + async function submit(input: <%= model.className %><%= actor.className %>CreateInput) { return create<%= model.className %>(input) .then((res) => { if (res) { diff --git a/libs/tools/src/lib/web-crud/files/ui/lib/__actorFileName__-__modelFileName__-ui-create-form.tsx.template b/libs/tools/src/lib/web-crud/files/ui/lib/__actorFileName__-__modelFileName__-ui-create-form.tsx.template index eca385d..9f911fc 100644 --- a/libs/tools/src/lib/web-crud/files/ui/lib/__actorFileName__-__modelFileName__-ui-create-form.tsx.template +++ b/libs/tools/src/lib/web-crud/files/ui/lib/__actorFileName__-__modelFileName__-ui-create-form.tsx.template @@ -1,10 +1,9 @@ import { Button, Group } from '@mantine/core' -import { <%= actor.className %>Create<%= model.className %>Input } from '@<%= npmScope %>/sdk' +import { <%= model.className %><%= actor.className %>CreateInput } from '@<%= npmScope %>/sdk' import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core' -import { ReactNode } from 'react' -export function <%= actor.className %><%= model.className %>UiCreateForm({ submit }: { submit: (res: <%= actor.className %>Create<%= model.className %>Input) => Promise }) { - const model: <%= actor.className %>Create<%= model.className %>Input = { +export function <%= actor.className %><%= model.className %>UiCreateForm({ submit }: { submit: (res: <%= model.className %><%= actor.className %>CreateInput) => Promise }) { + const model: <%= model.className %><%= actor.className %>CreateInput = { <% for (let field of fields){ %> <%= field.name %>: '', <% } %> @@ -13,13 +12,13 @@ export function <%= actor.className %><%= model.className %>UiCreateForm({ submi <% } %> } - const fields: UiFormField<<%= actor.className %>Create<%= model.className %>Input>[] = [ + const fields: UiFormField<<%= model.className %><%= actor.className %>CreateInput>[] = [ <% for (let field of fields){ %> formFieldText('<%= field.name %>', { label: '<%= field.name %>', required: true, }), <% } %> ] return ( - submit(res as <%= actor.className %>Create<%= model.className %>Input)}> + submit(res as <%= model.className %><%= actor.className %>CreateInput)}> diff --git a/libs/tools/src/lib/web-crud/files/ui/lib/__actorFileName__-__modelFileName__-ui-update-form.tsx.template b/libs/tools/src/lib/web-crud/files/ui/lib/__actorFileName__-__modelFileName__-ui-update-form.tsx.template index f76d744..56b7a63 100644 --- a/libs/tools/src/lib/web-crud/files/ui/lib/__actorFileName__-__modelFileName__-ui-update-form.tsx.template +++ b/libs/tools/src/lib/web-crud/files/ui/lib/__actorFileName__-__modelFileName__-ui-update-form.tsx.template @@ -1,27 +1,27 @@ import { Button, Group } from '@mantine/core' -import { <%= actor.className %>Update<%= model.className %>Input, <%= model.className %> } from '@<%= npmScope %>/sdk' +import { <%= model.className %><%= actor.className %>UpdateInput, <%= model.className %> } from '@<%= npmScope %>/sdk' import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core' export function <%= actor.className %><%= model.className %>UiUpdateForm({ submit, <%= model.propertyName %> }: { - submit: (res: <%= actor.className %>Update<%= model.className %>Input) => Promise + submit: (res: <%= model.className %><%= actor.className %>UpdateInput) => Promise <%= model.propertyName %>: <%= model.className %> }) { - const model: <%= actor.className %>Update<%= model.className %>Input = { + const model: <%= model.className %><%= actor.className %>UpdateInput = { <% for (let field of fields){ %> <%= field.name %>: <%= model.propertyName %>.<%= field.name %> ?? '', <% } %> } - const fields: UiFormField<<%= actor.className %>Update<%= model.className %>Input>[] = [ + const fields: UiFormField<<%= model.className %><%= actor.className %>UpdateInput>[] = [ <% for (let field of fields){ %> formFieldText('<%= field.name %>', { label: '<%= field.name %>', }), <% } %> ] return ( - submit(res as <%= actor.className %>Update<%= model.className %>Input)}> + submit(res as <%= model.className %><%= actor.className %>UpdateInput)}> diff --git a/libs/tools/src/lib/web-crud/files/ui/lib/__modelFileName__-ui-item.tsx.template b/libs/tools/src/lib/web-crud/files/ui/lib/__modelFileName__-ui-item.tsx.template index b1825b7..18f19a3 100644 --- a/libs/tools/src/lib/web-crud/files/ui/lib/__modelFileName__-ui-item.tsx.template +++ b/libs/tools/src/lib/web-crud/files/ui/lib/__modelFileName__-ui-item.tsx.template @@ -1,6 +1,6 @@ -import { AvatarProps, Group, type GroupProps, Stack, Text } from '@mantine/core' +import { AvatarProps, Group, GroupProps, Stack, Text } from '@mantine/core' import { <%= model.className %> } from '@<%= npmScope %>/sdk' -import { UiAnchor, type UiAnchorProps } from '@pubkey-ui/core' +import { UiAnchor, UiAnchorProps } from '@pubkey-ui/core' import { <%= model.className %>UiAvatar } from './<%= model.fileName %>-ui-avatar' export function <%= model.className %>UiItem({ diff --git a/libs/tools/src/lib/web-crud/generate-web-crud.ts b/libs/tools/src/lib/web-crud/generate-web-crud.ts index b94b86a..f8ebdbe 100644 --- a/libs/tools/src/lib/web-crud/generate-web-crud.ts +++ b/libs/tools/src/lib/web-crud/generate-web-crud.ts @@ -1,4 +1,4 @@ -import { generateFiles, type ProjectConfiguration, Tree } from '@nx/devkit' +import { generateFiles, ProjectConfiguration, Tree } from '@nx/devkit' import { NormalizedApiCrudSchema } from '../api-crud/normalized-api-crud.schema' import { addArrayItem } from '../utils/ast/add-array-item' diff --git a/libs/web/auth/ui/src/lib/auth-ui-shell.tsx b/libs/web/auth/ui/src/lib/auth-ui-shell.tsx index c44c77c..5b76a88 100644 --- a/libs/web/auth/ui/src/lib/auth-ui-shell.tsx +++ b/libs/web/auth/ui/src/lib/auth-ui-shell.tsx @@ -1,5 +1,5 @@ import { Button } from '@mantine/core' -import { IdentityProvider, type User } from '@pubkey-stack/sdk' +import { IdentityProvider, User } from '@pubkey-stack/sdk' import { IdentityUiLoginButtons } from '@pubkey-stack/web-identity-ui' import { UserUiAvatar } from '@pubkey-stack/web-user-ui' import { UiStack } from '@pubkey-ui/core' diff --git a/libs/web/identity/data-access/src/lib/use-admin-find-many-identity.ts b/libs/web/identity/data-access/src/lib/use-admin-find-many-identity.ts index 835d3d4..c02c384 100644 --- a/libs/web/identity/data-access/src/lib/use-admin-find-many-identity.ts +++ b/libs/web/identity/data-access/src/lib/use-admin-find-many-identity.ts @@ -1,5 +1,5 @@ import { modals } from '@mantine/modals' -import { AdminCreateIdentityInput, AdminFindManyIdentityInput, Identity, IdentityProvider } from '@pubkey-stack/sdk' +import { Identity, IdentityAdminCreateInput, IdentityAdminFindManyInput, IdentityProvider } from '@pubkey-stack/sdk' import { useSdk } from '@pubkey-stack/web-core-data-access' import { toastError, toastSuccess } from '@pubkey-ui/core' import { useQuery } from '@tanstack/react-query' @@ -8,7 +8,7 @@ import { useState } from 'react' export function useAdminFindManyIdentity({ ownerId, provider }: { ownerId?: string; provider?: IdentityProvider }) { const sdk = useSdk() - const [input] = useState({ + const [input] = useState({ ownerId: ownerId, provider: provider, }) @@ -21,7 +21,7 @@ export function useAdminFindManyIdentity({ ownerId, provider }: { ownerId?: stri return { items: query.data?.items ?? [], query, - createIdentity: async (input: AdminCreateIdentityInput) => { + createIdentity: async (input: IdentityAdminCreateInput) => { if (!ownerId) { toastError('No owner ID') return false diff --git a/libs/web/identity/data-access/src/lib/use-user-find-many-identity.ts b/libs/web/identity/data-access/src/lib/use-user-find-many-identity.ts index 9e962ea..0beffb6 100644 --- a/libs/web/identity/data-access/src/lib/use-user-find-many-identity.ts +++ b/libs/web/identity/data-access/src/lib/use-user-find-many-identity.ts @@ -1,4 +1,4 @@ -import { Identity, IdentityProvider, type UserFindManyIdentityInput } from '@pubkey-stack/sdk' +import { Identity, IdentityProvider, IdentityUserFindManyInput } from '@pubkey-stack/sdk' import { useSdk } from '@pubkey-stack/web-core-data-access' import { toastError, toastSuccess } from '@pubkey-ui/core' import { useQuery } from '@tanstack/react-query' @@ -6,7 +6,7 @@ import { useMemo } from 'react' export function useUserFindManyIdentity({ username }: { username: string }) { const sdk = useSdk() - const input: UserFindManyIdentityInput = useMemo(() => ({ username }), [username]) + const input: IdentityUserFindManyInput = useMemo(() => ({ username }), [username]) const query = useQuery({ queryKey: ['user', 'find-many-identity', input], queryFn: () => sdk.userFindManyIdentity({ input }).then((res) => res?.data), diff --git a/libs/web/identity/ui/src/lib/admin-identity-ui-create-form.tsx b/libs/web/identity/ui/src/lib/admin-identity-ui-create-form.tsx index c3b3bcb..c30aaf3 100644 --- a/libs/web/identity/ui/src/lib/admin-identity-ui-create-form.tsx +++ b/libs/web/identity/ui/src/lib/admin-identity-ui-create-form.tsx @@ -1,15 +1,15 @@ import { Button, Group } from '@mantine/core' -import { AdminCreateIdentityInput, IdentityProvider } from '@pubkey-stack/sdk' +import { IdentityAdminCreateInput, IdentityProvider } from '@pubkey-stack/sdk' import { formFieldSelect, formFieldText, getEnumOptions, UiForm, UiFormField } from '@pubkey-ui/core' -export function AuthUiIdentityCreateForm({ submit }: { submit: (res: AdminCreateIdentityInput) => Promise }) { - const model: AdminCreateIdentityInput = { +export function AuthUiIdentityCreateForm({ submit }: { submit: (res: IdentityAdminCreateInput) => Promise }) { + const model: IdentityAdminCreateInput = { provider: IdentityProvider.Solana, providerId: '', ownerId: '', } - const fields: UiFormField[] = [ + const fields: UiFormField[] = [ formFieldText('providerId', { label: 'Provider ID', }), @@ -20,7 +20,7 @@ export function AuthUiIdentityCreateForm({ submit }: { submit: (res: AdminCreate ] return ( - submit(res as AdminCreateIdentityInput)}> + submit(res as IdentityAdminCreateInput)}> diff --git a/libs/web/identity/ui/src/lib/identity-ui-login-buttons.tsx b/libs/web/identity/ui/src/lib/identity-ui-login-buttons.tsx index 8d9f030..8aeddd4 100644 --- a/libs/web/identity/ui/src/lib/identity-ui-login-buttons.tsx +++ b/libs/web/identity/ui/src/lib/identity-ui-login-buttons.tsx @@ -1,4 +1,4 @@ -import { Stack, type StackProps } from '@mantine/core' +import { Stack, StackProps } from '@mantine/core' import { IdentityProvider } from '@pubkey-stack/sdk' import { IdentityUiLoginButton } from './identity-ui-login-button' diff --git a/libs/web/identity/ui/src/lib/identity-ui-solana-login-button.tsx b/libs/web/identity/ui/src/lib/identity-ui-solana-login-button.tsx index 3fe0680..5e0721d 100644 --- a/libs/web/identity/ui/src/lib/identity-ui-solana-login-button.tsx +++ b/libs/web/identity/ui/src/lib/identity-ui-solana-login-button.tsx @@ -1,4 +1,4 @@ -import { Button, type ButtonProps, Modal, Tooltip } from '@mantine/core' +import { Button, ButtonProps, Modal, Tooltip } from '@mantine/core' import { useDisclosure } from '@mantine/hooks' import { IdentityProvider } from '@pubkey-stack/sdk' import { IdentityProviderSolanaLogin } from '@pubkey-stack/web-identity-data-access' diff --git a/libs/web/user/data-access/src/lib/use-admin-find-many-user.ts b/libs/web/user/data-access/src/lib/use-admin-find-many-user.ts index 5fdb04a..50c4443 100644 --- a/libs/web/user/data-access/src/lib/use-admin-find-many-user.ts +++ b/libs/web/user/data-access/src/lib/use-admin-find-many-user.ts @@ -1,10 +1,10 @@ -import { AdminCreateUserInput, AdminFindManyUserInput, UserRole, UserStatus } from '@pubkey-stack/sdk' +import { UserAdminCreateInput, UserAdminFindManyInput, UserRole, UserStatus } from '@pubkey-stack/sdk' import { useSdk } from '@pubkey-stack/web-core-data-access' import { toastError, toastSuccess } from '@pubkey-ui/core' import { useQuery } from '@tanstack/react-query' import { useState } from 'react' -export function useAdminFindManyUser(props?: AdminFindManyUserInput) { +export function useAdminFindManyUser(props?: UserAdminFindManyInput) { const sdk = useSdk() const [role, setRole] = useState(undefined) const [status, setStatus] = useState(undefined) @@ -12,7 +12,7 @@ export function useAdminFindManyUser(props?: AdminFindManyUserInput) { const [page, setPage] = useState(props?.page ?? 1) const [search, setSearch] = useState('') - const input: AdminFindManyUserInput = { limit, page, role, search, status } + const input: UserAdminFindManyInput = { limit, page, role, search, status } const query = useQuery({ queryKey: ['admin', 'find-many-user', input], queryFn: () => sdk.adminFindManyUser({ input }).then((res) => res.data), @@ -44,7 +44,7 @@ export function useAdminFindManyUser(props?: AdminFindManyUserInput) { setPage(1) setStatus(status) }, - createUser: (input: AdminCreateUserInput) => + createUser: (input: UserAdminCreateInput) => sdk .adminCreateUser({ input }) .then((res) => res.data) diff --git a/libs/web/user/data-access/src/lib/use-admin-find-one-user.ts b/libs/web/user/data-access/src/lib/use-admin-find-one-user.ts index 13640f9..7586aab 100644 --- a/libs/web/user/data-access/src/lib/use-admin-find-one-user.ts +++ b/libs/web/user/data-access/src/lib/use-admin-find-one-user.ts @@ -1,4 +1,4 @@ -import { AdminUpdateUserInput } from '@pubkey-stack/sdk' +import { UserAdminUpdateInput } from '@pubkey-stack/sdk' import { useSdk } from '@pubkey-stack/web-core-data-access' import { toastError, toastSuccess } from '@pubkey-ui/core' import { useQuery } from '@tanstack/react-query' @@ -15,7 +15,7 @@ export function useAdminFindOneUser({ userId }: { userId: string }) { return { item, query, - updateUser: async (input: AdminUpdateUserInput) => + updateUser: async (input: UserAdminUpdateInput) => sdk .adminUpdateUser({ userId, input }) .then((res) => res.data) diff --git a/libs/web/user/data-access/src/lib/use-user-find-many-user.ts b/libs/web/user/data-access/src/lib/use-user-find-many-user.ts index a59043e..9ec7bf1 100644 --- a/libs/web/user/data-access/src/lib/use-user-find-many-user.ts +++ b/libs/web/user/data-access/src/lib/use-user-find-many-user.ts @@ -1,15 +1,15 @@ -import { UserFindManyUserInput } from '@pubkey-stack/sdk' +import { UserUserFindManyInput } from '@pubkey-stack/sdk' import { useSdk } from '@pubkey-stack/web-core-data-access' import { useQuery } from '@tanstack/react-query' import { useState } from 'react' -export function useUserFindManyUser(props?: UserFindManyUserInput) { +export function useUserFindManyUser(props?: UserUserFindManyInput) { const sdk = useSdk() const [limit, setLimit] = useState(props?.limit ?? 10) const [page, setPage] = useState(props?.page ?? 1) const [search, setSearch] = useState('') - const input: UserFindManyUserInput = { limit, page, search } + const input: UserUserFindManyInput = { limit, page, search } const query = useQuery({ queryKey: ['user', 'find-many-user', input], queryFn: () => sdk.userFindManyUser({ input }).then((res) => res.data), diff --git a/libs/web/user/data-access/src/lib/use-user-profile.ts b/libs/web/user/data-access/src/lib/use-user-profile.ts index eb13050..6419db9 100644 --- a/libs/web/user/data-access/src/lib/use-user-profile.ts +++ b/libs/web/user/data-access/src/lib/use-user-profile.ts @@ -1,4 +1,4 @@ -import { UserUpdateUserInput } from '@pubkey-stack/sdk' +import { UserUserUpdateInput } from '@pubkey-stack/sdk' import { useAuth, useMe } from '@pubkey-stack/web-auth-data-access' import { useSdk } from '@pubkey-stack/web-core-data-access' import { toastError } from '@pubkey-ui/core' @@ -13,7 +13,7 @@ export function useUserProfile() { return { user: query.data?.item, query, - updateUser: async (input: UserUpdateUserInput) => { + updateUser: async (input: UserUserUpdateInput) => { return sdk .userUpdateUser({ input, diff --git a/libs/web/user/feature/src/lib/admin-user-create-feature.tsx b/libs/web/user/feature/src/lib/admin-user-create-feature.tsx index db19d26..db87b44 100644 --- a/libs/web/user/feature/src/lib/admin-user-create-feature.tsx +++ b/libs/web/user/feature/src/lib/admin-user-create-feature.tsx @@ -1,4 +1,4 @@ -import { AdminCreateUserInput } from '@pubkey-stack/sdk' +import { UserAdminCreateInput } from '@pubkey-stack/sdk' import { useAdminFindManyUser } from '@pubkey-stack/web-user-data-access' import { AdminUiCreateUserForm } from '@pubkey-stack/web-user-ui' import { toastError, UiBack, UiCard, UiPage } from '@pubkey-ui/core' @@ -8,7 +8,7 @@ export function AdminUserCreateFeature() { const navigate = useNavigate() const { createUser } = useAdminFindManyUser() - async function submit(input: AdminCreateUserInput) { + async function submit(input: UserAdminCreateInput) { return createUser(input) .then((res) => { if (res?.id) { diff --git a/libs/web/user/ui/src/lib/admin-user-ui-create-form.tsx b/libs/web/user/ui/src/lib/admin-user-ui-create-form.tsx index 0577ae3..3b4278c 100644 --- a/libs/web/user/ui/src/lib/admin-user-ui-create-form.tsx +++ b/libs/web/user/ui/src/lib/admin-user-ui-create-form.tsx @@ -1,19 +1,19 @@ import { Button, Group } from '@mantine/core' -import { AdminCreateUserInput } from '@pubkey-stack/sdk' +import { UserAdminCreateInput } from '@pubkey-stack/sdk' import { formFieldPassword, formFieldText, UiForm, UiFormField } from '@pubkey-ui/core' -export function AdminUiCreateUserForm({ submit }: { submit: (res: AdminCreateUserInput) => Promise }) { - const model: AdminCreateUserInput = { +export function AdminUiCreateUserForm({ submit }: { submit: (res: UserAdminCreateInput) => Promise }) { + const model: UserAdminCreateInput = { username: '', password: '', } - const fields: UiFormField[] = [ + const fields: UiFormField[] = [ formFieldText('username', { label: 'Username', required: true }), formFieldPassword('password', { label: 'Password' }), ] return ( - submit(res as AdminCreateUserInput)}> + submit(res as UserAdminCreateInput)}> diff --git a/libs/web/user/ui/src/lib/admin-user-ui-search.tsx b/libs/web/user/ui/src/lib/admin-user-ui-search.tsx index 6c63135..1fced5b 100644 --- a/libs/web/user/ui/src/lib/admin-user-ui-search.tsx +++ b/libs/web/user/ui/src/lib/admin-user-ui-search.tsx @@ -1,5 +1,5 @@ import { useAdminFindManyUser } from '@pubkey-stack/web-user-data-access' -import { UserUiAutocomplete, type UserUiAutocompleteProps } from './user-ui-autocomplete' +import { UserUiAutocomplete, UserUiAutocompleteProps } from './user-ui-autocomplete' export type AdminUserUiSearchProps = Omit diff --git a/libs/web/user/ui/src/lib/admin-user-ui-update-form.tsx b/libs/web/user/ui/src/lib/admin-user-ui-update-form.tsx index 6e21f87..fe880a9 100644 --- a/libs/web/user/ui/src/lib/admin-user-ui-update-form.tsx +++ b/libs/web/user/ui/src/lib/admin-user-ui-update-form.tsx @@ -1,12 +1,12 @@ import { Button, Group } from '@mantine/core' -import { AdminUpdateUserInput, User, UserRole, UserStatus } from '@pubkey-stack/sdk' +import { User, UserAdminUpdateInput, UserRole, UserStatus } from '@pubkey-stack/sdk' import { formFieldCheckbox, formFieldSelect, formFieldText, getEnumOptions, UiForm, UiFormField } from '@pubkey-ui/core' export function AdminUiUpdateUserForm({ submit, user, }: { - submit: (res: AdminUpdateUserInput) => Promise + submit: (res: UserAdminUpdateInput) => Promise user: User }) { const model = { @@ -18,7 +18,7 @@ export function AdminUiUpdateUserForm({ username: user.username ?? '', } - const fields: UiFormField[] = [ + const fields: UiFormField[] = [ formFieldSelect('role', { label: 'Role', options: getEnumOptions(UserRole) }), formFieldSelect('status', { label: 'Status', options: getEnumOptions(UserStatus) }), formFieldText('username', { label: 'Username' }), @@ -27,7 +27,7 @@ export function AdminUiUpdateUserForm({ formFieldCheckbox('developer', { label: 'Developer' }), ] return ( - submit(res as AdminUpdateUserInput)}> + submit(res as UserAdminUpdateInput)}> diff --git a/libs/web/user/ui/src/lib/user-ui-autocomplete.tsx b/libs/web/user/ui/src/lib/user-ui-autocomplete.tsx index d594470..849247d 100644 --- a/libs/web/user/ui/src/lib/user-ui-autocomplete.tsx +++ b/libs/web/user/ui/src/lib/user-ui-autocomplete.tsx @@ -1,4 +1,4 @@ -import { Autocomplete, type AutocompleteProps, CloseIcon, Loader } from '@mantine/core' +import { Autocomplete, AutocompleteProps, CloseIcon, Loader } from '@mantine/core' import type { User } from '@pubkey-stack/sdk' import { IconUserSearch } from '@tabler/icons-react' diff --git a/libs/web/user/ui/src/lib/user-ui-item.tsx b/libs/web/user/ui/src/lib/user-ui-item.tsx index f8101b4..0dc8354 100644 --- a/libs/web/user/ui/src/lib/user-ui-item.tsx +++ b/libs/web/user/ui/src/lib/user-ui-item.tsx @@ -1,6 +1,6 @@ -import { AvatarProps, Group, type GroupProps, Stack, Text } from '@mantine/core' +import { AvatarProps, Group, GroupProps, Stack, Text } from '@mantine/core' import { User } from '@pubkey-stack/sdk' -import { UiAnchor, type UiAnchorProps } from '@pubkey-ui/core' +import { UiAnchor, UiAnchorProps } from '@pubkey-ui/core' import { UserUiAvatar } from './user-ui-avatar' export function UserUiItem({ @@ -23,7 +23,7 @@ export function UserUiItem({ - + {user?.username} {user.name ? ( diff --git a/libs/web/user/ui/src/lib/user-ui-search.tsx b/libs/web/user/ui/src/lib/user-ui-search.tsx index ebb83e1..df749d2 100644 --- a/libs/web/user/ui/src/lib/user-ui-search.tsx +++ b/libs/web/user/ui/src/lib/user-ui-search.tsx @@ -1,5 +1,5 @@ import { useUserFindManyUser } from '@pubkey-stack/web-user-data-access' -import { UserUiAutocomplete, type UserUiAutocompleteProps } from './user-ui-autocomplete' +import { UserUiAutocomplete, UserUiAutocompleteProps } from './user-ui-autocomplete' export type UserUiSearchProps = Omit diff --git a/libs/web/user/ui/src/lib/user-ui-update-form.tsx b/libs/web/user/ui/src/lib/user-ui-update-form.tsx index 4ace371..99d88c9 100644 --- a/libs/web/user/ui/src/lib/user-ui-update-form.tsx +++ b/libs/web/user/ui/src/lib/user-ui-update-form.tsx @@ -1,26 +1,26 @@ import { Button, Group } from '@mantine/core' -import { User, UserUpdateUserInput } from '@pubkey-stack/sdk' +import { User, UserUserUpdateInput } from '@pubkey-stack/sdk' import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core' export function UserUiUpdateForm({ submit, user, }: { - submit: (res: UserUpdateUserInput) => Promise + submit: (res: UserUserUpdateInput) => Promise user: User }) { - const model: UserUpdateUserInput = { + const model: UserUserUpdateInput = { avatarUrl: user.avatarUrl ?? user.avatarUrl ?? '', developer: user.developer ?? false, name: user.name ?? '', } - const fields: UiFormField[] = [ + const fields: UiFormField[] = [ formFieldText('name', { label: 'Name' }), formFieldText('avatarUrl', { label: 'Avatar URL' }), ] return ( - submit(res as UserUpdateUserInput)}> + submit(res as UserUserUpdateInput)}> From c6f4717a856d85977f31c1448a2936bfb3410621 Mon Sep 17 00:00:00 2001 From: Bram Borggreve Date: Sat, 16 Mar 2024 06:50:11 +0000 Subject: [PATCH 08/12] fix: homepage routing --- .../api-crud-generator.spec.ts.snap | 20 +-- .../api-feature-generator.spec.ts.snap | 8 +- .../web-crud-generator.spec.ts.snap | 148 +++++++++--------- .../web-feature-generator.spec.ts.snap | 72 ++++----- .../core/feature/src/lib/web-core-routes.tsx | 8 +- libs/web/home/feature/src/index.ts | 4 +- .../web/home/feature/src/lib/home-feature.tsx | 13 -- libs/web/home/feature/src/lib/home-routes.tsx | 10 ++ .../home/feature/src/lib/pages/about-page.tsx | 2 +- .../home/feature/src/lib/pages/home-page.tsx | 2 +- 10 files changed, 142 insertions(+), 145 deletions(-) delete mode 100644 libs/web/home/feature/src/lib/home-feature.tsx create mode 100644 libs/web/home/feature/src/lib/home-routes.tsx diff --git a/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap b/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap index 518cb9d..d8e8a19 100644 --- a/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap +++ b/libs/tools/src/generators/api-crud/__snapshots__/api-crud-generator.spec.ts.snap @@ -193,9 +193,9 @@ exports[`api-crud generator should create crud with modelOwnerId 1`] = ` "get-company-where-admin.input.ts": { "content": [ "import { Prisma } from '@prisma/client';", - "import { AdminFindManyCompanyInput } from '../dto/admin-find-many-company.input';", + "import { CompanyAdminFindManyInput } from '../dto/company-admin-find-many.input';", "export function getCompanyWhereAdminInput(", - "input: AdminFindManyCompanyInput", + "input: CompanyAdminFindManyInput", "): Prisma.CompanyWhereInput {", "const where: Prisma.CompanyWhereInput = {", "ownerId: input.ownerId,", @@ -1545,9 +1545,9 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "get-company-where-admin.input.ts": { "content": [ "import { Prisma } from '@prisma/client';", - "import { AdminFindManyCompanyInput } from '../dto/admin-find-many-company.input';", + "import { CompanyAdminFindManyInput } from '../dto/company-admin-find-many.input';", "export function getCompanyWhereAdminInput(", - "input: AdminFindManyCompanyInput", + "input: CompanyAdminFindManyInput", "): Prisma.CompanyWhereInput {", "const where: Prisma.CompanyWhereInput = {", "ownerId: input.ownerId,", @@ -1567,10 +1567,10 @@ exports[`api-crud generator should create crud with modelOwnerId for admin and u "get-company-where-user.input.ts": { "content": [ "import { Prisma } from '@prisma/client';", - "import { UserFindManyCompanyInput } from '../dto/user-find-many-company.input';", + "import { CompanyUserFindManyInput } from '../dto/company-user-find-many.input';", "export function getCompanyWhereUserInput(", "ownerId: string,", - "input: UserFindManyCompanyInput", + "input: CompanyUserFindManyInput", "): Prisma.CompanyWhereInput {", "const where: Prisma.CompanyWhereInput = {", "ownerId: ownerId,", @@ -3028,9 +3028,9 @@ exports[`api-crud generator should create crud with modelParentId 1`] = ` "get-company-where-admin.input.ts": { "content": [ "import { Prisma } from '@prisma/client';", - "import { AdminFindManyCompanyInput } from '../dto/admin-find-many-company.input';", + "import { CompanyAdminFindManyInput } from '../dto/company-admin-find-many.input';", "export function getCompanyWhereAdminInput(", - "input: AdminFindManyCompanyInput", + "input: CompanyAdminFindManyInput", "): Prisma.CompanyWhereInput {", "const where: Prisma.CompanyWhereInput = {", "ownerId: input.ownerId,", @@ -4322,9 +4322,9 @@ exports[`api-crud generator should run successfully 1`] = ` "get-company-where-admin.input.ts": { "content": [ "import { Prisma } from '@prisma/client';", - "import { AdminFindManyCompanyInput } from '../dto/admin-find-many-company.input';", + "import { CompanyAdminFindManyInput } from '../dto/company-admin-find-many.input';", "export function getCompanyWhereAdminInput(", - "input: AdminFindManyCompanyInput", + "input: CompanyAdminFindManyInput", "): Prisma.CompanyWhereInput {", "const where: Prisma.CompanyWhereInput = {};", "if (input.search) {", diff --git a/libs/tools/src/generators/api-feature/__snapshots__/api-feature-generator.spec.ts.snap b/libs/tools/src/generators/api-feature/__snapshots__/api-feature-generator.spec.ts.snap index 23d3a99..d8fa100 100644 --- a/libs/tools/src/generators/api-feature/__snapshots__/api-feature-generator.spec.ts.snap +++ b/libs/tools/src/generators/api-feature/__snapshots__/api-feature-generator.spec.ts.snap @@ -274,10 +274,10 @@ export class TestPaging extends PagingResponse(Test) {} exports[`api-feature generator should generate the feature libraries with crud for admin and user 16`] = ` "import { Prisma } from '@prisma/client'; -import { AdminFindManyTestInput } from '../dto/admin-find-many-test.input'; +import { TestAdminFindManyInput } from '../dto/test-admin-find-many.input'; export function getTestWhereAdminInput( - input: AdminFindManyTestInput + input: TestAdminFindManyInput ): Prisma.TestWhereInput { const where: Prisma.TestWhereInput = {}; @@ -295,10 +295,10 @@ export function getTestWhereAdminInput( exports[`api-feature generator should generate the feature libraries with crud for admin and user 17`] = ` "import { Prisma } from '@prisma/client'; -import { UserFindManyTestInput } from '../dto/user-find-many-test.input'; +import { TestUserFindManyInput } from '../dto/test-user-find-many.input'; export function getTestWhereUserInput( - input: UserFindManyTestInput + input: TestUserFindManyInput ): Prisma.TestWhereInput { const where: Prisma.TestWhereInput = {}; diff --git a/libs/tools/src/generators/web-crud/__snapshots__/web-crud-generator.spec.ts.snap b/libs/tools/src/generators/web-crud/__snapshots__/web-crud-generator.spec.ts.snap index ebafcca..e4bac21 100644 --- a/libs/tools/src/generators/web-crud/__snapshots__/web-crud-generator.spec.ts.snap +++ b/libs/tools/src/generators/web-crud/__snapshots__/web-crud-generator.spec.ts.snap @@ -92,21 +92,21 @@ exports[`web-crud generator should create crud with modelOwnerId 1`] = ` "use-manager-find-many-company.ts": { "content": [ "import {", - "ManagerCreateCompanyInput,", - "ManagerFindManyCompanyInput,", + "CompanyManagerCreateInput,", + "CompanyManagerFindManyInput,", "} from '@proj/sdk';", "import { useSdk } from '@proj/test-core-data-access';", "import { toastError, toastSuccess } from '@pubkey-ui/core';", "import { useQuery } from '@tanstack/react-query';", "import { useState } from 'react';", "export function useManagerFindManyCompany(", - "props: Partial = {}", + "props: Partial = {}", ") {", "const sdk = useSdk();", "const [limit, setLimit] = useState(props?.limit ?? 10);", "const [page, setPage] = useState(props?.page ?? 1);", "const [search, setSearch] = useState(props?.search ?? '');", - "const input: ManagerFindManyCompanyInput = { page, limit, search };", + "const input: CompanyManagerFindManyInput = { page, limit, search };", "const query = useQuery({", "queryKey: ['manager', 'find-many-company', input],", "queryFn: () =>", @@ -125,7 +125,7 @@ exports[`web-crud generator should create crud with modelOwnerId 1`] = ` "total,", "},", "setSearch,", - "createCompany: (input: ManagerCreateCompanyInput) =>", + "createCompany: (input: CompanyManagerCreateInput) =>", "sdk", ".managerCreateCompany({ input })", ".then((res) => res.data)", @@ -154,7 +154,7 @@ exports[`web-crud generator should create crud with modelOwnerId 1`] = ` }, "use-manager-find-one-company.ts": { "content": [ - "import { ManagerUpdateCompanyInput } from '@proj/sdk';", + "import { CompanyManagerUpdateInput } from '@proj/sdk';", "import { useSdk } from '@proj/test-core-data-access';", "import { toastError, toastSuccess } from '@pubkey-ui/core';", "import { useQuery } from '@tanstack/react-query';", @@ -170,7 +170,7 @@ exports[`web-crud generator should create crud with modelOwnerId 1`] = ` "return {", "item,", "query,", - "updateCompany: async (input: ManagerUpdateCompanyInput) =>", + "updateCompany: async (input: CompanyManagerUpdateInput) =>", "sdk", ".managerUpdateCompany({ companyId, input })", ".then((res) => res.data)", @@ -342,7 +342,7 @@ exports[`web-crud generator should create crud with modelOwnerId 1`] = ` "children": { "manager-company-create.feature.tsx": { "content": [ - "import { ManagerCreateCompanyInput } from '@proj/sdk';", + "import { CompanyManagerCreateInput } from '@proj/sdk';", "import { useManagerFindManyCompany } from '@proj/test-company-data-access';", "import { ManagerCompanyUiCreateForm } from '@proj/test-company-ui';", "import { toastError, UiBack, UiCard, UiPage } from '@pubkey-ui/core';", @@ -350,7 +350,7 @@ exports[`web-crud generator should create crud with modelOwnerId 1`] = ` "export function ManagerCompanyCreateFeature() {", "const navigate = useNavigate();", "const { createCompany } = useManagerFindManyCompany();", - "async function submit(input: ManagerCreateCompanyInput) {", + "async function submit(input: CompanyManagerCreateInput) {", "return createCompany(input)", ".then((res) => {", "if (res) {", @@ -880,19 +880,19 @@ exports[`web-crud generator should create crud with modelOwnerId 1`] = ` "manager-company-ui-create-form.tsx": { "content": [ "import { Button, Group } from '@mantine/core';", - "import { ManagerCreateCompanyInput } from '@proj/sdk';", + "import { CompanyManagerCreateInput } from '@proj/sdk';", "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", "export function ManagerCompanyUiCreateForm({", "submit,", "}: {", - "submit: (res: ManagerCreateCompanyInput) => Promise;", + "submit: (res: CompanyManagerCreateInput) => Promise;", "}) {", - "const model: ManagerCreateCompanyInput = {", + "const model: CompanyManagerCreateInput = {", "name: '',", "location: '',", "phone: '',", "};", - "const fields: UiFormField[] = [", + "const fields: UiFormField[] = [", "formFieldText('name', { label: 'name', required: true }),", "formFieldText('location', { label: 'location', required: true }),", "formFieldText('phone', { label: 'phone', required: true }),", @@ -901,7 +901,7 @@ exports[`web-crud generator should create crud with modelOwnerId 1`] = ` " submit(res as ManagerCreateCompanyInput)}", + "submit={(res) => submit(res as CompanyManagerCreateInput)}", ">", "", "", @@ -993,21 +993,21 @@ exports[`web-crud generator should create crud with modelOwnerId 1`] = ` "manager-company-ui-update-form.tsx": { "content": [ "import { Button, Group } from '@mantine/core';", - "import { ManagerUpdateCompanyInput, Company } from '@proj/sdk';", + "import { CompanyManagerUpdateInput, Company } from '@proj/sdk';", "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", "export function ManagerCompanyUiUpdateForm({", "submit,", "company,", "}: {", - "submit: (res: ManagerUpdateCompanyInput) => Promise;", + "submit: (res: CompanyManagerUpdateInput) => Promise;", "company: Company;", "}) {", - "const model: ManagerUpdateCompanyInput = {", + "const model: CompanyManagerUpdateInput = {", "name: company.name ?? '',", "location: company.location ?? '',", "phone: company.phone ?? '',", "};", - "const fields: UiFormField[] = [", + "const fields: UiFormField[] = [", "formFieldText('name', { label: 'name' }),", "formFieldText('location', { label: 'location' }),", "formFieldText('phone', { label: 'phone' }),", @@ -1016,7 +1016,7 @@ exports[`web-crud generator should create crud with modelOwnerId 1`] = ` " submit(res as ManagerUpdateCompanyInput)}", + "submit={(res) => submit(res as CompanyManagerUpdateInput)}", ">", "", "", @@ -1710,19 +1710,19 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "children": { "use-admin-find-many-company.ts": { "content": [ - "import { AdminCreateCompanyInput, AdminFindManyCompanyInput } from '@proj/sdk';", + "import { CompanyAdminCreateInput, CompanyAdminFindManyInput } from '@proj/sdk';", "import { useSdk } from '@proj/test-core-data-access';", "import { toastError, toastSuccess } from '@pubkey-ui/core';", "import { useQuery } from '@tanstack/react-query';", "import { useState } from 'react';", "export function useAdminFindManyCompany(", - "props: Partial & { ownerId: string }", + "props: Partial & { ownerId: string }", ") {", "const sdk = useSdk();", "const [limit, setLimit] = useState(props?.limit ?? 10);", "const [page, setPage] = useState(props?.page ?? 1);", "const [search, setSearch] = useState(props?.search ?? '');", - "const input: AdminFindManyCompanyInput = {", + "const input: CompanyAdminFindManyInput = {", "page,", "limit,", "search,", @@ -1745,7 +1745,7 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "total,", "},", "setSearch,", - "createCompany: (input: AdminCreateCompanyInput) =>", + "createCompany: (input: CompanyAdminCreateInput) =>", "sdk", ".adminCreateCompany({ input: { ...input, ownerId: props.ownerId } })", ".then((res) => res.data)", @@ -1774,7 +1774,7 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u }, "use-admin-find-one-company.ts": { "content": [ - "import { AdminUpdateCompanyInput } from '@proj/sdk';", + "import { CompanyAdminUpdateInput } from '@proj/sdk';", "import { useSdk } from '@proj/test-core-data-access';", "import { toastError, toastSuccess } from '@pubkey-ui/core';", "import { useQuery } from '@tanstack/react-query';", @@ -1790,7 +1790,7 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "return {", "item,", "query,", - "updateCompany: async (input: AdminUpdateCompanyInput) =>", + "updateCompany: async (input: CompanyAdminUpdateInput) =>", "sdk", ".adminUpdateCompany({ companyId, input })", ".then((res) => res.data)", @@ -1815,19 +1815,19 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u }, "use-user-find-many-company.ts": { "content": [ - "import { UserCreateCompanyInput, UserFindManyCompanyInput } from '@proj/sdk';", + "import { CompanyUserCreateInput, CompanyUserFindManyInput } from '@proj/sdk';", "import { useSdk } from '@proj/test-core-data-access';", "import { toastError, toastSuccess } from '@pubkey-ui/core';", "import { useQuery } from '@tanstack/react-query';", "import { useState } from 'react';", "export function useUserFindManyCompany(", - "props: Partial = {}", + "props: Partial = {}", ") {", "const sdk = useSdk();", "const [limit, setLimit] = useState(props?.limit ?? 10);", "const [page, setPage] = useState(props?.page ?? 1);", "const [search, setSearch] = useState(props?.search ?? '');", - "const input: UserFindManyCompanyInput = { page, limit, search };", + "const input: CompanyUserFindManyInput = { page, limit, search };", "const query = useQuery({", "queryKey: ['user', 'find-many-company', input],", "queryFn: () => sdk.userFindManyCompany({ input }).then((res) => res.data),", @@ -1845,7 +1845,7 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "total,", "},", "setSearch,", - "createCompany: (input: UserCreateCompanyInput) =>", + "createCompany: (input: CompanyUserCreateInput) =>", "sdk", ".userCreateCompany({ input })", ".then((res) => res.data)", @@ -1874,7 +1874,7 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u }, "use-user-find-one-company.ts": { "content": [ - "import { UserUpdateCompanyInput } from '@proj/sdk';", + "import { CompanyUserUpdateInput } from '@proj/sdk';", "import { useSdk } from '@proj/test-core-data-access';", "import { toastError, toastSuccess } from '@pubkey-ui/core';", "import { useQuery } from '@tanstack/react-query';", @@ -1890,7 +1890,7 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "return {", "item,", "query,", - "updateCompany: async (input: UserUpdateCompanyInput) =>", + "updateCompany: async (input: CompanyUserUpdateInput) =>", "sdk", ".userUpdateCompany({ companyId, input })", ".then((res) => res.data)", @@ -2065,7 +2065,7 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "children": { "admin-company-create.feature.tsx": { "content": [ - "import { AdminCreateCompanyInput } from '@proj/sdk';", + "import { CompanyAdminCreateInput } from '@proj/sdk';", "import { useAdminFindManyCompany } from '@proj/test-company-data-access';", "import { AdminCompanyUiCreateForm } from '@proj/test-company-ui';", "import { toastError, UiBack, UiCard } from '@pubkey-ui/core';", @@ -2074,7 +2074,7 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "export function AdminCompanyCreateFeature({ ownerId }: { ownerId: string }) {", "const navigate = useNavigate();", "const { createCompany } = useAdminFindManyCompany({ ownerId });", - "async function submit(input: AdminCreateCompanyInput) {", + "async function submit(input: CompanyAdminCreateInput) {", "return createCompany(input)", ".then((res) => {", "if (res) {", @@ -2295,7 +2295,7 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u }, "user-company-create.feature.tsx": { "content": [ - "import { UserCreateCompanyInput } from '@proj/sdk';", + "import { CompanyUserCreateInput } from '@proj/sdk';", "import { useUserFindManyCompany } from '@proj/test-company-data-access';", "import { UserCompanyUiCreateForm } from '@proj/test-company-ui';", "import { toastError, UiBack, UiCard, UiPage } from '@pubkey-ui/core';", @@ -2303,7 +2303,7 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "export function UserCompanyCreateFeature() {", "const navigate = useNavigate();", "const { createCompany } = useUserFindManyCompany();", - "async function submit(input: UserCreateCompanyInput) {", + "async function submit(input: CompanyUserCreateInput) {", "return createCompany(input)", ".then((res) => {", "if (res) {", @@ -2669,20 +2669,20 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "admin-company-ui-create-form.tsx": { "content": [ "import { Button, Group } from '@mantine/core';", - "import { AdminCreateCompanyInput } from '@proj/sdk';", + "import { CompanyAdminCreateInput } from '@proj/sdk';", "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", "export function AdminCompanyUiCreateForm({", "submit,", "}: {", - "submit: (res: AdminCreateCompanyInput) => Promise;", + "submit: (res: CompanyAdminCreateInput) => Promise;", "}) {", - "const model: AdminCreateCompanyInput = {", + "const model: CompanyAdminCreateInput = {", "name: '',", "location: '',", "phone: '',", "ownerId: '',", "};", - "const fields: UiFormField[] = [", + "const fields: UiFormField[] = [", "formFieldText('name', { label: 'name', required: true }),", "formFieldText('location', { label: 'location', required: true }),", "formFieldText('phone', { label: 'phone', required: true }),", @@ -2691,7 +2691,7 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u " submit(res as AdminCreateCompanyInput)}", + "submit={(res) => submit(res as CompanyAdminCreateInput)}", ">", "", "", @@ -2783,21 +2783,21 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "admin-company-ui-update-form.tsx": { "content": [ "import { Button, Group } from '@mantine/core';", - "import { AdminUpdateCompanyInput, Company } from '@proj/sdk';", + "import { CompanyAdminUpdateInput, Company } from '@proj/sdk';", "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", "export function AdminCompanyUiUpdateForm({", "submit,", "company,", "}: {", - "submit: (res: AdminUpdateCompanyInput) => Promise;", + "submit: (res: CompanyAdminUpdateInput) => Promise;", "company: Company;", "}) {", - "const model: AdminUpdateCompanyInput = {", + "const model: CompanyAdminUpdateInput = {", "name: company.name ?? '',", "location: company.location ?? '',", "phone: company.phone ?? '',", "};", - "const fields: UiFormField[] = [", + "const fields: UiFormField[] = [", "formFieldText('name', { label: 'name' }),", "formFieldText('location', { label: 'location' }),", "formFieldText('phone', { label: 'phone' }),", @@ -2806,7 +2806,7 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u " submit(res as AdminUpdateCompanyInput)}", + "submit={(res) => submit(res as CompanyAdminUpdateInput)}", ">", "", "", @@ -2982,19 +2982,19 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "user-company-ui-create-form.tsx": { "content": [ "import { Button, Group } from '@mantine/core';", - "import { UserCreateCompanyInput } from '@proj/sdk';", + "import { CompanyUserCreateInput } from '@proj/sdk';", "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", "export function UserCompanyUiCreateForm({", "submit,", "}: {", - "submit: (res: UserCreateCompanyInput) => Promise;", + "submit: (res: CompanyUserCreateInput) => Promise;", "}) {", - "const model: UserCreateCompanyInput = {", + "const model: CompanyUserCreateInput = {", "name: '',", "location: '',", "phone: '',", "};", - "const fields: UiFormField[] = [", + "const fields: UiFormField[] = [", "formFieldText('name', { label: 'name', required: true }),", "formFieldText('location', { label: 'location', required: true }),", "formFieldText('phone', { label: 'phone', required: true }),", @@ -3003,7 +3003,7 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u " submit(res as UserCreateCompanyInput)}", + "submit={(res) => submit(res as CompanyUserCreateInput)}", ">", "", "", @@ -3095,21 +3095,21 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "user-company-ui-update-form.tsx": { "content": [ "import { Button, Group } from '@mantine/core';", - "import { UserUpdateCompanyInput, Company } from '@proj/sdk';", + "import { CompanyUserUpdateInput, Company } from '@proj/sdk';", "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", "export function UserCompanyUiUpdateForm({", "submit,", "company,", "}: {", - "submit: (res: UserUpdateCompanyInput) => Promise;", + "submit: (res: CompanyUserUpdateInput) => Promise;", "company: Company;", "}) {", - "const model: UserUpdateCompanyInput = {", + "const model: CompanyUserUpdateInput = {", "name: company.name ?? '',", "location: company.location ?? '',", "phone: company.phone ?? '',", "};", - "const fields: UiFormField[] = [", + "const fields: UiFormField[] = [", "formFieldText('name', { label: 'name' }),", "formFieldText('location', { label: 'location' }),", "formFieldText('phone', { label: 'phone' }),", @@ -3118,7 +3118,7 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u " submit(res as UserUpdateCompanyInput)}", + "submit={(res) => submit(res as CompanyUserUpdateInput)}", ">", "", "", @@ -3818,21 +3818,21 @@ exports[`web-crud generator should create crud with modelParentId 1`] = ` "use-manager-find-many-company.ts": { "content": [ "import {", - "ManagerCreateCompanyInput,", - "ManagerFindManyCompanyInput,", + "CompanyManagerCreateInput,", + "CompanyManagerFindManyInput,", "} from '@proj/sdk';", "import { useSdk } from '@proj/test-core-data-access';", "import { toastError, toastSuccess } from '@pubkey-ui/core';", "import { useQuery } from '@tanstack/react-query';", "import { useState } from 'react';", "export function useManagerFindManyCompany(", - "props: Partial = {}", + "props: Partial = {}", ") {", "const sdk = useSdk();", "const [limit, setLimit] = useState(props?.limit ?? 10);", "const [page, setPage] = useState(props?.page ?? 1);", "const [search, setSearch] = useState(props?.search ?? '');", - "const input: ManagerFindManyCompanyInput = { page, limit, search };", + "const input: CompanyManagerFindManyInput = { page, limit, search };", "const query = useQuery({", "queryKey: ['manager', 'find-many-company', input],", "queryFn: () =>", @@ -3851,7 +3851,7 @@ exports[`web-crud generator should create crud with modelParentId 1`] = ` "total,", "},", "setSearch,", - "createCompany: (input: ManagerCreateCompanyInput) =>", + "createCompany: (input: CompanyManagerCreateInput) =>", "sdk", ".managerCreateCompany({ input })", ".then((res) => res.data)", @@ -3880,7 +3880,7 @@ exports[`web-crud generator should create crud with modelParentId 1`] = ` }, "use-manager-find-one-company.ts": { "content": [ - "import { ManagerUpdateCompanyInput } from '@proj/sdk';", + "import { CompanyManagerUpdateInput } from '@proj/sdk';", "import { useSdk } from '@proj/test-core-data-access';", "import { toastError, toastSuccess } from '@pubkey-ui/core';", "import { useQuery } from '@tanstack/react-query';", @@ -3896,7 +3896,7 @@ exports[`web-crud generator should create crud with modelParentId 1`] = ` "return {", "item,", "query,", - "updateCompany: async (input: ManagerUpdateCompanyInput) =>", + "updateCompany: async (input: CompanyManagerUpdateInput) =>", "sdk", ".managerUpdateCompany({ companyId, input })", ".then((res) => res.data)", @@ -4068,7 +4068,7 @@ exports[`web-crud generator should create crud with modelParentId 1`] = ` "children": { "manager-company-create.feature.tsx": { "content": [ - "import { ManagerCreateCompanyInput } from '@proj/sdk';", + "import { CompanyManagerCreateInput } from '@proj/sdk';", "import { useManagerFindManyCompany } from '@proj/test-company-data-access';", "import { ManagerCompanyUiCreateForm } from '@proj/test-company-ui';", "import { toastError, UiBack, UiCard, UiPage } from '@pubkey-ui/core';", @@ -4076,7 +4076,7 @@ exports[`web-crud generator should create crud with modelParentId 1`] = ` "export function ManagerCompanyCreateFeature() {", "const navigate = useNavigate();", "const { createCompany } = useManagerFindManyCompany();", - "async function submit(input: ManagerCreateCompanyInput) {", + "async function submit(input: CompanyManagerCreateInput) {", "return createCompany(input)", ".then((res) => {", "if (res) {", @@ -4606,19 +4606,19 @@ exports[`web-crud generator should create crud with modelParentId 1`] = ` "manager-company-ui-create-form.tsx": { "content": [ "import { Button, Group } from '@mantine/core';", - "import { ManagerCreateCompanyInput } from '@proj/sdk';", + "import { CompanyManagerCreateInput } from '@proj/sdk';", "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", "export function ManagerCompanyUiCreateForm({", "submit,", "}: {", - "submit: (res: ManagerCreateCompanyInput) => Promise;", + "submit: (res: CompanyManagerCreateInput) => Promise;", "}) {", - "const model: ManagerCreateCompanyInput = {", + "const model: CompanyManagerCreateInput = {", "name: '',", "location: '',", "phone: '',", "};", - "const fields: UiFormField[] = [", + "const fields: UiFormField[] = [", "formFieldText('name', { label: 'name', required: true }),", "formFieldText('location', { label: 'location', required: true }),", "formFieldText('phone', { label: 'phone', required: true }),", @@ -4627,7 +4627,7 @@ exports[`web-crud generator should create crud with modelParentId 1`] = ` " submit(res as ManagerCreateCompanyInput)}", + "submit={(res) => submit(res as CompanyManagerCreateInput)}", ">", "", "", @@ -4719,21 +4719,21 @@ exports[`web-crud generator should create crud with modelParentId 1`] = ` "manager-company-ui-update-form.tsx": { "content": [ "import { Button, Group } from '@mantine/core';", - "import { ManagerUpdateCompanyInput, Company } from '@proj/sdk';", + "import { CompanyManagerUpdateInput, Company } from '@proj/sdk';", "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", "export function ManagerCompanyUiUpdateForm({", "submit,", "company,", "}: {", - "submit: (res: ManagerUpdateCompanyInput) => Promise;", + "submit: (res: CompanyManagerUpdateInput) => Promise;", "company: Company;", "}) {", - "const model: ManagerUpdateCompanyInput = {", + "const model: CompanyManagerUpdateInput = {", "name: company.name ?? '',", "location: company.location ?? '',", "phone: company.phone ?? '',", "};", - "const fields: UiFormField[] = [", + "const fields: UiFormField[] = [", "formFieldText('name', { label: 'name' }),", "formFieldText('location', { label: 'location' }),", "formFieldText('phone', { label: 'phone' }),", @@ -4742,7 +4742,7 @@ exports[`web-crud generator should create crud with modelParentId 1`] = ` " submit(res as ManagerUpdateCompanyInput)}", + "submit={(res) => submit(res as CompanyManagerUpdateInput)}", ">", "", "", diff --git a/libs/tools/src/generators/web-feature/__snapshots__/web-feature-generator.spec.ts.snap b/libs/tools/src/generators/web-feature/__snapshots__/web-feature-generator.spec.ts.snap index 33e8038..62c88cc 100644 --- a/libs/tools/src/generators/web-feature/__snapshots__/web-feature-generator.spec.ts.snap +++ b/libs/tools/src/generators/web-feature/__snapshots__/web-feature-generator.spec.ts.snap @@ -15,21 +15,21 @@ export * from './lib/use-user-find-one-test'; `; exports[`web-feature generator should run successfully with crud 5`] = ` -"import { AdminCreateTestInput, AdminFindManyTestInput } from '@proj/sdk'; +"import { TestAdminCreateInput, TestAdminFindManyInput } from '@proj/sdk'; import { useSdk } from '@proj/web-core-data-access'; import { toastError, toastSuccess } from '@pubkey-ui/core'; import { useQuery } from '@tanstack/react-query'; import { useState } from 'react'; export function useAdminFindManyTest( - props: Partial = {} + props: Partial = {} ) { const sdk = useSdk(); const [limit, setLimit] = useState(props?.limit ?? 10); const [page, setPage] = useState(props?.page ?? 1); const [search, setSearch] = useState(props?.search ?? ''); - const input: AdminFindManyTestInput = { page, limit, search }; + const input: TestAdminFindManyInput = { page, limit, search }; const query = useQuery({ queryKey: ['admin', 'find-many-test', input], queryFn: () => sdk.adminFindManyTest({ input }).then((res) => res.data), @@ -48,7 +48,7 @@ export function useAdminFindManyTest( total, }, setSearch, - createTest: (input: AdminCreateTestInput) => + createTest: (input: TestAdminCreateInput) => sdk .adminCreateTest({ input }) .then((res) => res.data) @@ -75,7 +75,7 @@ export function useAdminFindManyTest( `; exports[`web-feature generator should run successfully with crud 6`] = ` -"import { AdminUpdateTestInput } from '@proj/sdk'; +"import { TestAdminUpdateInput } from '@proj/sdk'; import { useSdk } from '@proj/web-core-data-access'; import { toastError, toastSuccess } from '@pubkey-ui/core'; import { useQuery } from '@tanstack/react-query'; @@ -92,7 +92,7 @@ export function useAdminFindOneTest({ testId }: { testId: string }) { return { item, query, - updateTest: async (input: AdminUpdateTestInput) => + updateTest: async (input: TestAdminUpdateInput) => sdk .adminUpdateTest({ testId, input }) .then((res) => res.data) @@ -115,21 +115,21 @@ export function useAdminFindOneTest({ testId }: { testId: string }) { `; exports[`web-feature generator should run successfully with crud 7`] = ` -"import { UserCreateTestInput, UserFindManyTestInput } from '@proj/sdk'; +"import { TestUserCreateInput, TestUserFindManyInput } from '@proj/sdk'; import { useSdk } from '@proj/web-core-data-access'; import { toastError, toastSuccess } from '@pubkey-ui/core'; import { useQuery } from '@tanstack/react-query'; import { useState } from 'react'; export function useUserFindManyTest( - props: Partial = {} + props: Partial = {} ) { const sdk = useSdk(); const [limit, setLimit] = useState(props?.limit ?? 10); const [page, setPage] = useState(props?.page ?? 1); const [search, setSearch] = useState(props?.search ?? ''); - const input: UserFindManyTestInput = { page, limit, search }; + const input: TestUserFindManyInput = { page, limit, search }; const query = useQuery({ queryKey: ['user', 'find-many-test', input], queryFn: () => sdk.userFindManyTest({ input }).then((res) => res.data), @@ -148,7 +148,7 @@ export function useUserFindManyTest( total, }, setSearch, - createTest: (input: UserCreateTestInput) => + createTest: (input: TestUserCreateInput) => sdk .userCreateTest({ input }) .then((res) => res.data) @@ -175,7 +175,7 @@ export function useUserFindManyTest( `; exports[`web-feature generator should run successfully with crud 8`] = ` -"import { UserUpdateTestInput } from '@proj/sdk'; +"import { TestUserUpdateInput } from '@proj/sdk'; import { useSdk } from '@proj/web-core-data-access'; import { toastError, toastSuccess } from '@pubkey-ui/core'; import { useQuery } from '@tanstack/react-query'; @@ -192,7 +192,7 @@ export function useUserFindOneTest({ testId }: { testId: string }) { return { item, query, - updateTest: async (input: UserUpdateTestInput) => + updateTest: async (input: TestUserUpdateInput) => sdk .userUpdateTest({ testId, input }) .then((res) => res.data) @@ -223,7 +223,7 @@ export const UserTestFeature = lazy(() => import('./lib/user-test.routes')); `; exports[`web-feature generator should run successfully with crud 10`] = ` -"import { AdminCreateTestInput } from '@proj/sdk'; +"import { TestAdminCreateInput } from '@proj/sdk'; import { useAdminFindManyTest } from '@proj/web-test-data-access'; import { AdminTestUiCreateForm } from '@proj/web-test-ui'; import { toastError, UiBack, UiCard, UiPage } from '@pubkey-ui/core'; @@ -233,7 +233,7 @@ export function AdminTestCreateFeature() { const navigate = useNavigate(); const { createTest } = useAdminFindManyTest(); - async function submit(input: AdminCreateTestInput) { + async function submit(input: TestAdminCreateInput) { return createTest(input) .then((res) => { if (res) { @@ -448,7 +448,7 @@ export default function AdminTestRoutes() { `; exports[`web-feature generator should run successfully with crud 16`] = ` -"import { UserCreateTestInput } from '@proj/sdk'; +"import { TestUserCreateInput } from '@proj/sdk'; import { useUserFindManyTest } from '@proj/web-test-data-access'; import { UserTestUiCreateForm } from '@proj/web-test-ui'; import { toastError, UiBack, UiCard, UiPage } from '@pubkey-ui/core'; @@ -458,7 +458,7 @@ export function UserTestCreateFeature() { const navigate = useNavigate(); const { createTest } = useUserFindManyTest(); - async function submit(input: UserCreateTestInput) { + async function submit(input: TestUserCreateInput) { return createTest(input) .then((res) => { if (res) { @@ -682,26 +682,26 @@ export * from './lib/user-test-ui-update-form'; exports[`web-feature generator should run successfully with crud 23`] = ` "import { Button, Group } from '@mantine/core'; -import { AdminCreateTestInput } from '@proj/sdk'; +import { TestAdminCreateInput } from '@proj/sdk'; import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core'; export function AdminTestUiCreateForm({ submit, }: { - submit: (res: AdminCreateTestInput) => Promise; + submit: (res: TestAdminCreateInput) => Promise; }) { - const model: AdminCreateTestInput = { + const model: TestAdminCreateInput = { name: '', }; - const fields: UiFormField[] = [ + const fields: UiFormField[] = [ formFieldText('name', { label: 'name', required: true }), ]; return ( submit(res as AdminCreateTestInput)} + submit={(res) => submit(res as TestAdminCreateInput)} > @@ -790,28 +790,28 @@ export function AdminTestUiTable({ exports[`web-feature generator should run successfully with crud 25`] = ` "import { Button, Group } from '@mantine/core'; -import { AdminUpdateTestInput, Test } from '@proj/sdk'; +import { TestAdminUpdateInput, Test } from '@proj/sdk'; import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core'; export function AdminTestUiUpdateForm({ submit, test, }: { - submit: (res: AdminUpdateTestInput) => Promise; + submit: (res: TestAdminUpdateInput) => Promise; test: Test; }) { - const model: AdminUpdateTestInput = { + const model: TestAdminUpdateInput = { name: test.name ?? '', }; - const fields: UiFormField[] = [ + const fields: UiFormField[] = [ formFieldText('name', { label: 'name' }), ]; return ( submit(res as AdminUpdateTestInput)} + submit={(res) => submit(res as TestAdminUpdateInput)} > @@ -974,26 +974,26 @@ export function TestUiItem({ exports[`web-feature generator should run successfully with crud 31`] = ` "import { Button, Group } from '@mantine/core'; -import { UserCreateTestInput } from '@proj/sdk'; +import { TestUserCreateInput } from '@proj/sdk'; import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core'; export function UserTestUiCreateForm({ submit, }: { - submit: (res: UserCreateTestInput) => Promise; + submit: (res: TestUserCreateInput) => Promise; }) { - const model: UserCreateTestInput = { + const model: TestUserCreateInput = { name: '', }; - const fields: UiFormField[] = [ + const fields: UiFormField[] = [ formFieldText('name', { label: 'name', required: true }), ]; return ( submit(res as UserCreateTestInput)} + submit={(res) => submit(res as TestUserCreateInput)} > @@ -1082,28 +1082,28 @@ export function UserTestUiTable({ exports[`web-feature generator should run successfully with crud 33`] = ` "import { Button, Group } from '@mantine/core'; -import { UserUpdateTestInput, Test } from '@proj/sdk'; +import { TestUserUpdateInput, Test } from '@proj/sdk'; import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core'; export function UserTestUiUpdateForm({ submit, test, }: { - submit: (res: UserUpdateTestInput) => Promise; + submit: (res: TestUserUpdateInput) => Promise; test: Test; }) { - const model: UserUpdateTestInput = { + const model: TestUserUpdateInput = { name: test.name ?? '', }; - const fields: UiFormField[] = [ + const fields: UiFormField[] = [ formFieldText('name', { label: 'name' }), ]; return ( submit(res as UserUpdateTestInput)} + submit={(res) => submit(res as TestUserUpdateInput)} > diff --git a/libs/web/core/feature/src/lib/web-core-routes.tsx b/libs/web/core/feature/src/lib/web-core-routes.tsx index 6f0ca5b..78af965 100644 --- a/libs/web/core/feature/src/lib/web-core-routes.tsx +++ b/libs/web/core/feature/src/lib/web-core-routes.tsx @@ -1,5 +1,6 @@ +import { useAuth } from '@pubkey-stack/web-auth-data-access' import { AuthLoginFeature, AuthRegisterFeature } from '@pubkey-stack/web-auth-feature' -import { HomeFeature } from '@pubkey-stack/web-home-feature' +import { HOME_ROUTES } from '@pubkey-stack/web-home-feature' import { UiNotFound } from '@pubkey-ui/core' import { lazy } from 'react' import { Navigate } from 'react-router-dom' @@ -9,8 +10,9 @@ export const LazyAdminFeature = lazy(() => import('./web-core-routes-admin')) export const LazyUserFeature = lazy(() => import('./web-core-routes-user')) export function WebCoreRoutes() { + const { user } = useAuth() return useGuardedRoutes({ - index: '/dashboard', + index: user ? '/dashboard' : '/home', admin: [ // Here you can add routes that are only accessible by admins under the /admin/* path // Visit /admin/custom-admin-page to see this route @@ -30,7 +32,7 @@ export function WebCoreRoutes() { { path: '/login', element: }, { path: '/register', element: }, // Homepage - { path: '/*', element: }, + ...HOME_ROUTES, // Routes for the 404 page { path: '/404', element: }, { path: '*', element: }, diff --git a/libs/web/home/feature/src/index.ts b/libs/web/home/feature/src/index.ts index 916f526..d7fef7d 100644 --- a/libs/web/home/feature/src/index.ts +++ b/libs/web/home/feature/src/index.ts @@ -1,3 +1 @@ -import { lazy } from 'react' - -export const HomeFeature = lazy(() => import('./lib/home-feature')) +export * from './lib/home-routes' diff --git a/libs/web/home/feature/src/lib/home-feature.tsx b/libs/web/home/feature/src/lib/home-feature.tsx deleted file mode 100644 index 8935b48..0000000 --- a/libs/web/home/feature/src/lib/home-feature.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { Navigate, Route, Routes } from 'react-router-dom' -import { AboutPage } from './pages/about-page' -import { HomePage } from './pages/home-page' - -export default function HomeFeature() { - return ( - - } /> - } /> - } /> - - ) -} diff --git a/libs/web/home/feature/src/lib/home-routes.tsx b/libs/web/home/feature/src/lib/home-routes.tsx new file mode 100644 index 0000000..f057b93 --- /dev/null +++ b/libs/web/home/feature/src/lib/home-routes.tsx @@ -0,0 +1,10 @@ +import { lazy } from 'react' +import { RouteObject } from 'react-router-dom' + +const LazyHome = lazy(() => import('./pages/home-page')) +const LazyAbout = lazy(() => import('./pages/about-page')) + +export const HOME_ROUTES: RouteObject[] = [ + { path: '/home', element: }, + { path: '/about', element: }, +] diff --git a/libs/web/home/feature/src/lib/pages/about-page.tsx b/libs/web/home/feature/src/lib/pages/about-page.tsx index d2605ae..ab58cb2 100644 --- a/libs/web/home/feature/src/lib/pages/about-page.tsx +++ b/libs/web/home/feature/src/lib/pages/about-page.tsx @@ -3,7 +3,7 @@ import { UiStack } from '@pubkey-ui/core' import { IconHome } from '@tabler/icons-react' import { Link } from 'react-router-dom' -export function AboutPage() { +export default function AboutPage() { return ( diff --git a/libs/web/home/feature/src/lib/pages/home-page.tsx b/libs/web/home/feature/src/lib/pages/home-page.tsx index 1946f14..3d25f62 100644 --- a/libs/web/home/feature/src/lib/pages/home-page.tsx +++ b/libs/web/home/feature/src/lib/pages/home-page.tsx @@ -3,7 +3,7 @@ import { UiStack } from '@pubkey-ui/core' import { IconBrandGithub, IconRocket } from '@tabler/icons-react' import { Link } from 'react-router-dom' -export function HomePage() { +export default function HomePage() { return ( From c969fab0e187bd8b8c5c850ca9a64e5dd69241d8 Mon Sep 17 00:00:00 2001 From: Bram Borggreve Date: Sat, 16 Mar 2024 07:27:50 +0000 Subject: [PATCH 09/12] refactor: re-structure routes --- .../feature/src/lib/web-core-providers.tsx | 36 ++++++++++++++++ .../feature/src/lib/web-core-routes-admin.tsx | 12 ++---- .../feature/src/lib/web-core-routes-user.tsx | 21 ++++------ .../core/feature/src/lib/web-core-routes.tsx | 8 ++-- .../core/feature/src/lib/web-core.feature.tsx | 41 +++++-------------- libs/web/core/ui/src/index.ts | 1 + libs/web/core/ui/src/lib/ui-dashboard.tsx | 9 ++++ .../dev/feature/src/lib/dev-admin-routes.tsx | 16 ++++---- libs/web/home/feature/src/lib/home-routes.tsx | 8 ++-- .../home/feature/src/lib/pages/about-page.tsx | 4 +- .../home/feature/src/lib/pages/home-page.tsx | 4 +- .../src/lib/admin-user-create-feature.tsx | 2 +- .../src/lib/admin-user-detail-feature.tsx | 2 +- .../src/lib/admin-user-list-feature.tsx | 10 ++--- .../feature/src/lib/admin-user.routes.tsx | 17 ++++---- .../src/lib/user-user-detail-feature.tsx | 2 +- .../src/lib/user-user-list-feature.tsx | 2 +- .../user/feature/src/lib/user-user.routes.tsx | 26 ++++-------- libs/web/user/ui/src/index.ts | 6 ++- .../src/lib/user-ui-select-role.tsx} | 6 ++- .../src/lib/user-ui-select-status.tsx} | 6 ++- 21 files changed, 123 insertions(+), 116 deletions(-) create mode 100644 libs/web/core/feature/src/lib/web-core-providers.tsx create mode 100644 libs/web/core/ui/src/lib/ui-dashboard.tsx rename libs/web/user/{feature/src/lib/admin-user-ui-select-role.tsx => ui/src/lib/user-ui-select-role.tsx} (71%) rename libs/web/user/{feature/src/lib/admin-user-ui-select-status.tsx => ui/src/lib/user-ui-select-status.tsx} (71%) diff --git a/libs/web/core/feature/src/lib/web-core-providers.tsx b/libs/web/core/feature/src/lib/web-core-providers.tsx new file mode 100644 index 0000000..44b1036 --- /dev/null +++ b/libs/web/core/feature/src/lib/web-core-providers.tsx @@ -0,0 +1,36 @@ +import '@pubkey-ui/core' +import '@pubkey-ui/core/index.esm.css' +import 'mantine-datatable/styles.layer.css' +import { AuthProvider } from '@pubkey-stack/web-auth-data-access' +import { AppConfigProvider, SdkProvider } from '@pubkey-stack/web-core-data-access' +import { SolanaClusterProvider } from '@pubkey-stack/web-solana-data-access' +import { toastError, UiTheme, UiThemeProvider } from '@pubkey-ui/core' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { ReactNode } from 'react' +import { Link } from 'react-router-dom' + +const client = new QueryClient({ + defaultOptions: { + mutations: { + onError: () => { + toastError(`Something went wrong`) + }, + }, + }, +}) + +export function WebCoreProviders({ children, theme }: { children: ReactNode; theme: UiTheme['theme'] }) { + return ( + {children}} theme={theme}> + + + + + {children} + + + + + + ) +} diff --git a/libs/web/core/feature/src/lib/web-core-routes-admin.tsx b/libs/web/core/feature/src/lib/web-core-routes-admin.tsx index 20a891a..76f4ae7 100644 --- a/libs/web/core/feature/src/lib/web-core-routes-admin.tsx +++ b/libs/web/core/feature/src/lib/web-core-routes-admin.tsx @@ -1,6 +1,7 @@ +import { UiDashboard } from '@pubkey-stack/web-core-ui' import { DevAdminRoutes } from '@pubkey-stack/web-dev-feature' import { AdminUserFeature } from '@pubkey-stack/web-user-feature' -import { UiContainer, UiDashboardGrid, UiDashboardItem, UiNotFound } from '@pubkey-ui/core' +import { UiDashboardItem, UiNotFound } from '@pubkey-ui/core' import { IconUsers } from '@tabler/icons-react' import { Navigate, RouteObject, useRoutes } from 'react-router-dom' @@ -18,14 +19,7 @@ const routes: RouteObject[] = [ export default function WebCoreRoutesAdmin() { return useRoutes([ { index: true, element: }, - { - path: 'dashboard/*', - element: ( - - - - ), - }, + { path: '/dashboard', element: }, ...routes, { path: '*', element: }, ]) diff --git a/libs/web/core/feature/src/lib/web-core-routes-user.tsx b/libs/web/core/feature/src/lib/web-core-routes-user.tsx index d92e93b..493ce82 100644 --- a/libs/web/core/feature/src/lib/web-core-routes-user.tsx +++ b/libs/web/core/feature/src/lib/web-core-routes-user.tsx @@ -1,9 +1,10 @@ +import { UiDashboard } from '@pubkey-stack/web-core-ui' import { SettingsFeature } from '@pubkey-stack/web-settings-feature' import { SolanaFeature } from '@pubkey-stack/web-solana-feature' import { UserFeature } from '@pubkey-stack/web-user-feature' -import { UiContainer, UiDashboardGrid, UiDashboardItem } from '@pubkey-ui/core' +import { UiDashboardItem, UiNotFound } from '@pubkey-ui/core' import { IconCurrencySolana, IconSettings, IconUsers } from '@tabler/icons-react' -import { RouteObject, useRoutes } from 'react-router-dom' +import { Navigate, RouteObject, useRoutes } from 'react-router-dom' const links: UiDashboardItem[] = [ // User Dashboard Links are added by the web-crud generator @@ -14,20 +15,16 @@ const links: UiDashboardItem[] = [ const routes: RouteObject[] = [ // User Dashboard Routes are added by the web-crud generator - { path: '/dashboard', element: }, { path: '/settings/*', element: }, { path: '/solana/*', element: }, { path: '/u/*', element: }, ] export default function WebCoreRoutesUser() { - return useRoutes(routes) -} - -function Dashboard() { - return ( - - - - ) + return useRoutes([ + { index: true, element: }, + { path: '/dashboard', element: }, + ...routes, + { path: '*', element: }, + ]) } diff --git a/libs/web/core/feature/src/lib/web-core-routes.tsx b/libs/web/core/feature/src/lib/web-core-routes.tsx index 78af965..f806047 100644 --- a/libs/web/core/feature/src/lib/web-core-routes.tsx +++ b/libs/web/core/feature/src/lib/web-core-routes.tsx @@ -6,8 +6,8 @@ import { lazy } from 'react' import { Navigate } from 'react-router-dom' import { useGuardedRoutes } from './use-guarded-routes' -export const LazyAdminFeature = lazy(() => import('./web-core-routes-admin')) -export const LazyUserFeature = lazy(() => import('./web-core-routes-user')) +export const AdminFeature = lazy(() => import('./web-core-routes-admin')) +export const UserFeature = lazy(() => import('./web-core-routes-user')) export function WebCoreRoutes() { const { user } = useAuth() @@ -17,11 +17,11 @@ export function WebCoreRoutes() { // Here you can add routes that are only accessible by admins under the /admin/* path // Visit /admin/custom-admin-page to see this route // { path: 'custom-admin-page', element:
CUSTOM ADMIN PAGE HERE
}, - { path: '*', element: }, + { path: '*', element: }, ], layout: [ // Here you can add routes that are part of the main layout - { path: '*', element: }, + { path: '*', element: }, ], full: [ // Here you can add routes that are not part of the main layout, visit /custom-full-page to see this route diff --git a/libs/web/core/feature/src/lib/web-core.feature.tsx b/libs/web/core/feature/src/lib/web-core.feature.tsx index 50bd739..6a8c41d 100644 --- a/libs/web/core/feature/src/lib/web-core.feature.tsx +++ b/libs/web/core/feature/src/lib/web-core.feature.tsx @@ -1,42 +1,21 @@ -import { AuthProvider } from '@pubkey-stack/web-auth-data-access' -import { AppConfigProvider, SdkProvider } from '@pubkey-stack/web-core-data-access' -import { SolanaClusterProvider } from '@pubkey-stack/web-solana-data-access' -import { toastError, UiThemeLink, UiThemeProvider } from '@pubkey-ui/core' -import '@pubkey-ui/core/index.esm.css' -import 'mantine-datatable/styles.layer.css' -import { QueryClient, QueryClientProvider } from '@tanstack/react-query' -import { BrowserRouter, Link } from 'react-router-dom' +import { createTheme, DEFAULT_THEME } from '@mantine/core' +import { BrowserRouter } from 'react-router-dom' +import { WebCoreProviders } from './web-core-providers' import { WebCoreRoutes } from './web-core-routes' -const client = new QueryClient({ - defaultOptions: { - mutations: { - onError: () => { - toastError(`Something went wrong`) - }, - }, +const theme = createTheme({ + colors: { + brand: DEFAULT_THEME.colors.blue, }, + primaryColor: 'brand', }) -// eslint-disable-next-line func-style -export const ThemeLink: UiThemeLink = ({ children, ...props }) => {children} - export function WebCoreFeature() { return ( - - - - - - - - - - - - - + + + ) } diff --git a/libs/web/core/ui/src/index.ts b/libs/web/core/ui/src/index.ts index b1f3704..cf4897b 100644 --- a/libs/web/core/ui/src/index.ts +++ b/libs/web/core/ui/src/index.ts @@ -1,3 +1,4 @@ +export * from './lib/ui-dashboard' export * from './lib/ui-grid' export * from './lib/ui-header-profile' export * from './lib/ui-modal-button' diff --git a/libs/web/core/ui/src/lib/ui-dashboard.tsx b/libs/web/core/ui/src/lib/ui-dashboard.tsx new file mode 100644 index 0000000..cbc323f --- /dev/null +++ b/libs/web/core/ui/src/lib/ui-dashboard.tsx @@ -0,0 +1,9 @@ +import { UiContainer, UiDashboardGrid, UiDashboardItem } from '@pubkey-ui/core' + +export function UiDashboard({ links }: { links: UiDashboardItem[] }) { + return ( + + + + ) +} diff --git a/libs/web/dev/feature/src/lib/dev-admin-routes.tsx b/libs/web/dev/feature/src/lib/dev-admin-routes.tsx index d02c521..c4720ca 100644 --- a/libs/web/dev/feature/src/lib/dev-admin-routes.tsx +++ b/libs/web/dev/feature/src/lib/dev-admin-routes.tsx @@ -1,19 +1,17 @@ -import { UiContainer, UiTabRoutes } from '@pubkey-ui/core' +import { UiContainer, UiTabRoute, UiTabRoutes } from '@pubkey-ui/core' import { DevIdentityWizard } from './dev-identity-wizard' import { DevNew } from './dev-new' import { DevUserAutocomplete } from './dev-user-autocomplete' export default function DevAdminRoutes() { + const tabs: UiTabRoute[] = [ + { path: 'new', label: 'New', element: }, + { path: 'identity-wizard', label: 'Identity Wizard', element: }, + { path: 'user-autocomplete', label: 'User Autocomplete', element: }, + ] return ( - }, - { path: 'identity-wizard', label: 'Identity Wizard', element: }, - { path: 'user-autocomplete', label: 'User Autocomplete', element: }, - ]} - /> + ) } diff --git a/libs/web/home/feature/src/lib/home-routes.tsx b/libs/web/home/feature/src/lib/home-routes.tsx index f057b93..ac18880 100644 --- a/libs/web/home/feature/src/lib/home-routes.tsx +++ b/libs/web/home/feature/src/lib/home-routes.tsx @@ -1,10 +1,10 @@ import { lazy } from 'react' import { RouteObject } from 'react-router-dom' -const LazyHome = lazy(() => import('./pages/home-page')) -const LazyAbout = lazy(() => import('./pages/about-page')) +const Home = lazy(() => import('./pages/home-page')) +const About = lazy(() => import('./pages/about-page')) export const HOME_ROUTES: RouteObject[] = [ - { path: '/home', element: }, - { path: '/about', element: }, + { path: '/home', element: }, + { path: '/about', element: }, ] diff --git a/libs/web/home/feature/src/lib/pages/about-page.tsx b/libs/web/home/feature/src/lib/pages/about-page.tsx index ab58cb2..3e0c80f 100644 --- a/libs/web/home/feature/src/lib/pages/about-page.tsx +++ b/libs/web/home/feature/src/lib/pages/about-page.tsx @@ -5,8 +5,8 @@ import { Link } from 'react-router-dom' export default function AboutPage() { return ( - - + + About PubKey Stack. This is an empty about page. diff --git a/libs/web/home/feature/src/lib/pages/home-page.tsx b/libs/web/home/feature/src/lib/pages/home-page.tsx index 3d25f62..3a06fe1 100644 --- a/libs/web/home/feature/src/lib/pages/home-page.tsx +++ b/libs/web/home/feature/src/lib/pages/home-page.tsx @@ -6,9 +6,8 @@ import { Link } from 'react-router-dom' export default function HomePage() { return ( - + Welcome to PubKey Stack. - This is the PubKey Stack starter project. - ", + "", "", - "
", + "", + "", ");", "}", ], @@ -992,9 +1004,10 @@ exports[`web-crud generator should create crud with modelOwnerId 1`] = ` }, "manager-company-ui-update-form.tsx": { "content": [ - "import { Button, Group } from '@mantine/core';", + "import { Button, Group, TextInput } from '@mantine/core';", + "import { useForm } from '@mantine/form';", "import { CompanyManagerUpdateInput, Company } from '@proj/sdk';", - "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", + "import { UiStack } from '@pubkey-ui/core';", "export function ManagerCompanyUiUpdateForm({", "submit,", "company,", @@ -1002,26 +1015,32 @@ exports[`web-crud generator should create crud with modelOwnerId 1`] = ` "submit: (res: CompanyManagerUpdateInput) => Promise;", "company: Company;", "}) {", - "const model: CompanyManagerUpdateInput = {", + "const form = useForm({", + "initialValues: {", "name: company.name ?? '',", "location: company.location ?? '',", "phone: company.phone ?? '',", - "};", - "const fields: UiFormField[] = [", - "formFieldText('name', { label: 'name' }),", - "formFieldText('location', { label: 'location' }),", - "formFieldText('phone', { label: 'phone' }),", - "];", + "},", + "});", "return (", - " submit(res as CompanyManagerUpdateInput)}", - ">", + "
submit(values))}>", + "", + "", + "", + "", "", "", "", - "", + "", + "
", ");", "}", ], @@ -2071,7 +2090,11 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "import { toastError, UiBack, UiCard } from '@pubkey-ui/core';", "import { useNavigate } from 'react-router-dom';", "import { Group, Text } from '@mantine/core';", - "export function AdminCompanyCreateFeature({ ownerId }: { ownerId: string }) {", + "export default function AdminCompanyCreateFeature({", + "ownerId,", + "}: {", + "ownerId: string;", + "}) {", "const navigate = useNavigate();", "const { createCompany } = useAdminFindManyCompany({ ownerId });", "async function submit(input: CompanyAdminCreateInput) {", @@ -2177,7 +2200,7 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "import { useParams } from 'react-router-dom';", "import { AdminCompanyDetailInfoTab } from './admin-company-detail-info.tab';", "import { AdminCompanyDetailSettingsTab } from './admin-company-detail-settings.tab';", - "export function AdminCompanyDetailFeature() {", + "export default function AdminCompanyDetailFeature() {", "const { companyId } = useParams<{ companyId: string }>() as {", "companyId: string;", "};", @@ -2229,7 +2252,11 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "UiStack,", "} from '@pubkey-ui/core';", "import { Link } from 'react-router-dom';", - "export function AdminCompanyListFeature({ ownerId }: { ownerId: string }) {", + "export default function AdminCompanyListFeature({", + "ownerId,", + "}: {", + "ownerId: string;", + "}) {", "const { deleteCompany, items, pagination, query, setSearch } =", "useAdminFindManyCompany({", "limit: 10,", @@ -2275,18 +2302,16 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u }, "admin-company.routes.tsx": { "content": [ + "import { lazy } from 'react';", "import { useRoutes } from 'react-router-dom';", - "import { AdminCompanyDetailFeature } from './admin-company-detail.feature';", - "import { AdminCompanyCreateFeature } from './admin-company-create.feature';", - "import { AdminCompanyListFeature } from './admin-company-list.feature';", + "const Create = lazy(() => import('./admin-company-create.feature'));", + "const Detail = lazy(() => import('./admin-company-detail.feature'));", + "const List = lazy(() => import('./admin-company-list.feature'));", "export default function AdminCompanyRoutes({ ownerId }: { ownerId: string }) {", "return useRoutes([", - "{ path: '', element: },", - "{", - "path: 'create',", - "element: ,", - "},", - "{ path: ':companyId/*', element: },", + "{ path: '', element: },", + "{ path: 'create', element: },", + "{ path: ':companyId/*', element: },", "]);", "}", ], @@ -2300,7 +2325,7 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "import { UserCompanyUiCreateForm } from '@proj/test-company-ui';", "import { toastError, UiBack, UiCard, UiPage } from '@pubkey-ui/core';", "import { useNavigate } from 'react-router-dom';", - "export function UserCompanyCreateFeature() {", + "export default function UserCompanyCreateFeature() {", "const navigate = useNavigate();", "const { createCompany } = useUserFindManyCompany();", "async function submit(input: CompanyUserCreateInput) {", @@ -2395,7 +2420,7 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "import { useParams } from 'react-router-dom';", "import { UserCompanyDetailInfoTab } from './user-company-detail-info.tab';", "import { UserCompanyDetailSettingsTab } from './user-company-detail-settings.tab';", - "export function UserCompanyDetailFeature() {", + "export default function UserCompanyDetailFeature() {", "const { companyId } = useParams<{ companyId: string }>() as {", "companyId: string;", "};", @@ -2450,7 +2475,7 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "UiPage,", "} from '@pubkey-ui/core';", "import { Link } from 'react-router-dom';", - "export function UserCompanyListFeature() {", + "export default function UserCompanyListFeature() {", "const { items, pagination, query, setSearch } = useUserFindManyCompany({", "limit: 12,", "});", @@ -2494,18 +2519,16 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u }, "user-company.routes.tsx": { "content": [ + "import { lazy } from 'react';", "import { useRoutes } from 'react-router-dom';", - "import { UserCompanyDetailFeature } from './user-company-detail.feature';", - "import { UserCompanyCreateFeature } from './user-company-create.feature';", - "import { UserCompanyListFeature } from './user-company-list.feature';", + "const Create = lazy(() => import('./user-company-create.feature'));", + "const Detail = lazy(() => import('./user-company-detail.feature'));", + "const List = lazy(() => import('./user-company-list.feature'));", "export default function UserCompanyRoutes() {", "return useRoutes([", - "{ path: '', element: },", - "{", - "path: 'create',", - "element: ,", - "},", - "{ path: ':companyId/*', element: },", + "{ path: '', element: },", + "{ path: 'create', element: },", + "{ path: ':companyId/*', element: },", "]);", "}", ], @@ -2668,35 +2691,49 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "children": { "admin-company-ui-create-form.tsx": { "content": [ - "import { Button, Group } from '@mantine/core';", + "import { Button, Group, TextInput } from '@mantine/core';", + "import { useForm } from '@mantine/form';", "import { CompanyAdminCreateInput } from '@proj/sdk';", - "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", + "import { UiStack } from '@pubkey-ui/core';", "export function AdminCompanyUiCreateForm({", "submit,", "}: {", "submit: (res: CompanyAdminCreateInput) => Promise;", "}) {", - "const model: CompanyAdminCreateInput = {", + "const form = useForm({", + "initialValues: {", "name: '',", "location: '',", "phone: '',", "ownerId: '',", - "};", - "const fields: UiFormField[] = [", - "formFieldText('name', { label: 'name', required: true }),", - "formFieldText('location', { label: 'location', required: true }),", - "formFieldText('phone', { label: 'phone', required: true }),", - "];", + "},", + "});", "return (", - " submit(res as CompanyAdminCreateInput)}", - ">", + "
submit(values))}>", + "", + "", + "", + "", "", - "", + "", "", - "", + "", + "
", ");", "}", ], @@ -2782,9 +2819,10 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u }, "admin-company-ui-update-form.tsx": { "content": [ - "import { Button, Group } from '@mantine/core';", + "import { Button, Group, TextInput } from '@mantine/core';", + "import { useForm } from '@mantine/form';", "import { CompanyAdminUpdateInput, Company } from '@proj/sdk';", - "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", + "import { UiStack } from '@pubkey-ui/core';", "export function AdminCompanyUiUpdateForm({", "submit,", "company,", @@ -2792,26 +2830,32 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "submit: (res: CompanyAdminUpdateInput) => Promise;", "company: Company;", "}) {", - "const model: CompanyAdminUpdateInput = {", + "const form = useForm({", + "initialValues: {", "name: company.name ?? '',", "location: company.location ?? '',", "phone: company.phone ?? '',", - "};", - "const fields: UiFormField[] = [", - "formFieldText('name', { label: 'name' }),", - "formFieldText('location', { label: 'location' }),", - "formFieldText('phone', { label: 'phone' }),", - "];", + "},", + "});", "return (", - " submit(res as CompanyAdminUpdateInput)}", - ">", + "
submit(values))}>", + "", + "", + "", + "", "", "", "", - "", + "", + "
", ");", "}", ], @@ -2981,34 +3025,48 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u }, "user-company-ui-create-form.tsx": { "content": [ - "import { Button, Group } from '@mantine/core';", + "import { Button, Group, TextInput } from '@mantine/core';", + "import { useForm } from '@mantine/form';", "import { CompanyUserCreateInput } from '@proj/sdk';", - "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", + "import { UiStack } from '@pubkey-ui/core';", "export function UserCompanyUiCreateForm({", "submit,", "}: {", "submit: (res: CompanyUserCreateInput) => Promise;", "}) {", - "const model: CompanyUserCreateInput = {", + "const form = useForm({", + "initialValues: {", "name: '',", "location: '',", "phone: '',", - "};", - "const fields: UiFormField[] = [", - "formFieldText('name', { label: 'name', required: true }),", - "formFieldText('location', { label: 'location', required: true }),", - "formFieldText('phone', { label: 'phone', required: true }),", - "];", + "},", + "});", "return (", - " submit(res as CompanyUserCreateInput)}", - ">", + "
submit(values))}>", + "", + "", + "", + "", "", - "", + "", "", - "", + "", + "
", ");", "}", ], @@ -3094,9 +3152,10 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u }, "user-company-ui-update-form.tsx": { "content": [ - "import { Button, Group } from '@mantine/core';", + "import { Button, Group, TextInput } from '@mantine/core';", + "import { useForm } from '@mantine/form';", "import { CompanyUserUpdateInput, Company } from '@proj/sdk';", - "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", + "import { UiStack } from '@pubkey-ui/core';", "export function UserCompanyUiUpdateForm({", "submit,", "company,", @@ -3104,26 +3163,32 @@ exports[`web-crud generator should create crud with modelOwnerId for admin and u "submit: (res: CompanyUserUpdateInput) => Promise;", "company: Company;", "}) {", - "const model: CompanyUserUpdateInput = {", + "const form = useForm({", + "initialValues: {", "name: company.name ?? '',", "location: company.location ?? '',", "phone: company.phone ?? '',", - "};", - "const fields: UiFormField[] = [", - "formFieldText('name', { label: 'name' }),", - "formFieldText('location', { label: 'location' }),", - "formFieldText('phone', { label: 'phone' }),", - "];", + "},", + "});", "return (", - " submit(res as CompanyUserUpdateInput)}", - ">", + "
submit(values))}>", + "", + "", + "", + "", "", "", "", - "", + "", + "
", ");", "}", ], @@ -4073,7 +4138,7 @@ exports[`web-crud generator should create crud with modelParentId 1`] = ` "import { ManagerCompanyUiCreateForm } from '@proj/test-company-ui';", "import { toastError, UiBack, UiCard, UiPage } from '@pubkey-ui/core';", "import { useNavigate } from 'react-router-dom';", - "export function ManagerCompanyCreateFeature() {", + "export default function ManagerCompanyCreateFeature() {", "const navigate = useNavigate();", "const { createCompany } = useManagerFindManyCompany();", "async function submit(input: CompanyManagerCreateInput) {", @@ -4174,7 +4239,7 @@ exports[`web-crud generator should create crud with modelParentId 1`] = ` "import { useParams } from 'react-router-dom';", "import { ManagerCompanyDetailInfoTab } from './manager-company-detail-info.tab';", "import { ManagerCompanyDetailSettingsTab } from './manager-company-detail-settings.tab';", - "export function ManagerCompanyDetailFeature() {", + "export default function ManagerCompanyDetailFeature() {", "const { companyId } = useParams<{ companyId: string }>() as {", "companyId: string;", "};", @@ -4229,7 +4294,7 @@ exports[`web-crud generator should create crud with modelParentId 1`] = ` "UiPage,", "} from '@pubkey-ui/core';", "import { Link } from 'react-router-dom';", - "export function ManagerCompanyListFeature() {", + "export default function ManagerCompanyListFeature() {", "const { items, pagination, query, setSearch } = useManagerFindManyCompany({", "limit: 12,", "});", @@ -4273,18 +4338,16 @@ exports[`web-crud generator should create crud with modelParentId 1`] = ` }, "manager-company.routes.tsx": { "content": [ + "import { lazy } from 'react';", "import { useRoutes } from 'react-router-dom';", - "import { ManagerCompanyDetailFeature } from './manager-company-detail.feature';", - "import { ManagerCompanyCreateFeature } from './manager-company-create.feature';", - "import { ManagerCompanyListFeature } from './manager-company-list.feature';", + "const Create = lazy(() => import('./manager-company-create.feature'));", + "const Detail = lazy(() => import('./manager-company-detail.feature'));", + "const List = lazy(() => import('./manager-company-list.feature'));", "export default function ManagerCompanyRoutes() {", "return useRoutes([", - "{ path: '', element: },", - "{", - "path: 'create',", - "element: ,", - "},", - "{ path: ':companyId/*', element: },", + "{ path: '', element: },", + "{ path: 'create', element: },", + "{ path: ':companyId/*', element: },", "]);", "}", ], @@ -4605,34 +4668,48 @@ exports[`web-crud generator should create crud with modelParentId 1`] = ` }, "manager-company-ui-create-form.tsx": { "content": [ - "import { Button, Group } from '@mantine/core';", + "import { Button, Group, TextInput } from '@mantine/core';", + "import { useForm } from '@mantine/form';", "import { CompanyManagerCreateInput } from '@proj/sdk';", - "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", + "import { UiStack } from '@pubkey-ui/core';", "export function ManagerCompanyUiCreateForm({", "submit,", "}: {", "submit: (res: CompanyManagerCreateInput) => Promise;", "}) {", - "const model: CompanyManagerCreateInput = {", + "const form = useForm({", + "initialValues: {", "name: '',", "location: '',", "phone: '',", - "};", - "const fields: UiFormField[] = [", - "formFieldText('name', { label: 'name', required: true }),", - "formFieldText('location', { label: 'location', required: true }),", - "formFieldText('phone', { label: 'phone', required: true }),", - "];", + "},", + "});", "return (", - " submit(res as CompanyManagerCreateInput)}", - ">", + "
submit(values))}>", + "", + "", + "", + "", "", - "", + "", "", - "", + "", + "
", ");", "}", ], @@ -4718,9 +4795,10 @@ exports[`web-crud generator should create crud with modelParentId 1`] = ` }, "manager-company-ui-update-form.tsx": { "content": [ - "import { Button, Group } from '@mantine/core';", + "import { Button, Group, TextInput } from '@mantine/core';", + "import { useForm } from '@mantine/form';", "import { CompanyManagerUpdateInput, Company } from '@proj/sdk';", - "import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core';", + "import { UiStack } from '@pubkey-ui/core';", "export function ManagerCompanyUiUpdateForm({", "submit,", "company,", @@ -4728,26 +4806,32 @@ exports[`web-crud generator should create crud with modelParentId 1`] = ` "submit: (res: CompanyManagerUpdateInput) => Promise;", "company: Company;", "}) {", - "const model: CompanyManagerUpdateInput = {", + "const form = useForm({", + "initialValues: {", "name: company.name ?? '',", "location: company.location ?? '',", "phone: company.phone ?? '',", - "};", - "const fields: UiFormField[] = [", - "formFieldText('name', { label: 'name' }),", - "formFieldText('location', { label: 'location' }),", - "formFieldText('phone', { label: 'phone' }),", - "];", + "},", + "});", "return (", - " submit(res as CompanyManagerUpdateInput)}", - ">", + "
submit(values))}>", + "", + "", + "", + "", "", "", "", - "", + "", + "
", ");", "}", ], diff --git a/libs/tools/src/generators/web-feature/__snapshots__/web-feature-generator.spec.ts.snap b/libs/tools/src/generators/web-feature/__snapshots__/web-feature-generator.spec.ts.snap index 62c88cc..1c63e85 100644 --- a/libs/tools/src/generators/web-feature/__snapshots__/web-feature-generator.spec.ts.snap +++ b/libs/tools/src/generators/web-feature/__snapshots__/web-feature-generator.spec.ts.snap @@ -229,7 +229,7 @@ import { AdminTestUiCreateForm } from '@proj/web-test-ui'; import { toastError, UiBack, UiCard, UiPage } from '@pubkey-ui/core'; import { useNavigate } from 'react-router-dom'; -export function AdminTestCreateFeature() { +export default function AdminTestCreateFeature() { const navigate = useNavigate(); const { createTest } = useAdminFindManyTest(); @@ -323,7 +323,7 @@ import { useParams } from 'react-router-dom'; import { AdminTestDetailInfoTab } from './admin-test-detail-info.tab'; import { AdminTestDetailSettingsTab } from './admin-test-detail-settings.tab'; -export function AdminTestDetailFeature() { +export default function AdminTestDetailFeature() { const { testId } = useParams<{ testId: string }>() as { testId: string }; const { item, query } = useAdminFindOneTest({ testId }); @@ -378,7 +378,7 @@ import { } from '@pubkey-ui/core'; import { Link } from 'react-router-dom'; -export function AdminTestListFeature() { +export default function AdminTestListFeature() { const { items, pagination, query, setSearch } = useAdminFindManyTest({ limit: 10, }); @@ -429,19 +429,18 @@ export function AdminTestListFeature() { `; exports[`web-feature generator should run successfully with crud 15`] = ` -"import { useRoutes } from 'react-router-dom'; -import { AdminTestDetailFeature } from './admin-test-detail.feature'; -import { AdminTestCreateFeature } from './admin-test-create.feature'; -import { AdminTestListFeature } from './admin-test-list.feature'; +"import { lazy } from 'react'; +import { useRoutes } from 'react-router-dom'; + +const Create = lazy(() => import('./admin-test-create.feature')); +const Detail = lazy(() => import('./admin-test-detail.feature')); +const List = lazy(() => import('./admin-test-list.feature')); export default function AdminTestRoutes() { return useRoutes([ - { path: '', element: }, - { - path: 'create', - element: , - }, - { path: ':testId/*', element: }, + { path: '', element: }, + { path: 'create', element: }, + { path: ':testId/*', element: }, ]); } " @@ -454,7 +453,7 @@ import { UserTestUiCreateForm } from '@proj/web-test-ui'; import { toastError, UiBack, UiCard, UiPage } from '@pubkey-ui/core'; import { useNavigate } from 'react-router-dom'; -export function UserTestCreateFeature() { +export default function UserTestCreateFeature() { const navigate = useNavigate(); const { createTest } = useUserFindManyTest(); @@ -548,7 +547,7 @@ import { useParams } from 'react-router-dom'; import { UserTestDetailInfoTab } from './user-test-detail-info.tab'; import { UserTestDetailSettingsTab } from './user-test-detail-settings.tab'; -export function UserTestDetailFeature() { +export default function UserTestDetailFeature() { const { testId } = useParams<{ testId: string }>() as { testId: string }; const { item, query } = useUserFindOneTest({ testId }); @@ -603,7 +602,7 @@ import { } from '@pubkey-ui/core'; import { Link } from 'react-router-dom'; -export function UserTestListFeature() { +export default function UserTestListFeature() { const { items, pagination, query, setSearch } = useUserFindManyTest({ limit: 12, }); @@ -647,19 +646,18 @@ export function UserTestListFeature() { `; exports[`web-feature generator should run successfully with crud 21`] = ` -"import { useRoutes } from 'react-router-dom'; -import { UserTestDetailFeature } from './user-test-detail.feature'; -import { UserTestCreateFeature } from './user-test-create.feature'; -import { UserTestListFeature } from './user-test-list.feature'; +"import { lazy } from 'react'; +import { useRoutes } from 'react-router-dom'; + +const Create = lazy(() => import('./user-test-create.feature')); +const Detail = lazy(() => import('./user-test-detail.feature')); +const List = lazy(() => import('./user-test-list.feature')); export default function UserTestRoutes() { return useRoutes([ - { path: '', element: }, - { - path: 'create', - element: , - }, - { path: ':testId/*', element: }, + { path: '', element: }, + { path: 'create', element: }, + { path: ':testId/*', element: }, ]); } " @@ -681,32 +679,37 @@ export * from './lib/user-test-ui-update-form'; `; exports[`web-feature generator should run successfully with crud 23`] = ` -"import { Button, Group } from '@mantine/core'; +"import { Button, Group, TextInput } from '@mantine/core'; +import { useForm } from '@mantine/form'; import { TestAdminCreateInput } from '@proj/sdk'; -import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core'; +import { UiStack } from '@pubkey-ui/core'; export function AdminTestUiCreateForm({ submit, }: { submit: (res: TestAdminCreateInput) => Promise; }) { - const model: TestAdminCreateInput = { - name: '', - }; + const form = useForm({ + initialValues: { + name: '', + }, + }); - const fields: UiFormField[] = [ - formFieldText('name', { label: 'name', required: true }), - ]; return ( - submit(res as TestAdminCreateInput)} - > - - - - +
submit(values))}> + + + + + + + +
); } " @@ -789,9 +792,10 @@ export function AdminTestUiTable({ `; exports[`web-feature generator should run successfully with crud 25`] = ` -"import { Button, Group } from '@mantine/core'; +"import { Button, Group, TextInput } from '@mantine/core'; +import { useForm } from '@mantine/form'; import { TestAdminUpdateInput, Test } from '@proj/sdk'; -import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core'; +import { UiStack } from '@pubkey-ui/core'; export function AdminTestUiUpdateForm({ submit, @@ -800,23 +804,22 @@ export function AdminTestUiUpdateForm({ submit: (res: TestAdminUpdateInput) => Promise; test: Test; }) { - const model: TestAdminUpdateInput = { - name: test.name ?? '', - }; + const form = useForm({ + initialValues: { + name: test.name ?? '', + }, + }); - const fields: UiFormField[] = [ - formFieldText('name', { label: 'name' }), - ]; return ( - submit(res as TestAdminUpdateInput)} - > - - - - +
submit(values))}> + + + + + + + +
); } " @@ -973,32 +976,37 @@ export function TestUiItem({ `; exports[`web-feature generator should run successfully with crud 31`] = ` -"import { Button, Group } from '@mantine/core'; +"import { Button, Group, TextInput } from '@mantine/core'; +import { useForm } from '@mantine/form'; import { TestUserCreateInput } from '@proj/sdk'; -import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core'; +import { UiStack } from '@pubkey-ui/core'; export function UserTestUiCreateForm({ submit, }: { submit: (res: TestUserCreateInput) => Promise; }) { - const model: TestUserCreateInput = { - name: '', - }; + const form = useForm({ + initialValues: { + name: '', + }, + }); - const fields: UiFormField[] = [ - formFieldText('name', { label: 'name', required: true }), - ]; return ( - submit(res as TestUserCreateInput)} - > - - - - +
submit(values))}> + + + + + + + +
); } " @@ -1081,9 +1089,10 @@ export function UserTestUiTable({ `; exports[`web-feature generator should run successfully with crud 33`] = ` -"import { Button, Group } from '@mantine/core'; +"import { Button, Group, TextInput } from '@mantine/core'; +import { useForm } from '@mantine/form'; import { TestUserUpdateInput, Test } from '@proj/sdk'; -import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core'; +import { UiStack } from '@pubkey-ui/core'; export function UserTestUiUpdateForm({ submit, @@ -1092,23 +1101,22 @@ export function UserTestUiUpdateForm({ submit: (res: TestUserUpdateInput) => Promise; test: Test; }) { - const model: TestUserUpdateInput = { - name: test.name ?? '', - }; + const form = useForm({ + initialValues: { + name: test.name ?? '', + }, + }); - const fields: UiFormField[] = [ - formFieldText('name', { label: 'name' }), - ]; return ( - submit(res as TestUserUpdateInput)} - > - - - - +
submit(values))}> + + + + + + + +
); } " diff --git a/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-create.feature.tsx.template b/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-create.feature.tsx.template index e541fde..9996cd1 100644 --- a/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-create.feature.tsx.template +++ b/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-create.feature.tsx.template @@ -5,7 +5,7 @@ import { toastError, UiBack, UiCard<% if(ownerId && actor.className === 'Admin') import { useNavigate } from 'react-router-dom' <% if(ownerId && actor.className === 'Admin'){ %>import { Group, Text } from '@mantine/core'<% } %> -export function <%= actor.className %><%= model.className %>CreateFeature(<% if(ownerId && actor.className === 'Admin'){ %>{ <%= ownerId %> }: { <%= ownerId %>: string } <% } %>) { +export default function <%= actor.className %><%= model.className %>CreateFeature(<% if(ownerId && actor.className === 'Admin'){ %>{ <%= ownerId %> }: { <%= ownerId %>: string } <% } %>) { const navigate = useNavigate() const { create<%= model.className %> } = use<%= actor.className %>FindMany<%= model.className %>(<% if(ownerId && actor.className === 'Admin'){ %>{ <%= ownerId %> }<% } %>) diff --git a/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-detail.feature.tsx.template b/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-detail.feature.tsx.template index 2ab393a..5165f00 100644 --- a/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-detail.feature.tsx.template +++ b/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-detail.feature.tsx.template @@ -6,7 +6,7 @@ import { useParams } from 'react-router-dom' import { <%= actor.className %><%= model.className %>DetailInfoTab } from './<%= actor.propertyName %>-<%= model.fileName %>-detail-info.tab' import { <%= actor.className %><%= model.className %>DetailSettingsTab } from './<%= actor.propertyName %>-<%= model.fileName %>-detail-settings.tab' -export function <%= actor.className %><%= model.className %>DetailFeature() { +export default function <%= actor.className %><%= model.className %>DetailFeature() { const { <%= model.propertyName %>Id } = useParams<{ <%= model.propertyName %>Id: string }>() as { <%= model.propertyName %>Id: string } const { item, query } = use<%= actor.className %>FindOne<%= model.className %>({ <%= model.propertyName %>Id }) diff --git a/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-list.feature.tsx.template b/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-list.feature.tsx.template index 390edfc..c18ef5e 100644 --- a/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-list.feature.tsx.template +++ b/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__-list.feature.tsx.template @@ -5,7 +5,7 @@ import { <% if(actorAdmin){ %><%= actor.className %><%= model.className %>UiTabl import { UiBack, UiDebugModal, UiInfo, UiLoader, <% if(ownerId && actor.className === 'Admin'){ %>UiStack<% } else { %>UiPage<% } %> } from '@pubkey-ui/core' import { Link } from 'react-router-dom' -export function <%= actor.className %><%= model.className %>ListFeature(<% if(ownerId && actor.className === 'Admin'){ %>{ <%= ownerId %> }: { <%= ownerId %>: string } <% } %>) { +export default function <%= actor.className %><%= model.className %>ListFeature(<% if(ownerId && actor.className === 'Admin'){ %>{ <%= ownerId %> }: { <%= ownerId %>: string } <% } %>) { const { <% if(ownerId && actor.className === 'Admin'){ %>delete<%= model.className %>, <% } %> items, pagination, query, setSearch } = use<%= actor.className %>FindMany<%= model.className %>({ limit: <% if(actorAdmin){ %>10<% } else { %>12<% } %>, <% if(ownerId && actor.className === 'Admin'){ %><%= ownerId %>,<% } %> diff --git a/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__.routes.tsx.template b/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__.routes.tsx.template index 04115ee..0b8e0c0 100644 --- a/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__.routes.tsx.template +++ b/libs/tools/src/lib/web-crud/files/feature/lib/__actorFileName__-__modelFileName__.routes.tsx.template @@ -1,15 +1,14 @@ +import { lazy } from 'react' import { useRoutes } from 'react-router-dom' -import { <%= actor.className %><%= model.className %>DetailFeature } from './<%= actor.propertyName %>-<%= model.fileName %>-detail.feature' -import { <%= actor.className %><%= model.className %>CreateFeature } from './<%= actor.propertyName %>-<%= model.fileName %>-create.feature' -import { <%= actor.className %><%= model.className %>ListFeature } from './<%= actor.propertyName %>-<%= model.fileName %>-list.feature' + +const Create = lazy(() => import('./<%= actor.fileName %>-<%= model.fileName %>-create.feature')) +const Detail = lazy(() => import('./<%= actor.fileName %>-<%= model.fileName %>-detail.feature')) +const List = lazy(() => import('./<%= actor.fileName %>-<%= model.fileName %>-list.feature')) export default function <%= actor.className %><%= model.className %>Routes(<% if(ownerId && actor.className === 'Admin'){ %>{ <%= ownerId %> }: { <%= ownerId %>: string } <% } %>) { return useRoutes([ - { path: '', element: <<%= actor.className %><%= model.className %>ListFeature <% if(ownerId && actor.className === 'Admin'){ %><%= ownerId %>={<%= ownerId %>}<% } %> /> }, - { - path: 'create', - element: <<%= actor.className %><%= model.className %>CreateFeature <% if(ownerId && actor.className === 'Admin'){ %><%= ownerId %>={<%= ownerId %>}<% } %> />, - }, - { path: ':<%= model.propertyName %>Id/*', element: <<%= actor.className %><%= model.className %>DetailFeature /> }, + { path: '', element: <%= ownerId %>={<%= ownerId %>}<% } %> /> }, + { path: 'create', element: <%= ownerId %>={<%= ownerId %>}<% } %> /> }, + { path: ':<%= model.propertyName %>Id/*', element: }, ]) } diff --git a/libs/tools/src/lib/web-crud/files/ui/lib/__actorFileName__-__modelFileName__-ui-create-form.tsx.template b/libs/tools/src/lib/web-crud/files/ui/lib/__actorFileName__-__modelFileName__-ui-create-form.tsx.template index 9f911fc..0aacd1f 100644 --- a/libs/tools/src/lib/web-crud/files/ui/lib/__actorFileName__-__modelFileName__-ui-create-form.tsx.template +++ b/libs/tools/src/lib/web-crud/files/ui/lib/__actorFileName__-__modelFileName__-ui-create-form.tsx.template @@ -1,27 +1,30 @@ -import { Button, Group } from '@mantine/core' +import { Button, Group, TextInput } from '@mantine/core' +import { useForm } from '@mantine/form' import { <%= model.className %><%= actor.className %>CreateInput } from '@<%= npmScope %>/sdk' -import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core' +import { UiStack } from '@pubkey-ui/core' export function <%= actor.className %><%= model.className %>UiCreateForm({ submit }: { submit: (res: <%= model.className %><%= actor.className %>CreateInput) => Promise }) { - const model: <%= model.className %><%= actor.className %>CreateInput = { - <% for (let field of fields){ %> - <%= field.name %>: '', - <% } %> - <% if(ownerId && actor.className === 'Admin'){ %> - <%= ownerId %>: '', - <% } %> - } + const form = useForm<<%= model.className %><%= actor.className %>CreateInput>({ + initialValues: { + <% for (let field of fields){ %> + <%= field.name %>: '', + <% } %> + <% if(ownerId && actor.className === 'Admin'){ %> + <%= ownerId %>: '', + <% } %> + }, + }) - const fields: UiFormField<<%= model.className %><%= actor.className %>CreateInput>[] = [ - <% for (let field of fields){ %> - formFieldText('<%= field.name %>', { label: '<%= field.name %>', required: true, }), - <% } %> - ] return ( - submit(res as <%= model.className %><%= actor.className %>CreateInput)}> - - - - +
submit(values))}> + + <% for (let field of fields){ %> + ')} /> + <% } %> + + + + +
) } diff --git a/libs/tools/src/lib/web-crud/files/ui/lib/__actorFileName__-__modelFileName__-ui-update-form.tsx.template b/libs/tools/src/lib/web-crud/files/ui/lib/__actorFileName__-__modelFileName__-ui-update-form.tsx.template index 56b7a63..66198d8 100644 --- a/libs/tools/src/lib/web-crud/files/ui/lib/__actorFileName__-__modelFileName__-ui-update-form.tsx.template +++ b/libs/tools/src/lib/web-crud/files/ui/lib/__actorFileName__-__modelFileName__-ui-update-form.tsx.template @@ -1,6 +1,7 @@ -import { Button, Group } from '@mantine/core' +import { Button, Group, TextInput } from '@mantine/core' +import { useForm } from '@mantine/form' import { <%= model.className %><%= actor.className %>UpdateInput, <%= model.className %> } from '@<%= npmScope %>/sdk' -import { formFieldText, UiForm, UiFormField } from '@pubkey-ui/core' +import { UiStack } from '@pubkey-ui/core' export function <%= actor.className %><%= model.className %>UiUpdateForm({ submit, @@ -9,22 +10,24 @@ export function <%= actor.className %><%= model.className %>UiUpdateForm({ submit: (res: <%= model.className %><%= actor.className %>UpdateInput) => Promise <%= model.propertyName %>: <%= model.className %> }) { - const model: <%= model.className %><%= actor.className %>UpdateInput = { - <% for (let field of fields){ %> - <%= field.name %>: <%= model.propertyName %>.<%= field.name %> ?? '', - <% } %> - } + const form = useForm<<%= model.className %><%= actor.className %>UpdateInput>({ + initialValues: { + <% for (let field of fields){ %> + <%= field.name %>: <%= model.propertyName %>.<%= field.name %> ?? '', + <% } %> + }, + }) - const fields: UiFormField<<%= model.className %><%= actor.className %>UpdateInput>[] = [ - <% for (let field of fields){ %> - formFieldText('<%= field.name %>', { label: '<%= field.name %>', }), - <% } %> - ] return ( - submit(res as <%= model.className %><%= actor.className %>UpdateInput)}> - - - - +
submit(values))}> + + <% for (let field of fields){ %> + ')} /> + <% } %> + + + + +
) } diff --git a/libs/web/auth/ui/src/lib/auth-ui-form.tsx b/libs/web/auth/ui/src/lib/auth-ui-form.tsx index 1c115e7..1965b77 100644 --- a/libs/web/auth/ui/src/lib/auth-ui-form.tsx +++ b/libs/web/auth/ui/src/lib/auth-ui-form.tsx @@ -1,6 +1,8 @@ +import { TextInput } from '@mantine/core' +import { useForm } from '@mantine/form' import { type LoginInput, RegisterInput } from '@pubkey-stack/sdk' -import { formFieldPassword, formFieldText, UiForm, UiFormField } from '@pubkey-ui/core' -import { ReactNode, useState } from 'react' +import { UiStack } from '@pubkey-ui/core' +import { ReactNode } from 'react' export type AuthUiFormInput = LoginInput | RegisterInput @@ -11,23 +13,20 @@ export function AuthUiForm({ children?: ReactNode submit: (res: AuthUiFormInput) => Promise }) { - const [model] = useState({ - username: '', - password: '', + const form = useForm({ + initialValues: { + username: '', + password: '', + }, }) - const fields: UiFormField[] = [ - formFieldText('username', { - placeholder: 'Username', - required: true, - }), - formFieldPassword('password', { - placeholder: 'Password', - required: true, - }), - ] + return ( - submit(res as AuthUiFormInput)}> - {children} - +
submit(values))}> + + + + {children} + +
) } diff --git a/libs/web/identity/ui/src/lib/admin-identity-ui-create-form.tsx b/libs/web/identity/ui/src/lib/admin-identity-ui-create-form.tsx index c30aaf3..e3625e5 100644 --- a/libs/web/identity/ui/src/lib/admin-identity-ui-create-form.tsx +++ b/libs/web/identity/ui/src/lib/admin-identity-ui-create-form.tsx @@ -1,29 +1,31 @@ -import { Button, Group } from '@mantine/core' +import { Button, Group, Select, TextInput } from '@mantine/core' +import { useForm } from '@mantine/form' import { IdentityAdminCreateInput, IdentityProvider } from '@pubkey-stack/sdk' -import { formFieldSelect, formFieldText, getEnumOptions, UiForm, UiFormField } from '@pubkey-ui/core' +import { getEnumOptions, UiStack } from '@pubkey-ui/core' export function AuthUiIdentityCreateForm({ submit }: { submit: (res: IdentityAdminCreateInput) => Promise }) { - const model: IdentityAdminCreateInput = { - provider: IdentityProvider.Solana, - providerId: '', - ownerId: '', - } - - const fields: UiFormField[] = [ - formFieldText('providerId', { - label: 'Provider ID', - }), - formFieldSelect('provider', { - label: 'Provider', - options: getEnumOptions(IdentityProvider), - }), - ] + const form = useForm({ + initialValues: { + provider: IdentityProvider.Solana, + providerId: '', + ownerId: '', + }, + }) return ( - submit(res as IdentityAdminCreateInput)}> - - - - +
submit(values))}> + + + +