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 @@
-
+
-
+
+
+
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.
+
+
+ Count: {{ count }}
+
+
+
+
+ `,
+})
+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.
+
+
+ Count: {{ count }}
+
+
+
+
+ `,
+})
+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
-
-
- Count {{ count }}
-
-
-
- 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
-
-
- Count {{ count }}
-
-
-
- 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