diff --git a/apps/trpc-app/index.html b/apps/trpc-app/index.html index 14d7cfcd4..86e7a0476 100644 --- a/apps/trpc-app/index.html +++ b/apps/trpc-app/index.html @@ -1,5 +1,5 @@ - + SPARTAN - Notes App @@ -8,7 +8,7 @@ - + diff --git a/apps/trpc-app/src/app/app.component.ts b/apps/trpc-app/src/app/app.component.ts index 0781b1e94..9dd3769eb 100644 --- a/apps/trpc-app/src/app/app.component.ts +++ b/apps/trpc-app/src/app/app.component.ts @@ -5,9 +5,6 @@ import { RouterOutlet } from '@angular/router'; selector: 'trpc-app-root', standalone: true, imports: [RouterOutlet], - host: { - class: 'max-w-screen-md mx-auto block h-full bg-zinc-900 text-zinc-50', - }, changeDetection: ChangeDetectionStrategy.Default, template: ` `, }) diff --git a/apps/trpc-app/src/app/pages/index.page.ts b/apps/trpc-app/src/app/pages/index.page.ts index c271146d5..38791085c 100644 --- a/apps/trpc-app/src/app/pages/index.page.ts +++ b/apps/trpc-app/src/app/pages/index.page.ts @@ -2,68 +2,390 @@ import { Component } from '@angular/core'; import { injectTRPCClient } from '../../trpc-client'; import { AsyncPipe, DatePipe, JsonPipe, NgFor, NgIf } from '@angular/common'; import { FormsModule, NgForm } from '@angular/forms'; -import { waitFor } from '../../wait-for'; +import { waitFor } from '@analogjs/trpc'; import { Note } from '../../note'; -const inputTw = - 'focus-visible:ring-2 focus-visible:ring-red-500 focus-visible:outline-0 block w-full appearance-none rounded-lg px-3 py-2 transition-colors text-base leading-tight md:text-sm bg-black/[.05] dark:bg-zinc-50/10 focus:bg-white dark:focus:bg-dark placeholder:text-zinc-500 dark:placeholder:text-zinc-400 contrast-more:border contrast-more:border-current'; -const btnTw = - 'focus-visible:ring-2 focus-visible:ring-zinc-50 focus-visible:outline-0 flex items-center justify-center rounded-lg px-2 py-1.5 text-sm font-bold tracking-tight shadow-xl shadow-red-500/20 bg-[#DD0031] hover:bg-opacity-70 text-zinc-800 hover:text-primary-darker'; - @Component({ selector: 'trpc-app-home', standalone: true, imports: [AsyncPipe, FormsModule, NgFor, DatePipe, NgIf, JsonPipe], host: { - class: 'block h-full p-4', + class: + 'flex min-h-screen flex-col h-full text-zinc-900 bg-zinc-50 px-4 pt-8 pb-32', }, template: ` -
-

Analog + tRPC

- Spartan Logo -
-
- - - -
-
-
+
+
+ Follow along on Twitter +

+ Analog. The fullstack Angular meta-framework +

+

+ Analog is for building applications and websites with Angular. +
Powered by Vite. +

+ +
+
+
-
-

{{ note.createdAt | date }}

+
+

+ Features +

+

+ Analog comes with a set of tools that aim to let you build powerful + full stack applications while providing the best possible developer + experience. +

+
+
+
+
+ Installed +
+
+ + + +
+

Angular

+

+ Ready to built enterprise grade applications with Angular. +

+
+
+
+
+
+ Installed +
+
+ + + + + +
+

Vite

+

+ Based on Vite. Super fast. Super ecosystem. +

+
+
+
+
+
+ Installed +
+
+ + + +
+

Nitro

+

+ Backend server that runs everywhere +

+
+
+
+
+
+ Installed +
+
+ + + +
+

TailwindCSS

+

+ The utility first CSS framework. +

+
+
+
+
+
+ Installed +
+
+ + + + + + + + + + +
+

tRPC

+

+ End-to-end typesafe APIs made easy. +

+
+
+
+
+
+ Installed +
+
+ + + +
+

Nx

+

+ Next generation build system with first class monorepo + support. +

+
+
+
+
+
+

+ To see all available features and learn how to use them check out + the official + documentation. +

+
+
+
+
+

+ Proudly Open Source +

+

+ Analog is open source and powered by open source software. +
+ The code is available on + GitHub. +

+
+
+ +
+
+

Leave a note

+

+ This is an example of how to you can use tRPC to superpower you + client server interaction. +

+
+
+ + +
+
+
+ +
+
+

{{ note.note }}

+

+ {{ note.createdAt | date }} +

+
+
+
-

{{ note.note }}

-
-
-

No notes yet!

-

Add a new one and see them appear here...

-
-
+
+
+
+

+ {{ loadingPosts ? 'Loading...' : 'No notes yet...' }} +

+

+ {{ + loadingPosts + ? '' + : 'Add a new one and see them appear here...' + }} +

+
+
+
+ + `, }) export default class HomeComponent { diff --git a/packages/nx-plugin/src/generators/app/files/index-pages/css-trpc/src/app/pages/index.page.ts__template__ b/packages/nx-plugin/src/generators/app/files/index-pages/css-trpc/src/app/pages/index.page.ts__template__ new file mode 100644 index 000000000..45d01a38a --- /dev/null +++ b/packages/nx-plugin/src/generators/app/files/index-pages/css-trpc/src/app/pages/index.page.ts__template__ @@ -0,0 +1,585 @@ +import { Component } from '@angular/core'; +import { AsyncPipe, DatePipe, NgFor, NgIf } from '@angular/common'; +import { FormsModule, NgForm } from '@angular/forms'; +import { waitFor } from '@analogjs/trpc'; +import { injectTRPCClient } from '../../trpc-client'; +import { Note } from '../../note'; + +@Component({ + selector: '<%= fileName %>-home', + standalone: true, + imports: [AsyncPipe, FormsModule, NgFor, DatePipe, NgIf], + styles: [ + ` + + a { + color: inherit; + text-decoration: inherit; + } + + :host { + display: flex; + padding: 2rem; + flex-direction: column; + height: 100%; + min-height: 100vh; + font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + } + + .main { + margin-left: auto; + margin-right: auto; + flex: 1 1 0; + } + + .section-main { + padding-top: 1.5rem; + padding-bottom: 2rem; + margin-top: 1.5rem; + } + + @media (min-width: 768px) { + .section-main { + padding-top: 2.5rem; + padding-bottom: 3rem; + } + } + + @media (min-width: 1024px) { + .section-main { + padding-top: 8rem; + padding-bottom: 8rem; + } + } + + .main-icon { + margin-left: auto; + margin-right: auto; + margin-bottom: -1rem; + width: 4rem; + height: 4rem; + } + + .container-main { + display: flex; + text-align: center; + flex-direction: column; + align-items: center; + gap: 1rem; + } + + .button-badge { + padding-top: 0.375rem; + padding-bottom: 0.375rem; + padding-left: 1rem; + padding-right: 1rem; + font-size: 0.875rem; + line-height: 1.25rem; + font-weight: 500; + border-radius: 1rem; + background-color: rgb(228 228 231); + } + + .text-analog-red { + color: rgb(221,0,49); + } + + .heading-1 { + font-size: 1.875rem; + line-height: 2.25rem; + font-weight: 500; + margin: 1rem 0; + } + + @media (min-width: 640px) { + .heading-1 { + font-size: 2.25rem; /* 36px */ + line-height: 2.5rem; /* 40px */ + } + } + + @media (min-width: 768px) { + .heading-1 { + font-size: 3rem; /* 48px */ + line-height: 1; + } + } + + @media (min-width: 1024px) { + .heading-1 { + font-size: 3.75rem; /* 60px */ + line-height: 1; + } + } + + .paragraph-intro { + line-height: 1.5; + } + + @media (min-width: 640px) { + .paragraph-intro { + font-size: 1.25rem; + line-height: 2rem; + } + } + + .button-group { + display: flex; + gap: 1rem; + } + + .primary-button { + display: inline-flex; + align-items: center; + justify-content: center; + font-size: 0.875rem; + font-weight: 500; + transition-property: color, background-color; + transition-duration: 150ms; + outline-offset: 2px; + opacity: 1; + pointer-events: auto; + background-color: rgb(9, 9, 11); + color: rgb(250, 250, 250); + height: 2.75rem; + padding-left: 2rem; + padding-right: 2rem; + border-radius: 0.375rem; + } + + .secondary-button { + display: inline-flex; + align-items: center; + justify-content: center; + font-size: 0.875rem; + font-weight: 500; + transition-property: color, background-color, border-color; + transition-duration: 150ms; + outline-offset: 2px; + opacity: 1; + pointer-events: auto; + background-color: rgb(250, 250, 250); + color: rgb(9, 9, 11); + height: 2.75rem; + padding-left: 2rem; + padding-right: 2rem; + border: 1px solid rgb(161, 161, 170, 0.25); + border-radius: 0.375rem; + } + + .secondary-button:hover { + background-color: rgb(244 244 245); + color: rgb(9, 9, 11); + } + + .section { + margin-top: 8rem; + margin-bottom: 8rem; + padding-top: 2rem; + padding-bottom: 2rem; + display: flex; + flex-direction: column; + gap: 0.5rem; + } + + @media (min-width: 768px) { + .section { + padding-top: 3rem; + padding-bottom: 3rem; + } + } + + @media (min-width: 1024px) { + .section { + padding-top: 6rem; + } + } + + .intro-container { + margin-left: auto; + margin-right: auto; + max-width: 58rem; + display: flex; + flex-direction: column; + align-items: center; + gap: 1rem; + text-align: center; + } + + .title { + font-weight: 500; + font-size: 3rem; + line-height: 1.1; + text-align: center; + margin: 0; + } + + .description { + max-width: 85%; + font-size: 1.125rem; + line-height: 1.75rem; + } + + + + .feature-card { + position: relative; + overflow: hidden; + border: 1px solid rgb(228 228 231); + border-radius: 0.375rem; + padding: 0.5rem; + } + + .status-badge { + position: absolute; + top: 0.5rem; + right: 0.5rem; + border-radius: 0.5rem; + background-color: rgb(228, 228, 231); + padding: 0.375rem 0.75rem; + font-size: 0.75rem; + font-weight: 500; + } + + .card-content { + display: flex; + height: 180px; + flex-direction: column; + justify-content: space-between; + border-radius: 0.375rem; + padding: 1.5rem; + } + + + .card-details { + margin-top: 0.5rem; + } + + .card-title { + font-weight: bold; + } + + .card-description { + font-size: 0.875rem; + color: rgb(39, 39, 42); + } + + .further-info-container { + margin-left: auto; + margin-right: auto; + text-align: center; + max-width: 58rem; + } + + .description { + font-size: 1.125rem; + line-height: 1.75rem; + } + + + .note-form { + display: flex; + padding-bottom: 0.5rem; + margin-top: 2rem; + align-items: center; + } + .note-input { + display: flex; + height: 2.5rem; + width: 100%; + border-radius: 0.375rem; + border: 1px solid rgb(161, 161, 170, 0.25); + background-color: transparent; + padding: 0.5rem 0.75rem; + font-size: 0.875rem; + outline: none; + font-family: inherit; + color: inherit; + } + + .note-input::placeholder { + color: rgb(161, 161, 170, 0.8); + } + + .note-input:focus-visible { + outline-width: 2px; + outline-style: solid; + outline-color: rgb(39, 39, 42); + outline-offset: 2px; + } + .note-input:disabled { + cursor: not-allowed; + opacity: 0.5; + } + + .add-note-button { + margin-left: 0.5rem; + height: 2.5rem !important; + } + .hidden { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; + } + .note { + position: relative; + } + .note-grid { + display: flex; + margin-top: 1rem; + flex-direction: column; + gap: 1rem; + } + .delete-note-icon { + width: 1rem; + height: 1rem; + } + .delete-note-button { + position: absolute; + top: 1rem; + right: 1rem; + padding: 0.5rem !important; + height: 2rem !important; + } + `, + ], + template: ` +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + Follow along on Twitter +

+ Analog. The fullstack Angular meta-framework +

+

+ Analog is for building applications and websites with Angular. +
Powered by Vite. +

+ +
+
+
+
+

Leave a note

+

+ This is an example of how to you can use tRPC to superpower you + client server interaction. +

+
+
+ + + +
+
+
+ +
+
+

{{ note.note }}

+

+ {{ note.createdAt | date }} +

+
+
+
+
+ +
+
+
+

+ {{ loadingPosts ? 'Loading...' : 'No notes yet...' }} +

+

+ {{ + loadingPosts + ? '' + : 'Add a new one and see them appear here...' + }} +

+
+
+
+
+
+ `, +}) +export default class HomeComponent { + private _trpc = injectTRPCClient(); + public loadingPosts = false; + public notes: Note[] = []; + public newNote = ''; + + constructor() { + waitFor(this._trpc.note.list.query().then((notes) => (this.notes = notes))); + } + + public noteTrackBy = (index: number, note: Note) => { + return note.id; + }; + + public addPost(form: NgForm) { + if (!form.valid) { + form.form.markAllAsTouched(); + return; + } + this._trpc.note.create + .mutate({ title: this.newNote }) + .then(() => this.fetchPosts()); + this.newNote = ''; + form.form.reset(); + } + + public removePost(id: number) { + this._trpc.note.remove.mutate({ id }).then(() => this.fetchPosts()); + } + + private fetchPosts() { + this.loadingPosts = true; + this._trpc.note.list.query().then((notes) => { + this.loadingPosts = false; + this.notes = notes; + }); + } +} diff --git a/packages/nx-plugin/src/generators/app/files/index-pages/css/src/app/pages/index.page.ts__template__ b/packages/nx-plugin/src/generators/app/files/index-pages/css/src/app/pages/index.page.ts__template__ new file mode 100644 index 000000000..0844bc9c0 --- /dev/null +++ b/packages/nx-plugin/src/generators/app/files/index-pages/css/src/app/pages/index.page.ts__template__ @@ -0,0 +1,355 @@ +import { Component } from '@angular/core'; +import { AsyncPipe, DatePipe, NgFor, NgIf } from '@angular/common'; + +@Component({ + selector: '<%= fileName %>-home', + standalone: true, + imports: [AsyncPipe, NgFor, DatePipe, NgIf], + styles: [ + ` + a { + color: inherit; + text-decoration: inherit; + } + + :host { + display: flex; + padding: 2rem; + flex-direction: column; + height: 100%; + min-height: 100vh; + font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + } + + .main { + margin-left: auto; + margin-right: auto; + flex: 1 1 0; + } + + .section-main { + padding-top: 1.5rem; + padding-bottom: 2rem; + margin-top: 1.5rem; + } + + @media (min-width: 768px) { + .section-main { + padding-top: 2.5rem; + padding-bottom: 3rem; + } + } + + @media (min-width: 1024px) { + .section-main { + padding-top: 8rem; + padding-bottom: 8rem; + } + } + + .main-icon { + margin-left: auto; + margin-right: auto; + margin-bottom: -1rem; + width: 4rem; + height: 4rem; + } + + .container-main { + display: flex; + text-align: center; + flex-direction: column; + align-items: center; + gap: 1rem; + } + + .button-badge { + padding-top: 0.375rem; + padding-bottom: 0.375rem; + padding-left: 1rem; + padding-right: 1rem; + font-size: 0.875rem; + line-height: 1.25rem; + font-weight: 500; + border-radius: 1rem; + background-color: rgb(228 228 231); + } + + .text-analog-red { + color: rgb(221,0,49); + } + + .heading-1 { + font-size: 1.875rem; + line-height: 2.25rem; + font-weight: 500; + margin: 1rem 0; + } + + @media (min-width: 640px) { + .heading-1 { + font-size: 2.25rem; /* 36px */ + line-height: 2.5rem; /* 40px */ + } + } + + @media (min-width: 768px) { + .heading-1 { + font-size: 3rem; /* 48px */ + line-height: 1; + } + } + + @media (min-width: 1024px) { + .heading-1 { + font-size: 3.75rem; /* 60px */ + line-height: 1; + } + } + + .paragraph-intro { + line-height: 1.5; + } + + @media (min-width: 640px) { + .paragraph-intro { + font-size: 1.25rem; + line-height: 2rem; + } + } + + .button-group { + display: flex; + gap: 1rem; + } + + .primary-button { + display: inline-flex; + align-items: center; + justify-content: center; + font-size: 0.875rem; + font-weight: 500; + transition-property: color, background-color; + transition-duration: 150ms; + outline-offset: 2px; + opacity: 1; + pointer-events: auto; + background-color: rgb(9, 9, 11); + color: rgb(250, 250, 250); + height: 2.75rem; + padding-left: 2rem; + padding-right: 2rem; + border-radius: 0.375rem; + } + + .secondary-button { + display: inline-flex; + align-items: center; + justify-content: center; + font-size: 0.875rem; + font-weight: 500; + transition-property: color, background-color, border-color; + transition-duration: 150ms; + outline-offset: 2px; + opacity: 1; + pointer-events: auto; + background-color: rgb(250, 250, 250); + color: rgb(9, 9, 11); + height: 2.75rem; + padding-left: 2rem; + padding-right: 2rem; + border: 1px solid rgb(161, 161, 170, 0.25); + border-radius: 0.375rem; + } + + .secondary-button:hover { + background-color: rgb(244 244 245); + color: rgb(9, 9, 11); + } + + .section { + margin-top: 8rem; + margin-bottom: 8rem; + padding-top: 2rem; + padding-bottom: 2rem; + display: flex; + flex-direction: column; + gap: 0.5rem; + } + + @media (min-width: 768px) { + .section { + padding-top: 3rem; + padding-bottom: 3rem; + } + } + + @media (min-width: 1024px) { + .section { + padding-top: 6rem; + } + } + + .intro-container { + margin-left: auto; + margin-right: auto; + max-width: 58rem; + display: flex; + flex-direction: column; + align-items: center; + gap: 1rem; + text-align: center; + } + + .title { + font-weight: 500; + font-size: 3rem; + line-height: 1.1; + text-align: center; + margin: 0; + } + + .description { + max-width: 85%; + font-size: 1.125rem; + line-height: 1.75rem; + } + + .count { + margin-left: 0.25rem; + font-family: Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', + monospace; + } + `, + ], + template: ` +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + Follow along on Twitter +

+ Analog. The fullstack Angular meta-framework +

+

+ Analog is for building applications and websites with Angular. +
Powered by Vite. +

+ +
+
+
+
+

Counter

+

+ This is a simple interactive counter. Powered by Angular. +

+ +
+
+
+ `, +}) +export default class HomeComponent { + public count = 0; + public increment() { + this.count++; + } +} diff --git a/packages/nx-plugin/src/generators/app/files/index-pages/tailwind-trpc/src/app/pages/index.page.ts__template__ b/packages/nx-plugin/src/generators/app/files/index-pages/tailwind-trpc/src/app/pages/index.page.ts__template__ new file mode 100644 index 000000000..e4cafac27 --- /dev/null +++ b/packages/nx-plugin/src/generators/app/files/index-pages/tailwind-trpc/src/app/pages/index.page.ts__template__ @@ -0,0 +1,269 @@ +import { Component } from '@angular/core'; +import { AsyncPipe, DatePipe, NgFor, NgIf } from '@angular/common'; +import { FormsModule, NgForm } from '@angular/forms'; +import { waitFor } from '@analogjs/trpc'; +import { injectTRPCClient } from '../../trpc-client'; +import { Note } from '../../note'; + +@Component({ + selector: '<%= fileName %>-home', + standalone: true, + imports: [AsyncPipe, FormsModule, NgFor, DatePipe, NgIf], + host: { + class: + 'flex min-h-screen flex-col text-zinc-900 bg-zinc-50 px-4 pt-8 pb-32', + }, + template: ` +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + Follow along on Twitter +

+ Analog. The fullstack Angular meta-framework +

+

+ Analog is for building applications and websites with Angular. +
Powered by Vite. +

+ +
+
+
+
+

Leave a note

+

+ This is an example of how to you can use tRPC to superpower you + client server interaction. +

+
+
+ + + +
+
+
+ +
+
+

{{ note.note }}

+

+ {{ note.createdAt | date }} +

+
+
+
+
+ +
+
+
+

+ {{ loadingPosts ? 'Loading...' : 'No notes yet...' }} +

+

+ {{ + loadingPosts + ? '' + : 'Add a new one and see them appear here...' + }} +

+
+
+
+
+
+ `, +}) +export default class HomeComponent { + private _trpc = injectTRPCClient(); + public loadingPosts = false; + public notes: Note[] = []; + public newNote = ''; + + constructor() { + waitFor(this._trpc.note.list.query().then((notes) => (this.notes = notes))); + } + + public noteTrackBy = (index: number, note: Note) => { + return note.id; + }; + + public addPost(form: NgForm) { + if (!form.valid) { + form.form.markAllAsTouched(); + return; + } + this._trpc.note.create + .mutate({ title: this.newNote }) + .then(() => this.fetchPosts()); + this.newNote = ''; + form.form.reset(); + } + + public removePost(id: number) { + this._trpc.note.remove.mutate({ id }).then(() => this.fetchPosts()); + } + + private fetchPosts() { + this.loadingPosts = true; + this._trpc.note.list.query().then((notes) => { + this.loadingPosts = false; + this.notes = notes; + }); + } +} diff --git a/packages/nx-plugin/src/generators/app/files/index-pages/tailwind/src/app/pages/index.page.ts__template__ b/packages/nx-plugin/src/generators/app/files/index-pages/tailwind/src/app/pages/index.page.ts__template__ new file mode 100644 index 000000000..4a952e685 --- /dev/null +++ b/packages/nx-plugin/src/generators/app/files/index-pages/tailwind/src/app/pages/index.page.ts__template__ @@ -0,0 +1,158 @@ +import { Component } from '@angular/core'; +import { AsyncPipe, DatePipe, NgFor, NgIf } from '@angular/common'; + +@Component({ + selector: '<%= fileName %>-home', + standalone: true, + imports: [AsyncPipe, <% if (addTRPC) { %>FormsModule,<% } %> NgFor, DatePipe, NgIf], + host: { + class: + 'flex min-h-screen flex-col text-zinc-900 bg-zinc-50 px-4 pt-8 pb-32', + }, + template: ` +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + Follow along on Twitter +

+ Analog. The fullstack Angular meta-framework +

+

+ Analog is for building applications and websites with Angular. +
Powered by Vite. +

+ +
+
+
+
+

Counter

+

+ This is a simple interactive counter. Powered by Angular. +

+ +
+
+
+ `, +}) +export default class HomeComponent { + public count = 0; + public increment() { + this.count++; + } +} diff --git a/packages/nx-plugin/src/generators/app/files/tRPC/src/note.ts__template__ b/packages/nx-plugin/src/generators/app/files/tRPC/src/note.ts__template__ new file mode 100644 index 000000000..f982d17fb --- /dev/null +++ b/packages/nx-plugin/src/generators/app/files/tRPC/src/note.ts__template__ @@ -0,0 +1,5 @@ +export type Note = { + id: number; + note: string; + createdAt: string; +}; diff --git a/packages/nx-plugin/src/generators/app/files/tRPC/src/server/routes/trpc/[trpc].ts__template__ b/packages/nx-plugin/src/generators/app/files/tRPC/src/server/routes/trpc/[trpc].ts__template__ new file mode 100644 index 000000000..1dbb2168c --- /dev/null +++ b/packages/nx-plugin/src/generators/app/files/tRPC/src/server/routes/trpc/[trpc].ts__template__ @@ -0,0 +1,8 @@ +import { appRouter } from '../../trpc/routers'; +import { createContext } from '../../trpc/context'; +import { createTrpcNitroHandler } from '@analogjs/trpc'; +// export API handler +export default createTrpcNitroHandler({ + router: appRouter, + createContext, +}); diff --git a/packages/nx-plugin/src/generators/app/files/tRPC/src/server/trpc/context.ts__template__ b/packages/nx-plugin/src/generators/app/files/tRPC/src/server/trpc/context.ts__template__ new file mode 100644 index 000000000..3542761db --- /dev/null +++ b/packages/nx-plugin/src/generators/app/files/tRPC/src/server/trpc/context.ts__template__ @@ -0,0 +1,7 @@ +import { inferAsyncReturnType } from '@trpc/server'; +/** + * Creates context for an incoming request + * @link https://trpc.io/docs/context + */ +export const createContext = () => ({}); +export type Context = inferAsyncReturnType; diff --git a/packages/nx-plugin/src/generators/app/files/tRPC/src/server/trpc/routers/index.ts__template__ b/packages/nx-plugin/src/generators/app/files/tRPC/src/server/trpc/routers/index.ts__template__ new file mode 100644 index 000000000..49c415a63 --- /dev/null +++ b/packages/nx-plugin/src/generators/app/files/tRPC/src/server/trpc/routers/index.ts__template__ @@ -0,0 +1,8 @@ +import { router } from '../trpc'; +import { noteRouter } from './notes'; + +export const appRouter = router({ + note: noteRouter, +}); +// export type definition of API +export type AppRouter = typeof appRouter; diff --git a/packages/nx-plugin/src/generators/app/files/tRPC/src/server/trpc/routers/notes.ts__template__ b/packages/nx-plugin/src/generators/app/files/tRPC/src/server/trpc/routers/notes.ts__template__ new file mode 100644 index 000000000..be3d3481d --- /dev/null +++ b/packages/nx-plugin/src/generators/app/files/tRPC/src/server/trpc/routers/notes.ts__template__ @@ -0,0 +1,32 @@ +import { z } from 'zod'; +import { publicProcedure, router } from '../trpc'; +import { Note } from '../../../note'; + +let noteId = 0; +const notes: Note[] = []; +export const noteRouter = router({ + create: publicProcedure + .input( + z.object({ + title: z.string(), + }) + ) + .mutation(({ input }) => + notes.push({ + id: noteId++, + note: input.title, + createdAt: new Date().toISOString(), + }) + ), + list: publicProcedure.query(() => notes), + remove: publicProcedure + .input( + z.object({ + id: z.number(), + }) + ) + .mutation(({ input }) => { + const index = notes.findIndex((note) => input.id === note.id); + notes.splice(index, 1); + }), +}); diff --git a/packages/nx-plugin/src/generators/app/files/tRPC/src/server/trpc/trpc.ts__template__ b/packages/nx-plugin/src/generators/app/files/tRPC/src/server/trpc/trpc.ts__template__ new file mode 100644 index 000000000..2ec64756b --- /dev/null +++ b/packages/nx-plugin/src/generators/app/files/tRPC/src/server/trpc/trpc.ts__template__ @@ -0,0 +1,10 @@ +import { initTRPC } from '@trpc/server'; +import { Context } from './context'; + +const t = initTRPC.context().create({}); +/** + * Unprotected procedure + **/ +export const publicProcedure = t.procedure; +export const router = t.router; +export const middleware = t.middleware; diff --git a/packages/nx-plugin/src/generators/app/files/tRPC/src/trpc-client.ts__template__ b/packages/nx-plugin/src/generators/app/files/tRPC/src/trpc-client.ts__template__ new file mode 100644 index 000000000..772bdb334 --- /dev/null +++ b/packages/nx-plugin/src/generators/app/files/tRPC/src/trpc-client.ts__template__ @@ -0,0 +1,11 @@ +import { AppRouter } from './server/trpc/routers'; +import { createTrpcClient } from '@analogjs/trpc'; +import { inject } from '@angular/core'; + +export const { provideTRPCClient, tRPCClient } = createTrpcClient({ + url: 'http://127.0.0.1:4200/api/trpc', +}); + +export function injectTRPCClient() { + return inject(tRPCClient); +} diff --git a/packages/nx-plugin/src/generators/app/files/template-angular-v15/src/app/app.component.ts__template__ b/packages/nx-plugin/src/generators/app/files/template-angular-v15/src/app/app.component.ts__template__ index de8a935a6..086a368dc 100644 --- a/packages/nx-plugin/src/generators/app/files/template-angular-v15/src/app/app.component.ts__template__ +++ b/packages/nx-plugin/src/generators/app/files/template-angular-v15/src/app/app.component.ts__template__ @@ -6,15 +6,5 @@ import { RouterOutlet } from '@angular/router'; standalone: true, imports: [RouterOutlet], template: ` `, - styles: [ - ` - :host { - max-width: 1280px; - margin: 0 auto; - padding: 2rem; - text-align: center; - } - `, - ], }) export class AppComponent {} diff --git a/packages/nx-plugin/src/generators/app/files/template-angular-v15/src/app/pages/index.page.ts__template__ b/packages/nx-plugin/src/generators/app/files/template-angular-v15/src/app/pages/index.page.ts__template__ deleted file mode 100644 index 5552a2c7b..000000000 --- a/packages/nx-plugin/src/generators/app/files/template-angular-v15/src/app/pages/index.page.ts__template__ +++ /dev/null @@ -1,62 +0,0 @@ -import { Component } from '@angular/core'; - -@Component({ - selector: '<%= fileName %>-home', - standalone: true, - template: ` -
- - - - - - -
- -

Vite + Angular

- -
- -
- -

- Check out - Analog, the fullstack meta-framework for Angular powered by Vite! -

- -

- Click on the Vite and Angular logos to learn more. -

- `, - styles: [ - ` - .logo { - height: 6em; - padding: 1.5em; - will-change: filter; - } - .logo:hover { - filter: drop-shadow(0 0 2em #646cffaa); - } - .logo.angular:hover { - filter: drop-shadow(0 0 2em #42b883aa); - } - .read-the-docs { - color: #888; - } - `, - ], -}) -export default class HomeComponent { - count = 0; - - increment() { - this.count++; - } -} diff --git a/packages/nx-plugin/src/generators/app/files/template-angular-v15/src/main.ts__template__ b/packages/nx-plugin/src/generators/app/files/template-angular-v15/src/main.ts__template__ index 0a459af40..c83df9926 100644 --- a/packages/nx-plugin/src/generators/app/files/template-angular-v15/src/main.ts__template__ +++ b/packages/nx-plugin/src/generators/app/files/template-angular-v15/src/main.ts__template__ @@ -1,10 +1,17 @@ import 'zone.js'; import { bootstrapApplication } from '@angular/platform-browser'; import { provideFileRouter } from '@analogjs/router'; - import { AppComponent } from './app/app.component'; import { mainProviders } from './main.providers'; +<% if (addTRPC) { %> +import { provideTRPCClient } from './trpc-client'; +<% } %> bootstrapApplication(AppComponent, { - providers: [provideFileRouter(), ...mainProviders], + providers: [ + provideFileRouter(), +<% if (addTRPC) { %> + provideTRPCClient(), +<% } %> + ...mainProviders], }); diff --git a/packages/nx-plugin/src/generators/app/files/template-angular-v15/src/styles.css__template__ b/packages/nx-plugin/src/generators/app/files/template-angular-v15/src/styles.css__template__ index 8e92f8fcd..336c6fd63 100644 --- a/packages/nx-plugin/src/generators/app/files/template-angular-v15/src/styles.css__template__ +++ b/packages/nx-plugin/src/generators/app/files/template-angular-v15/src/styles.css__template__ @@ -1,75 +1,4 @@ -/* You can add global styles to this file, and also import other style files */ -:root { - font-family: Inter, Avenir, Helvetica, Arial, sans-serif; - font-size: 16px; - line-height: 24px; - font-weight: 400; - - color-scheme: light dark; - color: rgba(255, 255, 255, 0.87); - background-color: #242424; - - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - -webkit-text-size-adjust: 100%; -} - -a { - font-weight: 500; - color: #646cff; - text-decoration: inherit; -} -a:hover { - color: #535bf2; -} - -body { - margin: 0; - display: flex; - place-items: center; - min-width: 320px; - min-height: 100vh; -} - -h1 { - font-size: 3.2em; - line-height: 1.1; -} - -button { - border-radius: 8px; - border: 1px solid transparent; - padding: 0.6em 1.2em; - font-size: 1em; - font-weight: 500; - font-family: inherit; - background-color: #1a1a1a; - cursor: pointer; - transition: border-color 0.25s; -} -button:hover { - border-color: #646cff; -} -button:focus, -button:focus-visible { - outline: 4px auto -webkit-focus-ring-color; -} - -.card { - padding: 2em; -} - -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; - } - a:hover { - color: #747bff; - } - button { - background-color: #f9f9f9; - } +html, body { + display: block; + height: 100%; } diff --git a/packages/nx-plugin/src/generators/app/files/template-angular-v15/vite.config.ts__template__ b/packages/nx-plugin/src/generators/app/files/template-angular-v15/vite.config.ts__template__ index ca40eb47a..a3d676f13 100644 --- a/packages/nx-plugin/src/generators/app/files/template-angular-v15/vite.config.ts__template__ +++ b/packages/nx-plugin/src/generators/app/files/template-angular-v15/vite.config.ts__template__ @@ -9,6 +9,14 @@ import tsConfigPaths from 'vite-tsconfig-paths'; export default defineConfig(({ mode }) => { return { publicDir: 'src/public', + <% if (addTRPC) { %> + server: { + host: '127.0.0.1' + }, + ssr: { + noExternal: '@analogjs/trpc/**', + }, + <% } %> optimizeDeps: { include: ['@angular/common', '@angular/forms'], }, diff --git a/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/app.config.server.ts__template__ b/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/app.config.server.ts__template__ new file mode 100644 index 000000000..1ee614143 --- /dev/null +++ b/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/app.config.server.ts__template__ @@ -0,0 +1,9 @@ +import { ApplicationConfig, mergeApplicationConfig } from '@angular/core'; +import { provideServerRendering } from '@angular/platform-server'; +import { appConfig } from './app.config'; + +const serverConfig: ApplicationConfig = { + providers: [provideServerRendering()], +}; + +export const config = mergeApplicationConfig(appConfig, serverConfig); diff --git a/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/app.config.ts__template__ b/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/app.config.ts__template__ new file mode 100644 index 000000000..2e8b3e004 --- /dev/null +++ b/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/app.config.ts__template__ @@ -0,0 +1,16 @@ +import { ApplicationConfig } from '@angular/core'; +import { provideClientHydration } from '@angular/platform-browser'; +import { provideFileRouter } from '@analogjs/router'; +<% if (addTRPC) { %> +import { provideTRPCClient } from './trpc-client'; +<% } %> + +export const appConfig: ApplicationConfig = { + providers: [ + provideFileRouter(), + provideClientHydration(), +<% if (addTRPC) { %> + provideTRPCClient(), +<% } %> + ], +}; diff --git a/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/app/app.component.ts__template__ b/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/app/app.component.ts__template__ index de8a935a6..086a368dc 100644 --- a/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/app/app.component.ts__template__ +++ b/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/app/app.component.ts__template__ @@ -6,15 +6,5 @@ import { RouterOutlet } from '@angular/router'; standalone: true, imports: [RouterOutlet], template: ` `, - styles: [ - ` - :host { - max-width: 1280px; - margin: 0 auto; - padding: 2rem; - text-align: center; - } - `, - ], }) export class AppComponent {} diff --git a/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/app/pages/index.page.ts__template__ b/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/app/pages/index.page.ts__template__ deleted file mode 100644 index 5552a2c7b..000000000 --- a/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/app/pages/index.page.ts__template__ +++ /dev/null @@ -1,62 +0,0 @@ -import { Component } from '@angular/core'; - -@Component({ - selector: '<%= fileName %>-home', - standalone: true, - template: ` -
- - - - - - -
- -

Vite + Angular

- -
- -
- -

- Check out - Analog, the fullstack meta-framework for Angular powered by Vite! -

- -

- Click on the Vite and Angular logos to learn more. -

- `, - styles: [ - ` - .logo { - height: 6em; - padding: 1.5em; - will-change: filter; - } - .logo:hover { - filter: drop-shadow(0 0 2em #646cffaa); - } - .logo.angular:hover { - filter: drop-shadow(0 0 2em #42b883aa); - } - .read-the-docs { - color: #888; - } - `, - ], -}) -export default class HomeComponent { - count = 0; - - increment() { - this.count++; - } -} diff --git a/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/main.providers.ts__template__ b/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/main.providers.ts__template__ deleted file mode 100644 index bce1d8737..000000000 --- a/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/main.providers.ts__template__ +++ /dev/null @@ -1,5 +0,0 @@ -/** - * Common providers shared with client and server-side. - */ - -export const mainProviders = []; diff --git a/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/main.server.ts__template__ b/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/main.server.ts__template__ index c6a59c92e..29ad24c06 100644 --- a/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/main.server.ts__template__ +++ b/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/main.server.ts__template__ @@ -1,32 +1,20 @@ import 'zone.js/node'; import { enableProdMode } from '@angular/core'; -import { bootstrapApplication } from '@angular/platform-browser'; -import { - provideServerRendering, - renderApplication, -} from '@angular/platform-server'; - +import { renderApplication } from '@angular/platform-server'; import { AppComponent } from './app/app.component'; -import { mainProviders } from './main.providers'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { config } from './app.config.server'; if (import.meta.env.PROD) { enableProdMode(); } -export function bootstrap() { - return bootstrapApplication(AppComponent, { - providers: [ - mainProviders, - provideServerRendering(), - ], - }); -} +const bootstrap = () => bootstrapApplication(AppComponent, config); export default async function render(url: string, document: string) { const html = await renderApplication(bootstrap, { document, url, }); - return html; } diff --git a/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/main.ts__template__ b/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/main.ts__template__ index 0a459af40..6a31bd61f 100644 --- a/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/main.ts__template__ +++ b/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/main.ts__template__ @@ -1,10 +1,9 @@ import 'zone.js'; import { bootstrapApplication } from '@angular/platform-browser'; -import { provideFileRouter } from '@analogjs/router'; import { AppComponent } from './app/app.component'; -import { mainProviders } from './main.providers'; +import { appConfig } from './app.config'; -bootstrapApplication(AppComponent, { - providers: [provideFileRouter(), ...mainProviders], -}); +bootstrapApplication(AppComponent, appConfig).catch((err) => + console.error(err) +); diff --git a/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/styles.css__template__ b/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/styles.css__template__ index 8e92f8fcd..336c6fd63 100644 --- a/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/styles.css__template__ +++ b/packages/nx-plugin/src/generators/app/files/template-angular-v16/src/styles.css__template__ @@ -1,75 +1,4 @@ -/* You can add global styles to this file, and also import other style files */ -:root { - font-family: Inter, Avenir, Helvetica, Arial, sans-serif; - font-size: 16px; - line-height: 24px; - font-weight: 400; - - color-scheme: light dark; - color: rgba(255, 255, 255, 0.87); - background-color: #242424; - - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - -webkit-text-size-adjust: 100%; -} - -a { - font-weight: 500; - color: #646cff; - text-decoration: inherit; -} -a:hover { - color: #535bf2; -} - -body { - margin: 0; - display: flex; - place-items: center; - min-width: 320px; - min-height: 100vh; -} - -h1 { - font-size: 3.2em; - line-height: 1.1; -} - -button { - border-radius: 8px; - border: 1px solid transparent; - padding: 0.6em 1.2em; - font-size: 1em; - font-weight: 500; - font-family: inherit; - background-color: #1a1a1a; - cursor: pointer; - transition: border-color 0.25s; -} -button:hover { - border-color: #646cff; -} -button:focus, -button:focus-visible { - outline: 4px auto -webkit-focus-ring-color; -} - -.card { - padding: 2em; -} - -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; - } - a:hover { - color: #747bff; - } - button { - background-color: #f9f9f9; - } +html, body { + display: block; + height: 100%; } diff --git a/packages/nx-plugin/src/generators/app/files/template-angular-v16/vite.config.ts__template__ b/packages/nx-plugin/src/generators/app/files/template-angular-v16/vite.config.ts__template__ index ca40eb47a..a3d676f13 100644 --- a/packages/nx-plugin/src/generators/app/files/template-angular-v16/vite.config.ts__template__ +++ b/packages/nx-plugin/src/generators/app/files/template-angular-v16/vite.config.ts__template__ @@ -9,6 +9,14 @@ import tsConfigPaths from 'vite-tsconfig-paths'; export default defineConfig(({ mode }) => { return { publicDir: 'src/public', + <% if (addTRPC) { %> + server: { + host: '127.0.0.1' + }, + ssr: { + noExternal: '@analogjs/trpc/**', + }, + <% } %> optimizeDeps: { include: ['@angular/common', '@angular/forms'], }, diff --git a/packages/nx-plugin/src/generators/app/generator.ts b/packages/nx-plugin/src/generators/app/generator.ts index b2c85aa47..7d93ba165 100644 --- a/packages/nx-plugin/src/generators/app/generator.ts +++ b/packages/nx-plugin/src/generators/app/generator.ts @@ -15,6 +15,8 @@ import { addAnalogDependencies } from './lib/add-analog-dependencies'; import { initializeAngularWorkspace } from './lib/initialize-analog-workspace'; import { addFiles } from './lib/add-files'; import { addTailwindConfig } from './lib/add-tailwind-config'; +import { addTRPC } from './lib/add-trpc'; +import { addIndexPages } from './lib/add-index-pages'; export interface NormalizedOptions extends AnalogNxApplicationGeneratorOptions, @@ -43,6 +45,9 @@ function normalizeOptions( : []; const offsetFromRoot = determineOffsetFromRoot(projectRoot); const nxPackageNamespace = major(nxVersion) >= 16 ? '@nx' : '@nrwl'; + const addTailwind = options.addTailwind ?? true; + const addTRPC = options.addTRPC ?? false; + return { ...options, ...allNames, @@ -53,6 +58,8 @@ function normalizeOptions( offsetFromRoot, appsDir, nxPackageNamespace, + addTailwind, + addTRPC, }; } @@ -97,7 +104,7 @@ export async function appGenerator( addFiles(tree, normalizedOptions, majorAngularVersion); - if (!normalizedOptions.skipTailwind) { + if (normalizedOptions.addTailwind) { await addTailwindConfig( tree, normalizedOptions.projectRoot, @@ -106,6 +113,17 @@ export async function appGenerator( ); } + if (normalizedOptions.addTRPC) { + await addTRPC( + tree, + normalizedOptions.projectRoot, + majorAngularVersion, + normalizedOptions + ); + } + + addIndexPages(tree, normalizedOptions); + if (!normalizedOptions.skipFormat) { await formatFiles(tree); } diff --git a/packages/nx-plugin/src/generators/app/lib/add-index-pages.ts b/packages/nx-plugin/src/generators/app/lib/add-index-pages.ts new file mode 100644 index 000000000..f1ebc285c --- /dev/null +++ b/packages/nx-plugin/src/generators/app/lib/add-index-pages.ts @@ -0,0 +1,21 @@ +import { generateFiles, Tree } from '@nrwl/devkit'; +import * as path from 'path'; +import { NormalizedOptions } from '../generator'; + +export function addIndexPages(tree: Tree, options: NormalizedOptions) { + const templateOptions = { + ...options, + template: '', + }; + let pageDirectory = options.addTailwind ? 'tailwind' : 'css'; + if (options.addTRPC) { + pageDirectory += '-trpc'; + } + + generateFiles( + tree, + path.join(__dirname, '..', 'files', 'index-pages', pageDirectory), + options.projectRoot, + templateOptions + ); +} diff --git a/packages/nx-plugin/src/generators/app/lib/add-trpc.ts b/packages/nx-plugin/src/generators/app/lib/add-trpc.ts new file mode 100644 index 000000000..081f117dc --- /dev/null +++ b/packages/nx-plugin/src/generators/app/lib/add-trpc.ts @@ -0,0 +1,57 @@ +import { + addDependenciesToPackageJson, + generateFiles, + Tree, +} from '@nrwl/devkit'; +import * as path from 'path'; +import { + V15_ANALOG_JS_TRPC, + V15_ISOMORPHIC_FETCH, + V15_SUPERJSON, + V15_TRPC_CLIENT, + V15_TRPC_SERVER, + V15_ZOD, + V16_ANALOG_JS_TRPC, + V16_SUPERJSON, + V16_TRPC_CLIENT, + V16_TRPC_SERVER, + V16_ZOD, +} from '../versions'; +import { NormalizedOptions } from '../generator'; + +export async function addTRPC( + tree: Tree, + projectRoot: string, + majorAngularVersion: number, + options: NormalizedOptions +) { + addDependenciesToPackageJson( + tree, + { + '@analogjs/trpc': + majorAngularVersion === 15 ? V15_ANALOG_JS_TRPC : V16_ANALOG_JS_TRPC, + '@trpc/client': + majorAngularVersion === 15 ? V15_TRPC_CLIENT : V16_TRPC_CLIENT, + '@trpc/server': + majorAngularVersion === 15 ? V15_TRPC_SERVER : V16_TRPC_SERVER, + superjson: majorAngularVersion === 15 ? V15_SUPERJSON : V16_SUPERJSON, + 'isomorphic-fetch': + majorAngularVersion === 15 + ? V15_ISOMORPHIC_FETCH + : V15_ISOMORPHIC_FETCH, + zod: majorAngularVersion === 15 ? V15_ZOD : V16_ZOD, + }, + {} + ); + + const templateOptions = { + ...options, + template: '', + }; + generateFiles( + tree, + path.join(__dirname, '..', 'files', 'trpc'), + projectRoot, + templateOptions + ); +} diff --git a/packages/nx-plugin/src/generators/app/schema.d.ts b/packages/nx-plugin/src/generators/app/schema.d.ts index b4d68940b..c6010f7ea 100644 --- a/packages/nx-plugin/src/generators/app/schema.d.ts +++ b/packages/nx-plugin/src/generators/app/schema.d.ts @@ -1,6 +1,7 @@ export interface AnalogNxApplicationGeneratorOptions { name: string; tags?: string; - skipTailwind?: boolean; + addTailwind?: boolean; + addTRPC?: boolean; skipFormat?: boolean; } diff --git a/packages/nx-plugin/src/generators/app/schema.json b/packages/nx-plugin/src/generators/app/schema.json index 05da1044f..716804883 100644 --- a/packages/nx-plugin/src/generators/app/schema.json +++ b/packages/nx-plugin/src/generators/app/schema.json @@ -14,10 +14,16 @@ }, "x-prompt": "What name would you like to use for your AnalogJs app?" }, - "skipTailwind": { + "addTailwind": { "type": "boolean", - "description": "Skip adding tailwind if set to true.", - "x-prompt": "Skip adding TailwindCSS?", + "description": "Adds tailwind if set to true.", + "x-prompt": "Add TailwindCSS for styling?", + "default": true + }, + "addTRPC": { + "type": "boolean", + "description": "Adds tRPC if set to true.", + "x-prompt": "Add tRPC for typesafe client/server interaction?", "default": false }, "tags": { diff --git a/packages/nx-plugin/src/generators/app/versions.ts b/packages/nx-plugin/src/generators/app/versions.ts index 546b0cda5..7e6478538 100644 --- a/packages/nx-plugin/src/generators/app/versions.ts +++ b/packages/nx-plugin/src/generators/app/versions.ts @@ -6,6 +6,12 @@ export const V16_NX_DEVKIT = '^16.0.0'; export const V16_NX_ANGULAR = '^16.0.0'; export const V16_ANALOG_JS_CONTENT = '^0.2.0-beta.6'; export const V16_ANALOG_JS_ROUTER = '^0.2.0-beta.6'; +export const V16_ANALOG_JS_TRPC = '^0.2.0-beta.6'; +export const V16_TRPC_CLIENT = '^10.25.0'; +export const V16_TRPC_SERVER = '^10.25.0'; +export const V16_ISOMORPHIC_FETCH = '^3.0.0'; +export const V16_SUPERJSON = '^1.12.3'; + export const V16_ANGULAR_PLATFORM_SERVER = '^16.0.0'; export const V16_FRONT_MATTER = '^4.0.2'; export const V16_MARKED = '^4.2.12'; @@ -19,6 +25,7 @@ export const V16_TYPESCRIPT = '~5.0.2'; export const V16_VITE = '^4.0.3'; export const V16_VITE_TSCONFIG_PATHS = '^4.0.2'; export const V16_VITEST = '^0.31.0'; +export const V16_ZOD = '^3.21.4'; // V15 // dependencies @@ -27,6 +34,11 @@ export const V15_NRWL_DEVKIT = '15.9.2'; export const V15_NRWL_ANGULAR = '15.9.2'; export const V15_ANALOG_JS_CONTENT = '^0.2.0-beta.6'; export const V15_ANALOG_JS_ROUTER = '^0.2.0-beta.6'; +export const V15_ANALOG_JS_TRPC = '^0.2.0-beta.6'; +export const V15_TRPC_CLIENT = '^10.25.0'; +export const V15_TRPC_SERVER = '^10.25.0'; +export const V15_ISOMORPHIC_FETCH = '^3.0.0'; +export const V15_SUPERJSON = '^1.12.3'; export const V15_ANGULAR_PLATFORM_SERVER = '^15.0.0'; export const V15_FRONT_MATTER = '^4.0.2'; export const V15_MARKED = '^4.2.12'; @@ -39,4 +51,5 @@ export const V15_JSDOM = '^20.0.0'; export const V15_TYPESCRIPT = '~4.8.4'; export const V15_VITE = '^4.0.3'; export const V15_VITE_TSCONFIG_PATHS = '^4.0.2'; -export const V15_VITEST = '^0.25.8'; +export const V15_VITEST = '^0.31.0'; +export const V15_ZOD = '^3.21.4'; diff --git a/packages/trpc/package.json b/packages/trpc/package.json index 54f7d6744..0f6f8a8cf 100644 --- a/packages/trpc/package.json +++ b/packages/trpc/package.json @@ -23,7 +23,8 @@ "@angular/core": "^16.0.0", "@trpc/client": "10.25.0", "@trpc/server": "10.25.0", - "isomorphic-fetch": "^3.0.0" + "isomorphic-fetch": "^3.0.0", + "superjson": "^1.12.3" }, "dependencies": { "tslib": "^2.3.0" diff --git a/packages/trpc/src/index.ts b/packages/trpc/src/index.ts index 45ff545b1..f42f4337c 100644 --- a/packages/trpc/src/index.ts +++ b/packages/trpc/src/index.ts @@ -1,2 +1,3 @@ export * from './lib/client/client'; export * from './lib/server/server'; +export * from './lib/utils/wait-for'; diff --git a/packages/trpc/src/lib/client/client.ts b/packages/trpc/src/lib/client/client.ts index bc151f609..eee94d453 100644 --- a/packages/trpc/src/lib/client/client.ts +++ b/packages/trpc/src/lib/client/client.ts @@ -16,7 +16,7 @@ import { CreateTRPCClientOptions } from '@trpc/client/src/createTRPCUntypedClien export type TrpcOptions = { url: string; - options: Partial>; + options?: Partial>; }; export type TrpcClient = ReturnType< diff --git a/apps/trpc-app/src/wait-for.ts b/packages/trpc/src/lib/utils/wait-for.ts similarity index 100% rename from apps/trpc-app/src/wait-for.ts rename to packages/trpc/src/lib/utils/wait-for.ts