macos update
Publish npm package / publish (push) Canceled after 0s

This commit is contained in:
2026-10-07 14:02:19 +02:00
parent 7fb87fbb96
commit c7e7e615c2
17 changed files with 284 additions and 130 deletions
+41 -2
View File
@@ -17,6 +17,15 @@ Supported mobile frontends:
bun create glstack bun create glstack
``` ```
The CLI asks for:
- **Project name** -- used for the directory, the database and the `@<name>/rpc` package
- **Web frontend** -- SvelteKit, Solid Start or none
- **Mobile frontend** -- React Native + Expo or none
- **Bundle identifier** (Expo only) -- reverse-DNS id used as both the iOS bundle identifier and the Android package, e.g. `com.example.app`
- **Go package prefix** -- e.g. `github.com/you`, giving the module path `github.com/you/<name>`
- **Install dependencies** -- runs `bun install` in the new project
## What you get ## What you get
A monorepo with the following structure: A monorepo with the following structure:
@@ -26,10 +35,11 @@ A monorepo with the following structure:
- **`apps/mobile`** -- Optional [React Native + Expo](https://expo.dev/) mobile app sharing the same RPC client - **`apps/mobile`** -- Optional [React Native + Expo](https://expo.dev/) mobile app sharing the same RPC client
- **`packages/proto`** -- Protobuf service definitions with [Buf](https://buf.build/) for codegen (Go + TypeScript) - **`packages/proto`** -- Protobuf service definitions with [Buf](https://buf.build/) for codegen (Go + TypeScript)
- **`packages/rpc`** -- Generated TypeScript Connect RPC client shared across frontend apps - **`packages/rpc`** -- Generated TypeScript Connect RPC client shared across frontend apps
- **`scripts`** -- Codegen helpers, e.g. building the `packages/rpc` index from the generated client
### Dev environment ### Dev environment
The template includes a [devenv.nix](https://devenv.sh/) configuration that sets up: The template includes a [devenv.nix](https://devenv.sh/) configuration for macOS and Linux that sets up:
- Go, TypeScript, Bun, Node.js - Go, TypeScript, Bun, Node.js
- PostgreSQL with an auto-provisioned database - PostgreSQL with an auto-provisioned database
@@ -37,10 +47,39 @@ The template includes a [devenv.nix](https://devenv.sh/) configuration that sets
- [Air](https://github.com/air-verse/air) for Go live reload - [Air](https://github.com/air-verse/air) for Go live reload
- [sqlc](https://sqlc.dev/) for type-safe SQL - [sqlc](https://sqlc.dev/) for type-safe SQL
- [dbmate](https://github.com/amacneil/dbmate) for database migrations - [dbmate](https://github.com/amacneil/dbmate) for database migrations
- With Expo: the Android SDK and an emulator, plus the iOS simulator on macOS
Start everything with:
```sh
cd <name>
devenv up
```
### Mobile (Expo)
`devenv up` creates an Android emulator matching your CPU (arm64 or x86_64), waits for it to boot and runs the app on it. On macOS it also builds and runs the app on the iOS simulator. Both apps share one Metro bundler, so saving a file reloads both.
The Android emulator reaches the API at `10.0.2.2:8080` and the iOS simulator at `127.0.0.1:8080`; the app picks the right one per platform.
The native `ios/` and `android/` folders are generated from `app.json` and not committed. After changing native config or upgrading Expo, delete them and they are regenerated on the next run.
#### iOS on macOS
Nix can't provide Xcode, so the iOS simulator needs a few things installed on the Mac. Entering the devenv shell checks them and lists anything missing; run `ios-check` to check again. Until they are met, `devenv up` skips iOS and runs everything else.
| Requirement | How to fix |
| --- | --- |
| Xcode | Install it from the [App Store](https://apps.apple.com/app/xcode/id497799835) |
| Xcode license and first-launch setup | `sudo xcodebuild -runFirstLaunch` |
| An iOS simulator runtime | `xcodebuild -downloadPlatform iOS` |
| An iPhone simulator | Create one in Xcode › Window › Devices and Simulators |
CocoaPods comes from Nix. The iOS build uses `/Applications/Xcode.app` (or the Xcode chosen with `xcode-select`) outside the Nix compiler environment, so the Command Line Tools being selected is fine.
### Starter example ### Starter example
The generated project includes a working Todo CRUD example wired end-to-end: protobuf schema, Go service implementation, SQL queries, and frontend UI. The generated project includes a working Todo CRUD example wired end-to-end: protobuf schema, Go service implementation, SQL queries, and frontend UI. In the mobile app, rows animate into place with [Reanimated](https://docs.swmansion.com/react-native-reanimated/) when a todo is checked off and the list re-sorts.
## License ## License
+17
View File
@@ -4,6 +4,7 @@ import * as p from "@clack/prompts";
import { initRenderer } from '@gregorlohaus/tdir' import { initRenderer } from '@gregorlohaus/tdir'
import { z } from 'zod' import { z } from 'zod'
import path from "node:path"; import path from "node:path";
import { readdir, rename } from "node:fs/promises";
p.intro(`create-glstack ${process.env.GLSTACK_DEV && 'isDev'}`); p.intro(`create-glstack ${process.env.GLSTACK_DEV && 'isDev'}`);
@@ -89,6 +90,22 @@ const destDir = path.join("./", project.name);
// `results` in the bundleid prompt makes group() infer it as unknown. // `results` in the bundleid prompt makes group() infer it as unknown.
render(destDir, { project: { ...project, bundleid: project.bundleid as string } }, { reverseMap: true }) render(destDir, { project: { ...project, bundleid: project.bundleid as string } }, { reverseMap: true })
// npm never publishes .gitignore/.npmrc, so the template stores them as _gitignore/_npmrc.
const dotfiles: Record<string, string> = { _gitignore: ".gitignore", _npmrc: ".npmrc" }
for (const file of await readdir(destDir, { recursive: true })) {
const dotname = dotfiles[path.basename(file)]
if (dotname) await rename(path.join(destDir, file), path.join(destDir, path.dirname(file), dotname))
}
const mapFile = Bun.file(path.join(destDir, ".tdir-map.json"))
if (await mapFile.exists()) {
const map = await mapFile.json()
for (const entry of map.files) {
const dotname = dotfiles[path.basename(entry.outputPath)]
if (dotname) entry.outputPath = path.join(path.dirname(entry.outputPath), dotname)
}
await Bun.write(mapFile, JSON.stringify(map, null, 2))
}
const s = p.spinner(); const s = p.spinner();
if (project.installDeps) { if (project.installDeps) {
s.start("Installing dependencies"); s.start("Installing dependencies");
@@ -36,7 +36,11 @@
"imageWidth": 76 "imageWidth": 76
} }
} }
] ],
"expo-font",
"expo-image",
"expo-status-bar",
"expo-web-browser"
], ],
"experiments": { "experiments": {
"typedRoutes": true, "typedRoutes": true,
@@ -3,32 +3,32 @@
"main": "expo-router/entry", "main": "expo-router/entry",
"version": "1.0.0", "version": "1.0.0",
"dependencies": { "dependencies": {
"@expo/ui": "~56.0.14",
"@<@var(context.project.name)>/rpc": "workspace:*", "@<@var(context.project.name)>/rpc": "workspace:*",
"expo": "~56.0.5", "@expo/ui": "~57.0.22",
"expo-constants": "~56.0.16", "expo": "~57.0.27",
"expo-crypto": "~56.0.4", "expo-constants": "~57.0.21",
"expo-dev-client": "~56.0.18", "expo-crypto": "~57.0.3",
"expo-device": "~56.0.4", "expo-dev-client": "~57.0.19",
"expo-font": "~56.0.5", "expo-device": "~57.0.2",
"expo-glass-effect": "~56.0.4", "expo-font": "~57.0.4",
"expo-image": "~56.0.9", "expo-glass-effect": "~57.0.4",
"expo-linking": "~56.0.12", "expo-image": "~57.0.5",
"expo-router": "~56.2.7", "expo-linking": "~57.0.12",
"expo-splash-screen": "~56.0.10", "expo-router": "~57.0.25",
"expo-status-bar": "~56.0.4", "expo-splash-screen": "~57.0.9",
"expo-symbols": "~56.0.5", "expo-status-bar": "~57.0.1",
"expo-system-ui": "~56.0.5", "expo-symbols": "~57.0.3",
"expo-web-browser": "~56.0.5", "expo-system-ui": "~57.0.4",
"expo-web-browser": "~57.0.3",
"react": "19.2.3", "react": "19.2.3",
"react-dom": "19.2.3", "react-dom": "19.2.3",
"react-native": "0.85.3", "react-native": "0.86.3",
"react-native-gesture-handler": "~2.31.1", "react-native-gesture-handler": "~2.32.0",
"react-native-reanimated": "4.3.1", "react-native-reanimated": "4.5.1",
"react-native-safe-area-context": "~5.7.0", "react-native-safe-area-context": "~5.7.0",
"react-native-screens": "4.25.2", "react-native-screens": "~4.26.0",
"react-native-web": "~0.21.0", "react-native-web": "~0.21.0",
"react-native-worklets": "0.8.3" "react-native-worklets": "0.10.1"
}, },
"devDependencies": { "devDependencies": {
"@types/react": "~19.2.2", "@types/react": "~19.2.2",
@@ -1,13 +1,47 @@
import { createRouter, Todo } from "@<@var(context.project.name)>/rpc" import { createRouter, Todo } from "@<@var(context.project.name)>/rpc"
import { useEffect, useState } from "react" import { useEffect, useState } from "react"
import { ScrollView, Button, Checkbox, Host, Column, TextInput, Text, useNativeState, Row, Icon } from "@expo/ui"; import { Platform, PlatformColor, ScrollView, useColorScheme } from "react-native"
import Animated, { FadeIn, FadeOut, LinearTransition } from "react-native-reanimated"
import { SafeAreaView } from "react-native-safe-area-context"
import { Button, Checkbox, Host, Column, TextInput, Text, useNativeState, Row, Icon } from "@expo/ui";
import * as Crypto from "expo-crypto" import * as Crypto from "expo-crypto"
import { colorInvert, controlSize } from "@expo/ui/swift-ui/modifiers"; import { background, colorInvert, controlSize, padding as iosPadding, shapes } from "@expo/ui/swift-ui/modifiers";
import { fillMaxWidth, padding, width } from "@expo/ui/jetpack-compose/modifiers"; // No numeric width() on Android: @expo/ui 57 can't convert it natively and crashes.
import { fillMaxWidth, padding, weight } from "@expo/ui/jetpack-compose/modifiers";
// The Android emulator reaches the host via 10.0.2.2; the iOS simulator shares the host's network.
const apiUrl = Platform.OS === "android" ? "http://10.0.2.2:8080" : "http://127.0.0.1:8080"
// SwiftUI clips a border to its corner radius, cutting off the corners, so on iOS the
// border is an outer rounded fill showing 1pt around an inner one.
const iosInputBorder = Platform.OS === "ios" ? [
iosPadding({ all: 10 }),
background(PlatformColor("secondarySystemGroupedBackground"), shapes.roundedRectangle({ cornerRadius: 9, roundedCornerStyle: "continuous" })),
iosPadding({ all: 1 }),
background(PlatformColor("separator"), shapes.roundedRectangle({ cornerRadius: 10, roundedCornerStyle: "continuous" })),
] : []
// Animates its position when the list re-sorts. The Host's measured height goes through state:
// on Android a layout transition ignores the size matchContents sets natively, collapsing the row.
function AnimatedRow({ children }: { children: React.ReactNode }) {
const [height, setHeight] = useState<number>()
return (
<Animated.View layout={LinearTransition.springify()} entering={FadeIn} exiting={FadeOut}>
<Host
matchContents={{ vertical: true }}
style={height ? { height } : undefined}
onLayoutContent={(e) => setHeight(e.nativeEvent.height)}
>
{children}
</Host>
</Animated.View>
)
}
export default function Index() { export default function Index() {
const router = createRouter("http://10.0.2.2:8080") const router = createRouter(apiUrl)
const [todos, setTodos] = useState<Array<Todo>>([]) const [todos, setTodos] = useState<Array<Todo>>([])
const todoToCreateTask = useNativeState<string>("") const todoToCreateTask = useNativeState<string>("")
const colorScheme = useColorScheme()
const fetchTodos = () => { const fetchTodos = () => {
router.todos.listTodos({}).then((r) => { router.todos.listTodos({}).then((r) => {
setTodos(r.todos) setTodos(r.todos)
@@ -15,19 +49,17 @@ export default function Index() {
} }
useEffect(() => { useEffect(() => {
fetchTodos(); fetchTodos();
}) }, [])
const setTodoDone = (id: string, task: string) => { const setTodoDone = (id: string, task: string) => {
return (done: boolean) => { return (done: boolean) => {
router.todos.updateTodo({ todo: { id, task, done } }) router.todos.updateTodo({ todo: { id, task, done } }).then(fetchTodos)
fetchTodos()
} }
} }
const deleteTodo = (id: string) => { const deleteTodo = (id: string) => {
return () => { return () => {
router.todos.deleteTodo({ todo: { id } }) router.todos.deleteTodo({ todo: { id } }).then(fetchTodos)
fetchTodos()
} }
} }
@@ -45,29 +77,43 @@ export default function Index() {
} }
return ( return (
<Host style={{ flex: 1 }}> <SafeAreaView style={{ flex: 1 }}>
<Host matchContents={{ vertical: true }}>
<Column alignment="center" modifiers={[fillMaxWidth()]}> <Column alignment="center" modifiers={[fillMaxWidth()]}>
<Text textStyle={{fontSize:30}}> Create Todo </Text> <Text textStyle={{fontSize:30}}> Create Todo </Text>
<TextInput value={todoToCreateTask} onChangeText={updateTodoToCreateTask} /> <TextInput
value={todoToCreateTask}
onChangeText={updateTodoToCreateTask}
placeholder="What needs to be done?"
style={Platform.OS === "ios"
? { width: 280 }
// Android draws the border as a fill behind the background, so the background must be opaque.
: { padding: 10, borderWidth: 1, borderColor: "#8E8E93", borderRadius: 8, backgroundColor: colorScheme === "dark" ? "#1C1B1F" : "#FFFFFF" }}
modifiers={Platform.OS === "ios" ? iosInputBorder : [fillMaxWidth(0.75)]}
/>
<Button modifiers={[controlSize('regular')]} label="create Todo" onPress={createTodo} /> <Button modifiers={[controlSize('regular')]} label="create Todo" onPress={createTodo} />
<ScrollView modifiers={[fillMaxWidth()]}> </Column>
</Host>
<ScrollView>
{ {
todos.map((todo) => ( todos.map((todo) => (
// Keyed by id so native toggles follow their todo.
<AnimatedRow key={todo.id}>
<Row alignment="center" modifiers={[fillMaxWidth(),padding(20,0,20,0)]}> <Row alignment="center" modifiers={[fillMaxWidth(),padding(20,0,20,0)]}>
<Column alignment="start" modifiers={[width(200)]}> <Column alignment="start" modifiers={[weight(1)]}>
<Text> {todo.task} </Text> <Text>{todo.task}</Text>
</Column> </Column>
<Column alignment="center"> <Column alignment="center">
<Checkbox value={todo.done || false} onValueChange={setTodoDone(todo.id || "", todo.task)} /> <Checkbox value={todo.done || false} onValueChange={setTodoDone(todo.id || "", todo.task)} />
</Column> </Column>
<Column alignment="end" modifiers={[fillMaxWidth()]}> <Column alignment="end">
<Button modifiers={[controlSize('regular')]} label="delete" onPress={deleteTodo(todo.id || "")}/> <Button modifiers={[controlSize('regular')]} label="delete" onPress={deleteTodo(todo.id || "")}/>
</Column> </Column>
</Row> </Row>
</AnimatedRow>
)) ))
} }
</ScrollView> </ScrollView>
</Column> </SafeAreaView>
</Host>
) )
} }
+47 -8
View File
@@ -1,5 +1,14 @@
{ pkgs, lib, config, inputs, ... }: { pkgs, lib, config, inputs, ... }:
<@if(eq(context.project.mobile,"expo"))>
let
# Sets dev_dir to Xcode's developer dir. devenv points DEVELOPER_DIR at the Nix SDK,
# which xcode-select would echo back, so it is unset for the lookup.
xcodeDevDir = ''
dev_dir="$(/usr/bin/env -u DEVELOPER_DIR /usr/bin/xcode-select -p 2>/dev/null)"
[ -x "$dev_dir/usr/bin/simctl" ] || dev_dir=/Applications/Xcode.app/Contents/Developer
'';
in
<@endif>
{ {
packages = [ packages = [
pkgs.bun pkgs.bun
@@ -33,6 +42,8 @@
# The emulator's bundled libs are only needed on Linux; macOS uses DYLD paths. # The emulator's bundled libs are only needed on Linux; macOS uses DYLD paths.
enterShell = lib.optionalString pkgs.stdenv.isLinux '' enterShell = lib.optionalString pkgs.stdenv.isLinux ''
export LD_LIBRARY_PATH=$ANDROID_HOME/emulator/lib64:$LD_LIBRARY_PATH export LD_LIBRARY_PATH=$ANDROID_HOME/emulator/lib64:$LD_LIBRARY_PATH
'' + lib.optionalString pkgs.stdenv.isDarwin ''
ios-check || true
''; '';
# Use a system image matching the host CPU (arm64 on Apple Silicon, x86_64 elsewhere). # Use a system image matching the host CPU (arm64 on Apple Silicon, x86_64 elsewhere).
scripts.create-avd.exec = '' scripts.create-avd.exec = ''
@@ -40,16 +51,39 @@
echo no | avdmanager create avd -n "Pixel_5_API34" -k "system-images;android-34;google_apis_playstore;${if pkgs.stdenv.hostPlatform.isAarch64 then "arm64-v8a" else "x86_64"}" -d "pixel_5" echo no | avdmanager create avd -n "Pixel_5_API34" -k "system-images;android-34;google_apis_playstore;${if pkgs.stdenv.hostPlatform.isAarch64 then "arm64-v8a" else "x86_64"}" -d "pixel_5"
fi fi
''; '';
# macOS only: run on the iOS simulator when Xcode with a simulator is installed. # macOS only: Nix can't provide Xcode, so report what the iOS build still needs.
scripts.ios-check = lib.mkIf pkgs.stdenv.isDarwin {
exec = ''
${xcodeDevDir}
export DEVELOPER_DIR="$dev_dir"
problems=""
missing() { problems+=" - $1"$'\n'; }
if [ ! -x "$dev_dir/usr/bin/simctl" ]; then
missing "Xcode is not installed. Install it from the App Store: https://apps.apple.com/app/xcode/id497799835"
else
if ! /usr/bin/xcodebuild -license check >/dev/null 2>&1 || ! /usr/bin/xcodebuild -checkFirstLaunchStatus >/dev/null 2>&1; then
missing "Xcode setup is incomplete (license or first-launch components). Run: sudo xcodebuild -runFirstLaunch"
fi
if ! /usr/bin/xcrun simctl list runtimes 2>/dev/null | grep -q '^iOS '; then
missing "No iOS simulator runtime is installed. Run: xcodebuild -downloadPlatform iOS"
elif ! /usr/bin/xcrun simctl list devices available 2>/dev/null | grep -q iPhone; then
missing "No iPhone simulator exists. Create one in Xcode > Window > Devices and Simulators"
fi
fi
if [ -n "$problems" ]; then
printf 'iOS simulator builds are disabled until this is fixed:\n%s' "$problems" >&2
exit 1
fi
'';
};
# macOS only: run on the iOS simulator when ios-check passes.
scripts.run-ios = lib.mkIf pkgs.stdenv.isDarwin { scripts.run-ios = lib.mkIf pkgs.stdenv.isDarwin {
exec = '' exec = ''
# devenv points DEVELOPER_DIR at the Nix SDK, which xcode-select would echo back. if ! ios-check; then
dev_dir="$(/usr/bin/env -u DEVELOPER_DIR /usr/bin/xcode-select -p 2>/dev/null)" echo "Skipping iOS."
[ -x "$dev_dir/usr/bin/simctl" ] || dev_dir=/Applications/Xcode.app/Contents/Developer
if ! DEVELOPER_DIR="$dev_dir" /usr/bin/xcrun simctl list devices available 2>/dev/null | grep -q iPhone; then
echo "No Xcode iOS simulator found, skipping iOS."
exit 0 exit 0
fi fi
${xcodeDevDir}
# devenv's Nix Apple SDK, xcrun and compiler wrappers break xcodebuild, so build in a clean env. # devenv's Nix Apple SDK, xcrun and compiler wrappers break xcodebuild, so build in a clean env.
exec /usr/bin/env -i HOME="$HOME" USER="$USER" TERM="$TERM" LANG=en_US.UTF-8 \ exec /usr/bin/env -i HOME="$HOME" USER="$USER" TERM="$TERM" LANG=en_US.UTF-8 \
DEVELOPER_DIR="$dev_dir" \ DEVELOPER_DIR="$dev_dir" \
@@ -110,7 +144,12 @@
after = ["devenv:processes:createavd@completed"]; after = ["devenv:processes:createavd@completed"];
}; };
expodev = { expodev = {
exec = "bunx expo run:android"; # Wait for the emulator to finish booting, otherwise expo tries to start a second copy of the AVD.
exec = ''
adb -e wait-for-device
until [ "$(adb -e shell getprop sys.boot_completed 2>/dev/null | tr -d '\r')" = 1 ]; do sleep 2; done
bunx expo run:android
'';
cwd = "./apps/mobile"; cwd = "./apps/mobile";
after= ["devenv:processes:emulator@started"]; after= ["devenv:processes:emulator@started"];
restart = { restart = {
+2 -1
View File
@@ -3,7 +3,8 @@
"private": true, "private": true,
"workspaces": [ "workspaces": [
"apps/*", "apps/*",
"packages/*" "packages/*",
"scripts"
], ],
"scripts": { "scripts": {
"dev": "bun run --filter '*' dev", "dev": "bun run --filter '*' dev",
+1
View File
@@ -30,6 +30,7 @@ func RunDbMigrations() error {
strconv.Itoa(conf.Database.Port), strconv.Itoa(conf.Database.Port),
"/", "/",
conf.Database.Name, conf.Database.Name,
"?sslmode=disable",
}, "")) }, ""))
if err != nil { if err != nil {
return err return err
+27 -24
View File
@@ -1,34 +1,37 @@
module <@var(context.project.goprefix)>/<@var(context.project.name)> module <@var(context.project.goprefix)>/<@var(context.project.name)>
go 1.25.7 go 1.26.0
require ( require (
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.9-20250912141014-52f32327d4b0.1 // indirect connectrpc.com/connect v1.21.0
buf.build/go/protovalidate v1.0.0 // indirect connectrpc.com/cors v0.1.0
cel.dev/expr v0.24.0 // indirect connectrpc.com/validate v0.7.0
connectrpc.com/connect v1.19.1 // indirect github.com/adrg/xdg v0.5.3
connectrpc.com/cors v0.1.0 // indirect github.com/amacneil/dbmate/v2 v2.36.0
connectrpc.com/validate v0.6.0 // indirect github.com/jackc/pgx/v5 v5.11.0
github.com/adrg/xdg v0.5.3 // indirect github.com/pelletier/go-toml v1.9.5
github.com/amacneil/dbmate/v2 v2.32.0 // indirect github.com/rs/cors v1.11.1
github.com/spf13/cobra v1.10.2
google.golang.org/protobuf v1.36.12
)
require (
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.12-20260825204119-511051f7f437.2 // indirect
buf.build/go/protovalidate v1.4.0 // indirect
cel.dev/cel-go v0.32.0 // indirect
cel.dev/expr v0.25.3 // indirect
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
github.com/google/cel-go v0.26.1 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/pgx/v5 v5.9.1 // indirect github.com/jackc/puddle/v2 v2.2.3 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/lib/pq v1.12.3 // indirect
github.com/lib/pq v1.12.0 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/rs/cors v1.11.1 // indirect
github.com/spf13/cobra v1.10.2 // indirect
github.com/spf13/pflag v1.0.10 // indirect github.com/spf13/pflag v1.0.10 // indirect
github.com/stoewer/go-strcase v1.3.1 // indirect go.yaml.in/yaml/v3 v3.0.5 // indirect
golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 // indirect golang.org/x/exp v0.0.0-20261005173118-76772065c9b0 // indirect
golang.org/x/sync v0.20.0 // indirect golang.org/x/sync v0.23.0 // indirect
golang.org/x/sys v0.42.0 // indirect golang.org/x/sys v0.48.0 // indirect
golang.org/x/text v0.35.0 // indirect golang.org/x/text v0.42.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20261005182115-fad411399dd8 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20261005182115-fad411399dd8 // indirect
google.golang.org/protobuf v1.36.11 // indirect
) )
+52 -48
View File
@@ -1,41 +1,52 @@
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.9-20250912141014-52f32327d4b0.1 h1:DQLS/rRxLHuugVzjJU5AvOwD57pdFl9he/0O7e5P294= buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.12-20260825204119-511051f7f437.2 h1:NbnlmV26O7oZ1iM5tsCI+GEx+3ZSdrhvnKQ/eWSrLiY=
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.9-20250912141014-52f32327d4b0.1/go.mod h1:aY3zbkNan5F+cGm9lITDP6oxJIwu0dn9KjJuJjWaHkg= buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.12-20260825204119-511051f7f437.2/go.mod h1:TCt1lluMFnctISJXvkIQ4x3ABrPuUKCWKyjKdkJNBpw=
buf.build/go/protovalidate v1.0.0 h1:IAG1etULddAy93fiBsFVhpj7es5zL53AfB/79CVGtyY= buf.build/go/protovalidate v1.4.0 h1:UjLrYbt5VX7+TMOs2+pG5FhZhIG1mSfK4EIopbb4LcM=
buf.build/go/protovalidate v1.0.0/go.mod h1:KQmEUrcQuC99hAw+juzOEAmILScQiKBP1Oc36vvCLW8= buf.build/go/protovalidate v1.4.0/go.mod h1:8vJfzNT6NIG2qm3uFsJDXMlRmG+bQJzbcIn1Aa0vPGs=
cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= cel.dev/cel-go v0.32.0 h1:irvpFKr5EuGPyxeME03ERh0rii1TX+BDAnB9eL3IvNk=
cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= cel.dev/cel-go v0.32.0/go.mod h1:DnVip7tpJSsgZymwfT+m1tnEVy3ivAjSMXPx12YrMkU=
connectrpc.com/connect v1.19.1 h1:R5M57z05+90EfEvCY1b7hBxDVOUl45PrtXtAV2fOC14= cel.dev/expr v0.25.3 h1:A2jO8jwOugrrovveCWfj0KEZOfqiLgAcwjpHPhzIGw0=
connectrpc.com/connect v1.19.1/go.mod h1:tN20fjdGlewnSFeZxLKb0xwIZ6ozc3OQs2hTXy4du9w= cel.dev/expr v0.25.3/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4=
connectrpc.com/connect v1.21.0 h1:LhqSJt7jHf5NJBo9Jq/t/9FjcYAideif0mg+qe2jCUs=
connectrpc.com/connect v1.21.0/go.mod h1:A2ygJrukXwWy32vkCAAHNVguZrqZ+jeZ9rGRnGR4dN4=
connectrpc.com/cors v0.1.0 h1:f3gTXJyDZPrDIZCQ567jxfD9PAIpopHiRDnJRt3QuOQ= connectrpc.com/cors v0.1.0 h1:f3gTXJyDZPrDIZCQ567jxfD9PAIpopHiRDnJRt3QuOQ=
connectrpc.com/cors v0.1.0/go.mod h1:v8SJZCPfHtGH1zsm+Ttajpozd4cYIUryl4dFB6QEpfg= connectrpc.com/cors v0.1.0/go.mod h1:v8SJZCPfHtGH1zsm+Ttajpozd4cYIUryl4dFB6QEpfg=
connectrpc.com/validate v0.6.0 h1:DcrgDKt2ZScrUs/d/mh9itD2yeEa0UbBBa+i0mwzx+4= connectrpc.com/validate v0.7.0 h1:E4wQiBymFW+GGWMwV4fO4yrvhIdzEVXlgRiZaSer/Hs=
connectrpc.com/validate v0.6.0/go.mod h1:ihrpI+8gVbLH1fvVWJL1I3j0CfWnF8P/90LsmluRiZs= connectrpc.com/validate v0.7.0/go.mod h1:BD3Onoa126tmoI3YG13UGFjBylgkd5LJ5whrAwi/wgg=
filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo=
filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc=
github.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78= github.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78=
github.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ= github.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ=
github.com/amacneil/dbmate/v2 v2.32.0 h1:DJWt+NRWlphTv1HXWWcAU7gsJKm/Ov8/+8k6yqLz8vA= github.com/amacneil/dbmate/v2 v2.36.0 h1:oWxpNxkPSJ57UNaP9x/Icj/Kw12QNiWVzNnBLWkHcLE=
github.com/amacneil/dbmate/v2 v2.32.0/go.mod h1:Kwax92bT+ZgqIXll9M+0QGuHVuu7O7AhsE+5p6PTqDc= github.com/amacneil/dbmate/v2 v2.36.0/go.mod h1:9B5Xs1OZ3kJUF739cgWhRDE4qrXs5hoRmTrgnvrpJH8=
github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ= github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=
github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
github.com/brianvoe/gofakeit/v6 v6.28.0 h1:Xib46XXuQfmlLS2EXRuJpqcw8St6qSZz75OUo0tgAW4=
github.com/brianvoe/gofakeit/v6 v6.28.0/go.mod h1:Xj58BMSnFqcn/fAQeSK+/PLtC5kSb7FJIq4JyGa8vEs=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo=
github.com/google/cel-go v0.26.1 h1:iPbVVEdkhTX++hpe3lzSk7D3G3QSYqLGoHOcEio+UXQ= github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
github.com/google/cel-go v0.26.1/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.9.1 h1:uwrxJXBnx76nyISkhr33kQLlUqjv7et7b9FjCen/tdc= github.com/jackc/pgx/v5 v5.11.0 h1:IzBBtyK9AHqf98cctWFifYSci2hgQR/cd56wB4p+ogg=
github.com/jackc/pgx/v5 v5.9.1/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4= github.com/jackc/pgx/v5 v5.11.0/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4=
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jackc/puddle/v2 v2.2.3 h1:f8HoREISb3l5eO9coPgK7U3hKLhWGokOFVcThl5jrao=
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jackc/puddle/v2 v2.2.3/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/lib/pq v1.12.0 h1:mC1zeiNamwKBecjHarAr26c/+d8V5w/u4J0I/yASbJo= github.com/lib/pq v1.12.3 h1:tTWxr2YLKwIvK90ZXEw8GP7UFHtcbTtty8zsI+YjrfQ=
github.com/lib/pq v1.12.0/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA= github.com/lib/pq v1.12.3/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA=
github.com/mattn/go-sqlite3 v1.14.42 h1:MigqEP4ZmHw3aIdIT7T+9TLa90Z6smwcthx+Azv4Cgo=
github.com/mattn/go-sqlite3 v1.14.42/go.mod h1:pjEuOr8IwzLJP2MfGeTb0A35jauH+C2kbHKBr7yXKVQ=
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rodaine/protogofakeit v0.1.1 h1:ZKouljuRM3A+TArppfBqnH8tGZHOwM/pjvtXe9DaXH8=
github.com/rodaine/protogofakeit v0.1.1/go.mod h1:pXn/AstBYMaSfc1/RqH3N82pBuxtWgejz1AlYpY1mI0=
github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA=
github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@@ -44,36 +55,29 @@ github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiT
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stoewer/go-strcase v1.3.1 h1:iS0MdW+kVTxgMoE1LAZyMiYJFKlOzLooE4MxjirtkAs=
github.com/stoewer/go-strcase v1.3.1/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04 h1:qXafrlZL1WsJW5OokjraLLRURHiw0OzKHD/RNdspp4w=
github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04/go.mod h1:FiwNQxz6hGoNFBC4nIx+CxZhI3nne5RmIOlT/MXcSD4=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 h1:jiDhWWeC7jfWqR9c/uplMOqJ0sbNlNWv0UkzE0vX1MA= go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw=
golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90/go.mod h1:xE1HEv6b+1SCZ5/uscMRjUBKtIxworgEcEi+/n9NQDQ= go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg=
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= golang.org/x/exp v0.0.0-20261005173118-76772065c9b0 h1:qUp3i6M39kccSm3OMMIE3tvs7YQWO9rFeCKdk1sSaFk=
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/exp v0.0.0-20261005173118-76772065c9b0/go.mod h1:SRjTzy5WcYqRRqquLUvHeeovSwLO0CZ3xcltZNO4Fck=
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk=
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0=
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo=
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og=
golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI=
golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E=
google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 h1:XzmzkmB14QhVhgnawEVsOn6OFsnpyxNPRY9QV01dNB0= google.golang.org/genproto/googleapis/api v0.0.0-20261005182115-fad411399dd8 h1:cFbkNigDInw+wVTXc+CyhUsoHGJCw0BR6mlNoRVfre0=
google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7 h1:41r6JMbpzBMen0R/4TZeeAmGXSJC7DftGINUodzTkPI= google.golang.org/genproto/googleapis/api v0.0.0-20261005182115-fad411399dd8/go.mod h1:QK6p7IgD7IZEZJBhhSUCib5X2vMOzlrGCGUw2XyVDh0=
google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:EIQZ5bFCfRQDV4MhRle7+OgjNtZ6P1PiZBgAKuxXu/Y= google.golang.org/genproto/googleapis/rpc v0.0.0-20261005182115-fad411399dd8 h1:0SXBqli5dnuCKMjI/X3FM226zEaEa0GUcSCJtN1vL2o=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7 h1:ndE4FoJqsIceKP2oYSnUZqhTdYufCYYkqwtFzfrhI7w= google.golang.org/genproto/googleapis/rpc v0.0.0-20261005182115-fad411399dd8/go.mod h1:OaIUM3+LpYcK2GXM4FTmhWoIq371Owdr+Cc7/BsYHHc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc=
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=