@exanderal/stackcraft 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -8
- package/dist/create/index.d.ts.map +1 -1
- package/dist/create/index.js +24 -1
- package/dist/create/index.js.map +1 -1
- package/dist/create/scaffold.d.ts.map +1 -1
- package/dist/create/scaffold.js +8 -2
- package/dist/create/scaffold.js.map +1 -1
- package/dist/create/scaffolders/__tests__/web-vite.test.js +1 -0
- package/dist/create/scaffolders/__tests__/web-vite.test.js.map +1 -1
- package/dist/create/scaffolders/api-nestjs-graphql.d.ts +3 -0
- package/dist/create/scaffolders/api-nestjs-graphql.d.ts.map +1 -0
- package/dist/create/scaffolders/api-nestjs-graphql.js +31 -0
- package/dist/create/scaffolders/api-nestjs-graphql.js.map +1 -0
- package/dist/create/scaffolders/api-nestjs-rest.d.ts.map +1 -1
- package/dist/create/scaffolders/api-nestjs-rest.js +19 -2
- package/dist/create/scaffolders/api-nestjs-rest.js.map +1 -1
- package/dist/create/types.d.ts +3 -1
- package/dist/create/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/templates/api-nestjs-graphql/.prettierrc +4 -0
- package/templates/api-nestjs-graphql/eslint.config.mjs +34 -0
- package/templates/api-nestjs-graphql/nest-cli.json +8 -0
- package/templates/api-nestjs-graphql/package.json +81 -0
- package/templates/api-nestjs-graphql/project.json +21 -0
- package/templates/api-nestjs-graphql/src/app.module.ts +21 -0
- package/templates/api-nestjs-graphql/src/common/entities/base.entity.ts +21 -0
- package/templates/api-nestjs-graphql/src/common/repositories/entity.repository.ts +21 -0
- package/templates/api-nestjs-graphql/src/common/repositories/readonly-entity.repository.ts +22 -0
- package/templates/api-nestjs-graphql/src/common/services/entity.service.ts +24 -0
- package/templates/api-nestjs-graphql/src/common/services/readonly-entity.service.ts +23 -0
- package/templates/api-nestjs-graphql/src/main.ts +8 -0
- package/templates/api-nestjs-graphql/src/modules/database/database.module.ts +18 -0
- package/templates/api-nestjs-graphql/src/modules/health/__tests__/health.controller.spec.ts +20 -0
- package/templates/api-nestjs-graphql/src/modules/health/__tests__/health.service.spec.ts +18 -0
- package/templates/api-nestjs-graphql/src/modules/health/health.controller.ts +12 -0
- package/templates/api-nestjs-graphql/src/modules/health/health.module.ts +9 -0
- package/templates/api-nestjs-graphql/src/modules/health/health.service.ts +8 -0
- package/templates/api-nestjs-graphql/test/app.e2e-spec.ts +29 -0
- package/templates/api-nestjs-graphql/test/jest-e2e.json +9 -0
- package/templates/api-nestjs-graphql/tsconfig.build.json +4 -0
- package/templates/api-nestjs-graphql/tsconfig.json +21 -0
- package/templates/api-nestjs-rest/package.json +5 -2
- package/templates/api-nestjs-rest/project.json +1 -1
- package/templates/api-nestjs-rest/src/app.module.ts +8 -5
- package/templates/api-nestjs-rest/src/common/entities/base.entity.ts +16 -0
- package/templates/api-nestjs-rest/src/common/repositories/entity.repository.ts +21 -0
- package/templates/api-nestjs-rest/src/common/repositories/readonly-entity.repository.ts +22 -0
- package/templates/api-nestjs-rest/src/common/services/entity.service.ts +24 -0
- package/templates/api-nestjs-rest/src/common/services/readonly-entity.service.ts +23 -0
- package/templates/api-nestjs-rest/src/modules/database/database.module.ts +18 -0
- package/templates/api-nestjs-rest/src/modules/health/__tests__/health.controller.spec.ts +20 -0
- package/templates/api-nestjs-rest/src/modules/health/__tests__/health.service.spec.ts +18 -0
- package/templates/api-nestjs-rest/src/modules/health/health.controller.ts +12 -0
- package/templates/api-nestjs-rest/src/modules/health/health.module.ts +9 -0
- package/templates/api-nestjs-rest/src/modules/health/health.service.ts +8 -0
- package/templates/api-nestjs-rest/test/app.e2e-spec.ts +9 -5
- package/templates/base/package.json +5 -1
- package/templates/base/pnpm-workspace.yaml +1 -0
- package/templates/base/tools/generators/controller/files/__fileName__.controller.ts__tmpl__ +36 -0
- package/templates/base/tools/generators/controller/index.js +22 -0
- package/templates/base/tools/generators/controller/schema.json +18 -0
- package/templates/base/tools/generators/generators.json +19 -0
- package/templates/base/tools/generators/module/files/__fileName__.model.ts__tmpl__ +8 -0
- package/templates/base/tools/generators/module/files/__fileName__.module.ts__tmpl__ +12 -0
- package/templates/base/tools/generators/module/files/__fileName__.repository.ts__tmpl__ +15 -0
- package/templates/base/tools/generators/module/files/__fileName__.service.ts__tmpl__ +11 -0
- package/templates/base/tools/generators/module/files/__tests__/__fileName__.integration.spec.ts__tmpl__ +31 -0
- package/templates/base/tools/generators/module/graphql-files/__fileName__.model.ts__tmpl__ +11 -0
- package/templates/base/tools/generators/module/index.js +26 -0
- package/templates/base/tools/generators/module/schema.json +23 -0
- package/templates/base/tools/generators/package.json +6 -0
- package/templates/base/tools/generators/resolver/files/__fileName__.resolver.ts__tmpl__ +28 -0
- package/templates/base/tools/generators/resolver/index.js +22 -0
- package/templates/base/tools/generators/resolver/schema.json +18 -0
- package/templates/web-nextjs/package.json +3 -0
- package/templates/web-nextjs/postcss.config.mjs +7 -0
- package/templates/web-nextjs/src/app/globals.css +1 -0
- package/templates/web-nextjs/src/components/TemplateComponent/TemplateComponent.behaviour.ts +39 -0
- package/templates/web-nextjs/src/components/TemplateComponent/TemplateComponent.tsx +14 -0
- package/templates/web-vite/package.json +2 -0
- package/templates/web-vite/src/components/TemplateComponent/TemplateComponent.behaviour.ts +39 -0
- package/templates/web-vite/src/components/TemplateComponent/TemplateComponent.tsx +14 -0
- package/templates/web-vite/src/index.css +1 -8
- package/templates/web-vite/vite.config.ts +3 -3
- package/templates/api-nestjs-rest/src/app.controller.spec.ts +0 -22
- package/templates/api-nestjs-rest/src/app.controller.ts +0 -12
- package/templates/api-nestjs-rest/src/app.service.ts +0 -8
- package/templates/web-nextjs/app/globals.css +0 -10
- /package/templates/web-nextjs/{app → src/app}/favicon.ico +0 -0
- /package/templates/web-nextjs/{app → src/app}/layout.tsx +0 -0
- /package/templates/web-nextjs/{app → src/app}/page.tsx +0 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Test } from '@nestjs/testing';
|
|
2
|
+
import { getRepositoryToken } from '@nestjs/typeorm';
|
|
3
|
+
import { Repository } from 'typeorm';
|
|
4
|
+
import { <%= className %>Model } from '../<%= fileName %>.model';
|
|
5
|
+
import { <%= className %>Module } from '../<%= fileName %>.module';
|
|
6
|
+
import { <%= className %>Service } from '../<%= fileName %>.service';
|
|
7
|
+
|
|
8
|
+
describe('<%= className %>Service', () => {
|
|
9
|
+
let service: <%= className %>Service;
|
|
10
|
+
|
|
11
|
+
beforeAll(async () => {
|
|
12
|
+
const module = await Test.createTestingModule({
|
|
13
|
+
imports: [<%= className %>Module],
|
|
14
|
+
})
|
|
15
|
+
.overrideProvider(getRepositoryToken(<%= className %>Model))
|
|
16
|
+
.useValue({
|
|
17
|
+
find: jest.fn(),
|
|
18
|
+
findOne: jest.fn(),
|
|
19
|
+
findOneBy: jest.fn(),
|
|
20
|
+
save: jest.fn(),
|
|
21
|
+
delete: jest.fn(),
|
|
22
|
+
} satisfies Partial<Repository<<%= className %>Model>>)
|
|
23
|
+
.compile();
|
|
24
|
+
|
|
25
|
+
service = module.get(<%= className %>Service);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('is defined', () => {
|
|
29
|
+
expect(service).toBeDefined();
|
|
30
|
+
});
|
|
31
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ObjectType } from '@nestjs/graphql';
|
|
2
|
+
import { Entity } from 'typeorm';
|
|
3
|
+
import { BaseEntity } from '../../common/entities/base.entity';
|
|
4
|
+
|
|
5
|
+
@ObjectType()
|
|
6
|
+
@Entity('<%= fileName %>s')
|
|
7
|
+
export class <%= className %>Model extends BaseEntity {
|
|
8
|
+
// @Field()
|
|
9
|
+
// @Column()
|
|
10
|
+
// name: string;
|
|
11
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const { formatFiles, generateFiles, names } = require('@nx/devkit');
|
|
2
|
+
const { execSync } = require('node:child_process');
|
|
3
|
+
const { join } = require('node:path');
|
|
4
|
+
|
|
5
|
+
module.exports = async function (tree, options) {
|
|
6
|
+
const n = names(options.name);
|
|
7
|
+
const modulePath = `apps/backend/src/modules/${n.fileName}`;
|
|
8
|
+
|
|
9
|
+
generateFiles(tree, join(__dirname, 'files'), modulePath, { ...n, tmpl: '' });
|
|
10
|
+
|
|
11
|
+
if (options.graphql) {
|
|
12
|
+
generateFiles(tree, join(__dirname, 'graphql-files'), modulePath, { ...n, tmpl: '' });
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
await formatFiles(tree);
|
|
16
|
+
|
|
17
|
+
console.log(`\n✓ Module created at ${modulePath}/`);
|
|
18
|
+
console.log(` → Import ${n.className}Module in app.module.ts\n`);
|
|
19
|
+
|
|
20
|
+
return () => {
|
|
21
|
+
execSync(`npx prettier --write ${modulePath}`, {
|
|
22
|
+
cwd: tree.root,
|
|
23
|
+
stdio: 'inherit',
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/schema",
|
|
3
|
+
"cli": "nx",
|
|
4
|
+
"id": "module",
|
|
5
|
+
"title": "Create a NestJS domain module",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"name": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"description": "Module name, singular lowercase (e.g. trainer)",
|
|
11
|
+
"$default": {
|
|
12
|
+
"$source": "argv",
|
|
13
|
+
"index": 0
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"graphql": {
|
|
17
|
+
"type": "boolean",
|
|
18
|
+
"description": "Add @ObjectType() to the model (required for GraphQL resolvers)",
|
|
19
|
+
"default": false
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"required": ["name"]
|
|
23
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Args,
|
|
3
|
+
Mutation,
|
|
4
|
+
Query,
|
|
5
|
+
Resolver,
|
|
6
|
+
} from '@nestjs/graphql';
|
|
7
|
+
import { <%= className %>Model } from '../../modules/<%= fileName %>/<%= fileName %>.model';
|
|
8
|
+
import { <%= className %>Service } from '../../modules/<%= fileName %>/<%= fileName %>.service';
|
|
9
|
+
|
|
10
|
+
@Resolver(() => <%= className %>Model)
|
|
11
|
+
export class <%= className %>Resolver {
|
|
12
|
+
constructor(private readonly service: <%= className %>Service) {}
|
|
13
|
+
|
|
14
|
+
@Query(() => [<%= className %>Model])
|
|
15
|
+
<%= propertyName %>s() {
|
|
16
|
+
return this.service.findAll();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@Query(() => <%= className %>Model, { nullable: true })
|
|
20
|
+
<%= propertyName %>(@Args('id') id: string) {
|
|
21
|
+
return this.service.findById(id);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@Mutation(() => Boolean)
|
|
25
|
+
remove<%= className %>(@Args('id') id: string) {
|
|
26
|
+
return this.service.remove(id).then(() => true);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const { formatFiles, generateFiles, names } = require('@nx/devkit');
|
|
2
|
+
const { execSync } = require('node:child_process');
|
|
3
|
+
const { join } = require('node:path');
|
|
4
|
+
|
|
5
|
+
module.exports = async function (tree, options) {
|
|
6
|
+
const n = names(options.name);
|
|
7
|
+
const resolverPath = `apps/backend/src/resolvers/${n.fileName}`;
|
|
8
|
+
|
|
9
|
+
generateFiles(tree, join(__dirname, 'files'), resolverPath, { ...n, tmpl: '' });
|
|
10
|
+
|
|
11
|
+
await formatFiles(tree);
|
|
12
|
+
|
|
13
|
+
console.log(`\n✓ Resolver created at ${resolverPath}/`);
|
|
14
|
+
console.log(` → Import ${n.className}Module and register ${n.className}Resolver in your module\n`);
|
|
15
|
+
|
|
16
|
+
return () => {
|
|
17
|
+
execSync(`npx prettier --write ${resolverPath}`, {
|
|
18
|
+
cwd: tree.root,
|
|
19
|
+
stdio: 'inherit',
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/schema",
|
|
3
|
+
"cli": "nx",
|
|
4
|
+
"id": "resolver",
|
|
5
|
+
"title": "Create a GraphQL resolver",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"name": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"description": "Module name to generate a resolver for (e.g. trainer)",
|
|
11
|
+
"$default": {
|
|
12
|
+
"$source": "argv",
|
|
13
|
+
"index": 0
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"required": ["name"]
|
|
18
|
+
}
|
|
@@ -14,10 +14,13 @@
|
|
|
14
14
|
"react-dom": "19.2.4"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
+
"@tailwindcss/postcss": "^4.0.0",
|
|
17
18
|
"@types/node": "^20",
|
|
18
19
|
"@types/react": "^19",
|
|
19
20
|
"@types/react-dom": "^19",
|
|
20
21
|
"babel-plugin-react-compiler": "1.0.0",
|
|
22
|
+
"postcss": "^8.0.0",
|
|
23
|
+
"tailwindcss": "^4.0.0",
|
|
21
24
|
"typescript": "^5"
|
|
22
25
|
}
|
|
23
26
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
|
|
3
|
+
type UseTemplateComponent = {
|
|
4
|
+
state: {
|
|
5
|
+
count: number;
|
|
6
|
+
};
|
|
7
|
+
handlers: {
|
|
8
|
+
handleCountIncrement: () => void;
|
|
9
|
+
handleCountDecrement: () => void;
|
|
10
|
+
handleCountReset: () => void;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const useTemplateComponent = (): UseTemplateComponent => {
|
|
15
|
+
const [count, setCount] = useState<number>(0);
|
|
16
|
+
|
|
17
|
+
const handleCountIncrement = () => {
|
|
18
|
+
setCount((prev) => prev + 1);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const handleCountDecrement = () => {
|
|
22
|
+
setCount((prev) => prev - 1);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const handleCountReset = () => {
|
|
26
|
+
setCount(0);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
state: {
|
|
31
|
+
count,
|
|
32
|
+
},
|
|
33
|
+
handlers: {
|
|
34
|
+
handleCountIncrement,
|
|
35
|
+
handleCountDecrement,
|
|
36
|
+
handleCountReset,
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { useTemplateComponent } from "./TemplateComponent.behaviour";
|
|
3
|
+
|
|
4
|
+
export const TemplateComponent = () => {
|
|
5
|
+
const { state, handlers } = useTemplateComponent();
|
|
6
|
+
return (
|
|
7
|
+
<div>
|
|
8
|
+
<div>Count: {state.count}</div>
|
|
9
|
+
<button onClick={handlers.handleCountIncrement}>Increment</button>
|
|
10
|
+
<button onClick={handlers.handleCountDecrement}>Decrement</button>
|
|
11
|
+
<button onClick={handlers.handleCountReset}>Reset</button>
|
|
12
|
+
</div>
|
|
13
|
+
);
|
|
14
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
|
|
3
|
+
type UseTemplateComponent = {
|
|
4
|
+
state: {
|
|
5
|
+
count: number;
|
|
6
|
+
};
|
|
7
|
+
handlers: {
|
|
8
|
+
handleCountIncrement: () => void;
|
|
9
|
+
handleCountDecrement: () => void;
|
|
10
|
+
handleCountReset: () => void;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const useTemplateComponent = (): UseTemplateComponent => {
|
|
15
|
+
const [count, setCount] = useState<number>(0);
|
|
16
|
+
|
|
17
|
+
const handleCountIncrement = () => {
|
|
18
|
+
setCount((prev) => prev + 1);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const handleCountDecrement = () => {
|
|
22
|
+
setCount((prev) => prev - 1);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const handleCountReset = () => {
|
|
26
|
+
setCount(0);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
state: {
|
|
31
|
+
count,
|
|
32
|
+
},
|
|
33
|
+
handlers: {
|
|
34
|
+
handleCountIncrement,
|
|
35
|
+
handleCountDecrement,
|
|
36
|
+
handleCountReset,
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { useTemplateComponent } from "./TemplateComponent.behaviour";
|
|
3
|
+
|
|
4
|
+
export const TemplateComponent = () => {
|
|
5
|
+
const { state, handlers } = useTemplateComponent();
|
|
6
|
+
return (
|
|
7
|
+
<div>
|
|
8
|
+
<div>Count: {state.count}</div>
|
|
9
|
+
<button onClick={handlers.handleCountIncrement}>Increment</button>
|
|
10
|
+
<button onClick={handlers.handleCountDecrement}>Decrement</button>
|
|
11
|
+
<button onClick={handlers.handleCountReset}>Reset</button>
|
|
12
|
+
</div>
|
|
13
|
+
);
|
|
14
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import tailwindcss from '@tailwindcss/vite'
|
|
2
2
|
import react from '@vitejs/plugin-react'
|
|
3
|
+
import { defineConfig } from 'vite'
|
|
3
4
|
|
|
4
|
-
// https://vite.dev/config/
|
|
5
5
|
export default defineConfig({
|
|
6
|
-
plugins: [react()],
|
|
6
|
+
plugins: [react(), tailwindcss()],
|
|
7
7
|
})
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { Test, TestingModule } from '@nestjs/testing';
|
|
2
|
-
import { AppController } from './app.controller';
|
|
3
|
-
import { AppService } from './app.service';
|
|
4
|
-
|
|
5
|
-
describe('AppController', () => {
|
|
6
|
-
let appController: AppController;
|
|
7
|
-
|
|
8
|
-
beforeEach(async () => {
|
|
9
|
-
const app: TestingModule = await Test.createTestingModule({
|
|
10
|
-
controllers: [AppController],
|
|
11
|
-
providers: [AppService],
|
|
12
|
-
}).compile();
|
|
13
|
-
|
|
14
|
-
appController = app.get<AppController>(AppController);
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
describe('root', () => {
|
|
18
|
-
it('should return "Hello World!"', () => {
|
|
19
|
-
expect(appController.getHello()).toBe('Hello World!');
|
|
20
|
-
});
|
|
21
|
-
});
|
|
22
|
-
});
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Controller, Get } from '@nestjs/common';
|
|
2
|
-
import { AppService } from './app.service';
|
|
3
|
-
|
|
4
|
-
@Controller()
|
|
5
|
-
export class AppController {
|
|
6
|
-
constructor(private readonly appService: AppService) {}
|
|
7
|
-
|
|
8
|
-
@Get()
|
|
9
|
-
getHello(): string {
|
|
10
|
-
return this.appService.getHello();
|
|
11
|
-
}
|
|
12
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|