Merge branch 'main' into login-passkey

This commit is contained in:
Max Peintner
2023-07-03 17:37:15 +02:00
30 changed files with 1312 additions and 113 deletions

View File

@@ -1,26 +1,76 @@
name: Test name: Quality
on:
pull_request: on: pull_request
concurrency: ${{ github.workflow }}-${{ github.ref }}
jobs: jobs:
test: quality:
name: Test
name: Ensure Quality
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: 'read'
strategy:
fail-fast: false
matrix:
command:
- lint
- test:unit
- test:integration
steps: steps:
- name: Checkout Repo - name: Checkout Repo
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: Setup pnpm 7 - name: Setup pnpm 7
uses: pnpm/action-setup@v2 uses: pnpm/action-setup@v2
with: with:
version: 7 version: 7
- name: Setup Node.js 16.x - name: Setup Node.js 16.x
uses: actions/setup-node@v2 uses: actions/setup-node@v2
with: with:
node-version: 16.x node-version: 16.x
- uses: pnpm/action-setup@v2
name: Install pnpm
id: pnpm-install
with:
version: 7
run_install: false
- name: Get pnpm store directory
id: pnpm-cache
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- uses: actions/cache@v3
name: Setup Cypress binary cache
with:
path: ~/.cache/Cypress
key: ${{ runner.os }}-cypress-binary-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-cypress-binary-
if: ${{ matrix.command }} == "test:integration"
- name: Install Dependencies - name: Install Dependencies
id: deps id: deps
run: pnpm install run: pnpm install
- name: Test
id: test - name: Check
run: pnpm test id: check
run: pnpm ${{ matrix.command }}

4
.gitignore vendored
View File

@@ -7,8 +7,8 @@ dist
dist-ssr dist-ssr
*.local *.local
.env .env
apps/login/.env.local.?.bak apps/login/.env.local
apps/login/.env.local.??.bak apps/login/.env.acceptance
.cache .cache
server/dist server/dist
public/dist public/dist

View File

@@ -38,25 +38,6 @@ However, it might be easier to develop against your ZITADEL Cloud instance
if you don't have docker installed if you don't have docker installed
or have limited resources on your local machine. or have limited resources on your local machine.
### Testing
You can execute the following commands in the following directories:
- apps/login
- packages/zitadel-client
- packages/zitadel-server
- packages/zitadel-react
- packages/zitadel-next
- The projects root directory: all tests in the project are executed
```sh
# Run all once
pnpm test
# Rerun tests on file changes
pnpm test:watch
```
### Developing Against Your Local ZITADEL Instance ### Developing Against Your Local ZITADEL Instance
```sh ```sh
@@ -68,15 +49,18 @@ docker compose --file ./acceptance/docker-compose.yaml pull
# Run ZITADEL and configure ./apps/login/.env.local # Run ZITADEL and configure ./apps/login/.env.local
docker compose --file ./acceptance/docker-compose.yaml run setup docker compose --file ./acceptance/docker-compose.yaml run setup
# Configure your shell to use the environment variables written to ./apps/login/.env.acceptance
source ./apps/login/.env.acceptance
``` ```
### Developing Against Your ZITADEL Cloud Instance ### Developing Against Your ZITADEL Cloud Instance
Create the file ./apps/login/.env.local with the following content: Configure your shell by exporting the following environment variables:
```sh ```sh
ZITADEL_API_URL=<your cloud instance URL here> export ZITADEL_API_URL=<your cloud instance URL here>
ZITADEL_ORG_ID=<your service accounts organization id here> export ZITADEL_ORG_ID=<your service accounts organization id here>
ZITADEL_SERVICE_USER_TOKEN=<your service account personal access token here> export ZITADEL_SERVICE_USER_TOKEN=<your service account personal access token here>
``` ```
### Setting up local environment ### Setting up local environment
@@ -94,4 +78,20 @@ pnpm dev
The application is now available at `http://localhost:3000` The application is now available at `http://localhost:3000`
### Testing
You can execute the following commands `pnpm test` for a single test run or `pnpm test:watch` in the following directories:
- apps/login
- packages/zitadel-client
- packages/zitadel-server
- packages/zitadel-react
- packages/zitadel-next
- The projects root directory: all tests in the project are executed
In apps/login, these commands also spin up the application and a ZITADEL gRPC API mock server to run integration tests using [Cypress](https://www.cypress.io/) against them.
If you want to run the integration tests standalone against an environment of your choice, navigate to ./apps/login, [configure your shell as you like](# Developing Against Your ZITADEL Cloud Instance) and run `pnpm test:integration:run` or `pnpm test:integration:open`.
Then you need to lifecycle the mock process using the command `pnpm mock` or the more fine grained commands `pnpm mock:build`, `pnpm mock:build:nocache`, `pnpm mock:run` and `pnpm mock:destroy`.
That's it! 🎉 That's it! 🎉

View File

@@ -11,7 +11,7 @@ echo "Using audience ${AUDIENCE} for which the key is used."
SERVICE=${SERVICE:-$AUDIENCE} SERVICE=${SERVICE:-$AUDIENCE}
echo "Using the service ${SERVICE} to connect to ZITADEL. For example in docker compose this can differ from the audience." echo "Using the service ${SERVICE} to connect to ZITADEL. For example in docker compose this can differ from the audience."
WRITE_ENVIRONMENT_FILE=${WRITE_ENVIRONMENT_FILE:-$(dirname "$0")/../apps/login/.env.local} WRITE_ENVIRONMENT_FILE=${WRITE_ENVIRONMENT_FILE:-$(dirname "$0")/../apps/login/.env.acceptance}
echo "Writing environment file to ${WRITE_ENVIRONMENT_FILE} when done." echo "Writing environment file to ${WRITE_ENVIRONMENT_FILE} when done."
AUDIENCE_HOST="$(echo $AUDIENCE | cut -d/ -f3)" AUDIENCE_HOST="$(echo $AUDIENCE | cut -d/ -f3)"
@@ -44,27 +44,6 @@ echo "${ORG_RESPONSE}" | jq
ORG_ID=$(echo -n ${ORG_RESPONSE} | jq --raw-output '.org.id') ORG_ID=$(echo -n ${ORG_RESPONSE} | jq --raw-output '.org.id')
echo "Extracted default org id ${ORG_ID}" echo "Extracted default org id ${ORG_ID}"
ENVIRONMENT_BACKUP_FILE=${WRITE_ENVIRONMENT_FILE}
# If the original file already exists, rename it
if [[ -e ${WRITE_ENVIRONMENT_FILE} ]]; then
if grep -q 'localhost' ${WRITE_ENVIRONMENT_FILE}; then
echo "Current environment file ${WRITE_ENVIRONMENT_FILE} contains localhost. Overwriting:"
cat ${WRITE_ENVIRONMENT_FILE}
else
i=0
# If a backup file already exists, increment counter until a free filename is found
while [[ -e ${ENVIRONMENT_BACKUP_FILE}.${i}.bak ]]; do
let "i++"
if [[ ${i} -eq 50 ]]; then
echo "Warning: Too many backup files (limit is 50), overwriting ${ENVIRONMENT_BACKUP_FILE}.${i}.bak"
break
fi
done
mv ${WRITE_ENVIRONMENT_FILE} ${ENVIRONMENT_BACKUP_FILE}.${i}.bak
echo "Renamed existing environment file to ${ENVIRONMENT_BACKUP_FILE}.${i}.bak"
fi
fi
echo "ZITADEL_API_URL=${AUDIENCE} echo "ZITADEL_API_URL=${AUDIENCE}
ZITADEL_ORG_ID=${ORG_ID} ZITADEL_ORG_ID=${ORG_ID}
ZITADEL_SERVICE_USER_TOKEN=${TOKEN}" > ${WRITE_ENVIRONMENT_FILE} ZITADEL_SERVICE_USER_TOKEN=${TOKEN}" > ${WRITE_ENVIRONMENT_FILE}

View File

@@ -0,0 +1 @@
ZITADEL_API_URL=http://localhost:22222

View File

@@ -1,16 +1,19 @@
import type { Config } from "@jest/types"; import type { Config } from "@jest/types";
import { pathsToModuleNameMapper } from "ts-jest"; import { pathsToModuleNameMapper } from "ts-jest";
import { compilerOptions } from "./tsconfig.json"; import { compilerOptions } from "../tsconfig.json";
// We make these type imports explicit, so IDEs with their own typescript engine understand them, too.
import type {} from "@testing-library/jest-dom";
export default async (): Promise<Config.InitialOptions> => { export default async (): Promise<Config.InitialOptions> => {
return { return {
preset: "ts-jest", preset: "ts-jest",
transform: { transform: {
"^.+\\.tsx?$": ["ts-jest", { tsconfig: "./__test__/tsconfig.json" }], "^.+\\.tsx?$": ["ts-jest", { tsconfig: "<rootDir>/tsconfig.json" }],
}, },
setupFilesAfterEnv: ["@testing-library/jest-dom/extend-expect"], setupFilesAfterEnv: ["@testing-library/jest-dom/extend-expect"],
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, {
prefix: "<rootDir>/", prefix: "<rootDir>/../",
}), }),
testEnvironment: "jsdom", testEnvironment: "jsdom",
testRegex: "/__test__/.*\\.test\\.tsx?$", testRegex: "/__test__/.*\\.test\\.tsx?$",

2
apps/login/cypress/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
screenshots
videos

View File

@@ -0,0 +1,12 @@
import { defineConfig } from "cypress";
export default defineConfig({
reporter: "list",
e2e: {
baseUrl: "http://localhost:3000",
specPattern: "cypress/integration/**/*.cy.{js,jsx,ts,tsx}",
setupNodeEvents(on, config) {
// implement node event listeners here
},
},
});

View File

@@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}

View File

@@ -0,0 +1,21 @@
import { addStub, removeStub } from "../support/mock";
describe("/verify", () => {
it("redirects after successful email verification", () => {
removeStub("zitadel.user.v2alpha.UserService", "VerifyEmail");
addStub("zitadel.user.v2alpha.UserService", "VerifyEmail");
cy.visit("/verify?userID=123&code=abc&submit=true");
cy.location("pathname", { timeout: 10_000 }).should("eq", "/username");
});
it("shows an error if validation failed", () => {
removeStub("zitadel.user.v2alpha.UserService", "VerifyEmail");
addStub("zitadel.user.v2alpha.UserService", "VerifyEmail", {
code: 3,
error: "error validating code",
});
// TODO: Avoid uncaught exception in application
cy.once("uncaught:exception", () => false);
cy.visit("/verify?userID=123&code=abc&submit=true");
cy.contains("error validating code");
});
});

View File

@@ -0,0 +1,37 @@
/// <reference types="cypress" />
// ***********************************************
// This example commands.ts shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
//
// declare global {
// namespace Cypress {
// interface Chainable {
// login(email: string, password: string): Chainable<void>
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
// }
// }
// }

View File

@@ -0,0 +1,20 @@
// ***********************************************************
// This example support/e2e.ts is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import "./commands";
// Alternatively you can use CommonJS syntax:
// require('./commands')

View File

@@ -0,0 +1,26 @@
export function removeStub(service: string, method: string) {
return cy.request({
url: "http://localhost:22220/v1/stubs",
method: "DELETE",
qs: {
service: service,
method: method,
},
});
}
export function addStub(service: string, method: string, out?: any) {
return cy.request({
url: "http://localhost:22220/v1/stubs",
method: "POST",
body: {
stubs: [
{
service: service,
method: method,
out: out,
},
],
},
});
}

View File

@@ -0,0 +1,9 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"target": "es5",
"lib": ["es5", "dom"],
"types": ["cypress", "node"]
},
"include": ["**/*.ts"]
}

View File

@@ -0,0 +1,20 @@
FROM bufbuild/buf:1.21.0 as protos
RUN buf export https://github.com/envoyproxy/protoc-gen-validate.git --path validate --output /proto
RUN buf export https://github.com/grpc-ecosystem/grpc-gateway.git --path protoc-gen-openapiv2 --output /proto
RUN buf export https://github.com/googleapis/googleapis.git --path google/api/annotations.proto --path google/api/http.proto --path google/api/field_behavior.proto --output /proto
RUN buf export https://github.com/zitadel/zitadel.git --path ./proto/zitadel --output /proto
FROM scratch AS config
COPY mocked-services.cfg .
COPY initial-stubs initial-stubs
COPY --from=protos /proto .
FROM golang:1.20.5-alpine3.18 as grpc-mock
RUN go install github.com/eliobischof/grpc-mock/cmd/grpc-mock@01b09f60db1b501178af59bed03b2c22661df48c
COPY --from=config / .
ENTRYPOINT [ "sh", "-c", "grpc-mock -v 1 -proto $(tr '\n' ',' < ./mocked-services.cfg) -stub-dir ./initial-stubs" ]

View File

@@ -0,0 +1,17 @@
[
{
"service": "zitadel.settings.v2alpha.SettingsService",
"method": "GetBrandingSettings",
"out": {}
},
{
"service": "zitadel.settings.v2alpha.SettingsService",
"method": "GetLegalAndSupportSettings",
"out": {}
},
{
"service": "zitadel.settings.v2alpha.SettingsService",
"method": "GetPasswordComplexitySettings",
"out": {}
}
]

View File

@@ -0,0 +1,6 @@
zitadel/user/v2alpha/user_service.proto
zitadel/session/v2alpha/session_service.proto
zitadel/settings/v2alpha/settings_service.proto
zitadel/management.proto
zitadel/auth.proto
zitadel/admin.proto

View File

@@ -9,7 +9,7 @@ const nextConfig = {
remotePatterns: [ remotePatterns: [
{ {
protocol: "https", protocol: "https",
hostname: process.env.ZITADEL_API_URL.replace("https://", ""), hostname: process.env.ZITADEL_API_URL?.replace("https://", "") || "",
port: "", port: "",
pathname: "/**", pathname: "/**",
}, },

View File

@@ -3,15 +3,27 @@
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev", "dev": "next dev",
"test": "jest", "test": "concurrently --timings --kill-others-on-fail 'npm:test:unit' 'npm:test:integration'",
"test:watch": "jest --watch", "test:watch": "concurrently --kill-others 'npm:test:unit:watch' 'npm:test:integration:watch'",
"test:unit": "jest --config ./__test__/jest.config.ts",
"test:unit:watch": "pnpm test:unit --watch",
"test:integration": "pnpm mock:build && concurrently --names 'mock,test' --success command-test --kill-others 'pnpm:mock' 'env-cmd -f ./.env.integration start-server-and-test start http://localhost:3000 \"test:integration:run\"'",
"test:integration:watch": "concurrently --names 'mock,test' --kill-others 'pnpm:mock' 'env-cmd -f ./.env.integration start-server-and-test dev http://localhost:3000 \"pnpm nodemon -e js,jsx,ts,tsx,css,scss --ignore \\\"__test__/**\\\" --exec \\\"pnpm test:integration:run\\\"\"'",
"test:integration:run": "cypress run --config-file ./cypress/cypress.config.ts --quiet",
"test:integration:open": "cypress open --config-file ./cypress/cypress.config.ts",
"mock": "pnpm mock:build && pnpm mock:run",
"mock:run": "pnpm mock:stop && docker run --rm --name zitadel-mock-grpc-server --publish 22220:22220 --publish 22222:22222 zitadel-mock-grpc-server",
"mock:build": "DOCKER_BUILDKIT=1 docker build --tag zitadel-mock-grpc-server ./mock",
"mock:build:nocache": "pnpm mock:build --no-cache",
"mock:stop": "docker rm --force zitadel-mock-grpc-server 2>/dev/null || true",
"mock:destroy": "docker rmi --force zitadel-mock-grpc-server 2>/dev/null || true",
"lint": "next lint && prettier --check .", "lint": "next lint && prettier --check .",
"lint:fix": "prettier --write .", "lint:fix": "prettier --write .",
"lint-staged": "lint-staged", "lint-staged": "lint-staged",
"build": "next build", "build": "next build",
"prestart": "build", "prestart": "pnpm build",
"start": "next start", "start": "next start",
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf .next" "clean": "pnpm mock:destroy && rm -rf .turbo && rm -rf node_modules && rm -rf .next"
}, },
"git": { "git": {
"pre-commit": "lint-staged" "pre-commit": "lint-staged"
@@ -56,15 +68,21 @@
"@vercel/git-hooks": "1.0.0", "@vercel/git-hooks": "1.0.0",
"@zitadel/tsconfig": "workspace:*", "@zitadel/tsconfig": "workspace:*",
"autoprefixer": "10.4.13", "autoprefixer": "10.4.13",
"concurrently": "^8.1.0",
"cypress": "^12.14.0",
"del-cli": "5.0.0", "del-cli": "5.0.0",
"env-cmd": "^10.1.0",
"eslint-config-zitadel": "workspace:*", "eslint-config-zitadel": "workspace:*",
"grpc-tools": "1.11.3", "grpc-tools": "1.11.3",
"jest": "^29.5.0", "jest": "^29.5.0",
"jest-environment-jsdom": "^29.5.0", "jest-environment-jsdom": "^29.5.0",
"jest-silent-reporter": "^0.5.0",
"lint-staged": "13.0.3", "lint-staged": "13.0.3",
"make-dir-cli": "3.0.0", "make-dir-cli": "3.0.0",
"nodemon": "^2.0.22",
"postcss": "8.4.21", "postcss": "8.4.21",
"prettier-plugin-tailwindcss": "0.1.13", "prettier-plugin-tailwindcss": "0.1.13",
"start-server-and-test": "^2.0.0",
"tailwindcss": "3.2.4", "tailwindcss": "3.2.4",
"ts-jest": "^29.1.0", "ts-jest": "^29.1.0",
"ts-node": "^10.9.1", "ts-node": "^10.9.1",

21
apps/login/turbo.json Normal file
View File

@@ -0,0 +1,21 @@
{
"extends": ["//"],
"pipeline": {
"build": {
"outputs": ["dist/**", ".next/**", "!.next/cache/**"],
"dependsOn": ["^build"]
},
"test": {
"dependsOn": ["@zitadel/server#build", "@zitadel/react#build"]
},
"test:integration": {
"dependsOn": ["@zitadel/server#build", "@zitadel/react#build"]
},
"test:unit": {
"dependsOn": ["@zitadel/server#build"]
},
"test:watch": {
"dependsOn": ["@zitadel/server#build", "@zitadel/react#build"]
}
}
}

View File

@@ -4,9 +4,12 @@
"generate": "turbo run generate", "generate": "turbo run generate",
"build": "turbo run build", "build": "turbo run build",
"test": "turbo run test", "test": "turbo run test",
"test:unit": "turbo run test:unit",
"test:integration": "turbo run test:integration",
"test:watch": "turbo run test:watch", "test:watch": "turbo run test:watch",
"dev": "turbo run dev --no-cache --continue", "dev": "turbo run dev --no-cache --continue",
"lint": "turbo run lint", "lint": "turbo run lint",
"lint:fix": "turbo run lint:fix",
"clean": "turbo run clean && rm -rf node_modules", "clean": "turbo run clean && rm -rf node_modules",
"format": "prettier --write \"**/*.{ts,tsx,md}\"", "format": "prettier --write \"**/*.{ts,tsx,md}\"",
"changeset": "changeset", "changeset": "changeset",

View File

@@ -11,10 +11,11 @@
], ],
"scripts": { "scripts": {
"generate": "buf generate https://github.com/zitadel/zitadel.git --path ./proto/zitadel", "generate": "buf generate https://github.com/zitadel/zitadel.git --path ./proto/zitadel",
"prebuild": "pnpm run generate",
"build": "tsup src/index.ts --format esm,cjs --dts", "build": "tsup src/index.ts --format esm,cjs --dts",
"test": "jest", "test": "pnpm test:unit",
"test:watch": "jest --watch", "test:watch": "pnpm test:unit:watch",
"test:unit": "jest",
"test:unit:watch": "jest --watch",
"dev": "tsup src/index.ts --format esm,cjs --watch --dts", "dev": "tsup src/index.ts --format esm,cjs --watch --dts",
"lint": "eslint \"src/**/*.ts*\"", "lint": "eslint \"src/**/*.ts*\"",
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist" "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist"

View File

@@ -0,0 +1,21 @@
{
"extends": [
"//"
],
"pipeline": {
"generate": {
"outputs": [
"src/proto/**"
],
"cache": true
},
"build": {
"outputs": [
"dist/**"
],
"dependsOn": [
"generate"
]
}
}
}

View File

@@ -11,8 +11,10 @@
], ],
"scripts": { "scripts": {
"build": "tsup src/index.tsx --format esm,cjs --dts --external react", "build": "tsup src/index.tsx --format esm,cjs --dts --external react",
"test": "jest", "test": "pnpm test:unit",
"test:watch": "jest --watch", "test:watch": "pnpm test:unit:watch",
"test:unit": "jest",
"test:unit:watch": "jest --watch",
"dev": "tsup src/index.tsx --format esm,cjs --watch --dts --external react", "dev": "tsup src/index.tsx --format esm,cjs --watch --dts --external react",
"lint": "eslint \"src/**/*.ts*\"", "lint": "eslint \"src/**/*.ts*\"",
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist" "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist"

View File

@@ -13,8 +13,10 @@
}, },
"scripts": { "scripts": {
"build": "tsup", "build": "tsup",
"test": "jest", "test": "pnpm test:unit",
"test:watch": "jest --watch", "test:watch": "pnpm test:unit:watch",
"test:unit": "jest",
"test:unit:watch": "jest --watch",
"dev": "tsup --watch", "dev": "tsup --watch",
"lint": "eslint \"src/**/*.ts*\"", "lint": "eslint \"src/**/*.ts*\"",
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist", "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist",

View File

@@ -0,0 +1,12 @@
{
"extends": [
"//"
],
"pipeline": {
"build": {
"outputs": [
"dist/**"
]
}
}
}

View File

@@ -12,10 +12,11 @@
], ],
"scripts": { "scripts": {
"generate": "buf generate https://github.com/zitadel/zitadel.git --path ./proto/zitadel", "generate": "buf generate https://github.com/zitadel/zitadel.git --path ./proto/zitadel",
"prebuild": "pnpm run generate",
"build": "tsup --dts", "build": "tsup --dts",
"test": "jest", "test": "pnpm test:unit",
"test:watch": "jest --watch", "test:watch": "pnpm test:unit:watch",
"test:unit": "jest",
"test:unit:watch": "jest --watch",
"dev": "tsup --dts --watch", "dev": "tsup --dts --watch",
"lint": "eslint \"src/**/*.ts*\"", "lint": "eslint \"src/**/*.ts*\"",
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist" "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist"

View File

@@ -0,0 +1,21 @@
{
"extends": [
"//"
],
"pipeline": {
"generate": {
"outputs": [
"src/proto/**"
],
"cache": true
},
"build": {
"outputs": [
"dist/**"
],
"dependsOn": [
"generate"
]
}
}
}

936
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -2,36 +2,17 @@
"$schema": "https://turbo.build/schema.json", "$schema": "https://turbo.build/schema.json",
"pipeline": { "pipeline": {
"generate": { "generate": {
"outputs": [
"src/proto/**"
],
"cache": true "cache": true
}, },
"build": { "build": {},
"outputs": [ "test": {},
"dist/**", "test:unit": {},
".next/**", "test:integration": {},
"!.next/cache/**"
],
"dependsOn": [
"lint",
"generate",
"^build"
]
},
"test": {
"dependsOn": [
"generate",
"@zitadel/server#build"
]
},
"test:watch": { "test:watch": {
"dependsOn": [ "persistent": true
"generate",
"@zitadel/server#build"
]
}, },
"lint": {}, "lint": {},
"lint:fix": {},
"dev": { "dev": {
"cache": false, "cache": false,
"persistent": true "persistent": true