mirror of
https://github.com/foomo/sesamy-cli.git
synced 2025-10-16 12:35:36 +00:00
Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
61d671341c | ||
|
|
df04a14c25 | ||
|
|
c3a1a68c9b | ||
|
|
97ef3a7ce6 | ||
|
|
35d4393f4e | ||
|
|
fe98357ece | ||
|
|
3e6697a98d | ||
|
|
d5358405af | ||
|
|
27dff33e47 | ||
|
|
acf13a73b1 | ||
|
|
de67860229 | ||
|
|
f6539da3c0 | ||
|
|
53794ef0f8 | ||
|
|
a021b3eafd | ||
|
|
e2ce7e64fe | ||
|
|
539624ceb3 | ||
|
|
740d4981ea | ||
|
|
5fdd26d867 | ||
|
|
b1b71cc166 | ||
|
|
c6f5292df3 | ||
|
|
9df36edda0 | ||
|
|
3e03bc1226 |
2
.dockerignore
Normal file
2
.dockerignore
Normal file
@ -0,0 +1,2 @@
|
||||
sesamy
|
||||
dist
|
||||
9
.github/workflows/release.yml
vendored
9
.github/workflows/release.yml
vendored
@ -22,15 +22,22 @@ jobs:
|
||||
check-latest: true
|
||||
go-version-file: go.mod
|
||||
|
||||
- uses: docker/setup-qemu-action@v3
|
||||
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
|
||||
- id: app_token
|
||||
uses: tibdex/github-app-token@v2
|
||||
with:
|
||||
app_id: ${{ secrets.TOKEN_APP_ID }}
|
||||
private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }}
|
||||
|
||||
- name: Login to docker.io
|
||||
run: docker login -u ${{ secrets.DOCKERHUB_USERNAME }} -p ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- uses: goreleaser/goreleaser-action@v6
|
||||
with:
|
||||
version: latest
|
||||
version: '~> v2'
|
||||
args: release --clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.app_token.outputs.token }}
|
||||
|
||||
4
.github/workflows/test.yml
vendored
4
.github/workflows/test.yml
vendored
@ -7,6 +7,10 @@ on:
|
||||
merge_group:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
concurrency:
|
||||
group: "${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}"
|
||||
cancel-in-progress: true
|
||||
|
||||
9
.gitignore
vendored
9
.gitignore
vendored
@ -16,13 +16,18 @@
|
||||
## Editorconfig
|
||||
!.editorconfig
|
||||
|
||||
## Ownbrew
|
||||
!.ownbrew.yaml
|
||||
## Docker
|
||||
!.dockerignore
|
||||
|
||||
## Husky
|
||||
!.husky/
|
||||
!.husky.yaml
|
||||
|
||||
## Golang
|
||||
go.work
|
||||
go.work.sum
|
||||
!.golangci.yml
|
||||
!.goreleaser.yml
|
||||
|
||||
## Ownbrew
|
||||
!.ownbrew.yaml
|
||||
|
||||
@ -181,6 +181,8 @@ linters:
|
||||
disabled: true
|
||||
- name: indent-error-flow
|
||||
disabled: true
|
||||
- name: var-naming
|
||||
disabled: true
|
||||
testifylint:
|
||||
disable:
|
||||
- float-compare
|
||||
|
||||
@ -41,3 +41,74 @@ brews:
|
||||
description: "CLI utitlity to manage Server Side Tag Management"
|
||||
test: |
|
||||
system "#{bin}/sesamy --version"
|
||||
|
||||
dockers:
|
||||
- use: buildx
|
||||
goos: linux
|
||||
goarch: amd64
|
||||
dockerfile: Dockerfile
|
||||
image_templates:
|
||||
- '{{ if eq .Prerelease "" }}foomo/sesamy:latest-amd64{{ end }}'
|
||||
- 'foomo/sesamy:{{ .Version }}-amd64'
|
||||
- '{{ if eq .Prerelease "" }}foomo/sesamy:{{ .Major }}-amd64{{ end }}'
|
||||
- '{{ if eq .Prerelease "" }}foomo/sesamy:{{ .Major }}.{{ .Minor }}-amd64{{ end }}'
|
||||
build_flag_templates:
|
||||
- '--pull'
|
||||
# https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys
|
||||
- '--label=org.opencontainers.image.title={{.ProjectName}}'
|
||||
- '--label=org.opencontainers.image.description=CLI utility manage infrastructure as code with helm'
|
||||
- '--label=org.opencontainers.image.source={{.GitURL}}'
|
||||
- '--label=org.opencontainers.image.url={{.GitURL}}'
|
||||
- '--label=org.opencontainers.image.documentation={{.GitURL}}'
|
||||
- '--label=org.opencontainers.image.created={{.Date}}'
|
||||
- '--label=org.opencontainers.image.revision={{.FullCommit}}'
|
||||
- '--label=org.opencontainers.image.version={{.Version}}'
|
||||
- '--platform=linux/amd64'
|
||||
|
||||
- use: buildx
|
||||
goos: linux
|
||||
goarch: arm64
|
||||
dockerfile: Dockerfile
|
||||
image_templates:
|
||||
- '{{ if eq .Prerelease "" }}foomo/sesamy:latest-arm64{{ end }}'
|
||||
- 'foomo/sesamy:{{ .Version }}-arm64'
|
||||
- '{{ if eq .Prerelease "" }}foomo/sesamy:{{ .Major }}-arm64{{ end }}'
|
||||
- '{{ if eq .Prerelease "" }}foomo/sesamy:{{ .Major }}.{{ .Minor }}-arm64{{ end }}'
|
||||
build_flag_templates:
|
||||
- '--pull'
|
||||
# https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys
|
||||
- '--label=org.opencontainers.image.title={{.ProjectName}}'
|
||||
- '--label=org.opencontainers.image.description=CLI utility manage infrastructure as code with helm'
|
||||
- '--label=org.opencontainers.image.source={{.GitURL}}'
|
||||
- '--label=org.opencontainers.image.url={{.GitURL}}'
|
||||
- '--label=org.opencontainers.image.documentation={{.GitURL}}'
|
||||
- '--label=org.opencontainers.image.created={{.Date}}'
|
||||
- '--label=org.opencontainers.image.revision={{.FullCommit}}'
|
||||
- '--label=org.opencontainers.image.version={{.Version}}'
|
||||
- '--platform=linux/arm64'
|
||||
|
||||
docker_manifests:
|
||||
# basic
|
||||
- name_template: 'foomo/sesamy:latest'
|
||||
image_templates:
|
||||
- 'foomo/sesamy:latest-amd64'
|
||||
- 'foomo/sesamy:latest-arm64'
|
||||
skip_push: auto
|
||||
|
||||
- name_template: 'foomo/sesamy:{{ .Version }}'
|
||||
image_templates:
|
||||
- 'foomo/sesamy:{{ .Version }}-amd64'
|
||||
- 'foomo/sesamy:{{ .Version }}-arm64'
|
||||
skip_push: auto
|
||||
|
||||
- name_template: 'foomo/sesamy:{{ .Major }}'
|
||||
image_templates:
|
||||
- 'foomo/sesamy:{{ .Major }}-amd64'
|
||||
- 'foomo/sesamy:{{ .Major }}-arm64'
|
||||
skip_push: auto
|
||||
|
||||
- name_template: 'foomo/sesamy:{{ .Major }}.{{ .Minor }}'
|
||||
image_templates:
|
||||
- 'foomo/sesamy:{{ .Major }}.{{ .Minor }}-amd64'
|
||||
- 'foomo/sesamy:{{ .Major }}.{{ .Minor }}-arm64'
|
||||
skip_push: auto
|
||||
|
||||
12
Dockerfile
Normal file
12
Dockerfile
Normal file
@ -0,0 +1,12 @@
|
||||
FROM alpine:latest
|
||||
|
||||
RUN apk --no-cache add ca-certificates
|
||||
|
||||
RUN adduser -D -u 1001 -g 1001 sesamy
|
||||
|
||||
COPY sesamy /usr/bin/
|
||||
|
||||
USER sesamy
|
||||
WORKDIR /home/sesamy
|
||||
|
||||
ENTRYPOINT ["sesamy"]
|
||||
58
Makefile
58
Makefile
@ -17,12 +17,7 @@ PATH:=bin:$(PATH)
|
||||
fi
|
||||
@git config core.hooksPath .husky
|
||||
|
||||
## === Tasks ===
|
||||
|
||||
.PHONY: brew
|
||||
## Install project binaries
|
||||
brew:
|
||||
@ownbrew install
|
||||
### Tasks
|
||||
|
||||
.PHONY: doc
|
||||
## Open go docs
|
||||
@ -59,11 +54,13 @@ outdated:
|
||||
## Build binary
|
||||
build:
|
||||
@mkdir -p bin
|
||||
@echo "building: bin/sesamy"
|
||||
@go build -tags=safe -o bin/sesamy main.go
|
||||
|
||||
.PHONY: install
|
||||
## Install binary
|
||||
install:
|
||||
@echo "installing: ${GOPATH}/bin/sesamy"
|
||||
@go build -tags=safe -o ${GOPATH}/bin/sesamy main.go
|
||||
|
||||
.PHONY: install.debug
|
||||
@ -71,36 +68,27 @@ install:
|
||||
install.debug:
|
||||
@go build -tags=safe -gclags="all=-N -l" -o ${GOPATH}/bin/sesamy main.go
|
||||
|
||||
## === Utils ===
|
||||
### Utils
|
||||
|
||||
.PHONY: brew
|
||||
## Install project binaries
|
||||
brew:
|
||||
@ownbrew install
|
||||
|
||||
.PHONY: help
|
||||
## Show help text
|
||||
help:
|
||||
@echo "\033[1;36mSesamy CLI\033[0m"
|
||||
@awk '{ \
|
||||
if ($$0 ~ /^.PHONY: [a-zA-Z\-\_0-9]+$$/) { \
|
||||
helpCommand = substr($$0, index($$0, ":") + 2); \
|
||||
if (helpMessage) { \
|
||||
printf "\033[36m%-23s\033[0m %s\n", \
|
||||
helpCommand, helpMessage; \
|
||||
helpMessage = ""; \
|
||||
} \
|
||||
} else if ($$0 ~ /^[a-zA-Z\-\_0-9.]+:/) { \
|
||||
helpCommand = substr($$0, 0, index($$0, ":")); \
|
||||
if (helpMessage) { \
|
||||
printf "\033[36m%-23s\033[0m %s\n", \
|
||||
helpCommand, helpMessage"\n"; \
|
||||
helpMessage = ""; \
|
||||
} \
|
||||
} else if ($$0 ~ /^##/) { \
|
||||
if (helpMessage) { \
|
||||
helpMessage = helpMessage"\n "substr($$0, 3); \
|
||||
} else { \
|
||||
helpMessage = substr($$0, 3); \
|
||||
} \
|
||||
} else { \
|
||||
if (helpMessage) { \
|
||||
print "\n "helpMessage"\n" \
|
||||
} \
|
||||
helpMessage = ""; \
|
||||
} \
|
||||
}' \
|
||||
$(MAKEFILE_LIST)
|
||||
if($$0 ~ /^### /){ \
|
||||
if(help) printf "\033[36m%-23s\033[0m %s\n\n", cmd, help; help=""; \
|
||||
printf "\n\033[1;36m%s\033[0m\n", substr($$0,5); \
|
||||
} else if($$0 ~ /^[a-zA-Z0-9._-]+:/){ \
|
||||
cmd = substr($$0, 1, index($$0, ":")-1); \
|
||||
if(help) printf " \033[36m%-23s\033[0m %s\n", cmd, help; help=""; \
|
||||
} else if($$0 ~ /^##/){ \
|
||||
help = help ? help "\n " substr($$0,3) : substr($$0,3); \
|
||||
} else if(help){ \
|
||||
print "\n " help "\n"; help=""; \
|
||||
} \
|
||||
}' $(MAKEFILE_LIST)
|
||||
|
||||
33
README.md
33
README.md
@ -280,6 +280,8 @@ conversionLinker:
|
||||
enabled: true
|
||||
# Consent mode name
|
||||
mode: ad_storage
|
||||
# Accept incoming linker parameters
|
||||
enableLinkerParams: true
|
||||
|
||||
# --- Umami settings
|
||||
umami:
|
||||
@ -491,6 +493,37 @@ mixpanel:
|
||||
- ViewItem
|
||||
- ViewItemList
|
||||
|
||||
# --- Pinterest
|
||||
pinterest:
|
||||
# Enable provider
|
||||
enabled: true
|
||||
# Pinterest advertiser id
|
||||
advertiserId: ''
|
||||
# Pinterest API access token
|
||||
apiAccessToken: ''
|
||||
# Enable test mode
|
||||
testModeEnabled: false
|
||||
# Google Consent settings
|
||||
googleConsent:
|
||||
# Enable consent mode
|
||||
enabled: true
|
||||
# Consent mode name
|
||||
mode: analytics_storage
|
||||
# Google Tag Manager server container settings
|
||||
serverContainer:
|
||||
# Directory containing the go.mod file
|
||||
directory: .
|
||||
# Contemplate package config for generated events
|
||||
packages:
|
||||
- path: 'github.com/foomo/sesamy-go/pkg/event'
|
||||
types:
|
||||
- AddToCart
|
||||
- GenerateLead
|
||||
- PageView
|
||||
- Purchase
|
||||
- Search
|
||||
- SignUp
|
||||
- ViewItemList
|
||||
```
|
||||
|
||||
## Caveats
|
||||
|
||||
23
cmd/diff.go
Normal file
23
cmd/diff.go
Normal file
@ -0,0 +1,23 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
|
||||
"github.com/foomo/sesamy-cli/cmd/diff"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// NewDiff represents the diff command
|
||||
func NewDiff(l *slog.Logger) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "diff",
|
||||
Short: "Print Google Tag Manager container status diff",
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
diff.NewWeb(l),
|
||||
diff.NewServer(l),
|
||||
)
|
||||
|
||||
return cmd
|
||||
}
|
||||
400
cmd/diff/diff.go
Normal file
400
cmd/diff/diff.go
Normal file
@ -0,0 +1,400 @@
|
||||
package diff
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"log/slog"
|
||||
"strings"
|
||||
|
||||
"github.com/foomo/sesamy-cli/pkg/tagmanager"
|
||||
"github.com/itchyny/json2yaml"
|
||||
"github.com/sters/yaml-diff/yamldiff"
|
||||
)
|
||||
|
||||
const ChangeStatusDeleted = "deleted"
|
||||
|
||||
func diff(ctx context.Context, l *slog.Logger, tm *tagmanager.TagManager) (string, error) {
|
||||
l.Info("└ ⬇︎ Loading status")
|
||||
s, err := tm.Service().Accounts.Containers.Workspaces.GetStatus(tm.WorkspacePath()).Context(ctx).Do()
|
||||
if err != nil {
|
||||
return "", err
|
||||
} else if len(s.WorkspaceChange) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
l.Info("└ ⬇︎ Loading live version")
|
||||
live, err := tm.Service().Accounts.Containers.Versions.Live(tm.ContainerPath()).Do()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var res []string
|
||||
for _, entity := range s.WorkspaceChange {
|
||||
switch {
|
||||
case entity.Tag != nil:
|
||||
res = append(res, " # Tag: "+entity.Tag.Name+" ("+entity.ChangeStatus+")\n")
|
||||
|
||||
// unset props
|
||||
entity.Tag.Path = ""
|
||||
entity.Tag.Fingerprint = ""
|
||||
entity.Tag.WorkspaceId = ""
|
||||
entity.Tag.TagManagerUrl = ""
|
||||
|
||||
var changed string
|
||||
if entity.ChangeStatus != ChangeStatusDeleted {
|
||||
changed, err = ToYalm(entity.Tag)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
var original string
|
||||
for _, value := range live.Tag {
|
||||
if value.Name == entity.Tag.Name {
|
||||
// unset props
|
||||
value.Fingerprint = ""
|
||||
|
||||
original, err = ToYalm(value)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
d, err := ToDiff(original, changed)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
res = append(res, d...)
|
||||
case entity.Folder != nil:
|
||||
res = append(res, " # Folder: "+entity.Folder.Name+" ("+entity.ChangeStatus+")")
|
||||
|
||||
// unset props
|
||||
entity.Folder.Path = ""
|
||||
entity.Folder.Fingerprint = ""
|
||||
entity.Folder.WorkspaceId = ""
|
||||
entity.Folder.TagManagerUrl = ""
|
||||
|
||||
var changed string
|
||||
if entity.ChangeStatus != ChangeStatusDeleted {
|
||||
changed, err = ToYalm(entity.Folder)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
var original string
|
||||
for _, value := range live.Folder {
|
||||
if value.Name == entity.Folder.Name {
|
||||
// unset props
|
||||
value.Fingerprint = ""
|
||||
|
||||
original, err = ToYalm(value)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
d, err := ToDiff(original, changed)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
res = append(res, d...)
|
||||
case entity.Trigger != nil:
|
||||
res = append(res, " # Trigger: "+entity.Trigger.Name+" ("+entity.ChangeStatus+")")
|
||||
|
||||
// unset props
|
||||
entity.Trigger.Path = ""
|
||||
entity.Trigger.Fingerprint = ""
|
||||
entity.Trigger.WorkspaceId = ""
|
||||
entity.Trigger.TagManagerUrl = ""
|
||||
|
||||
var changed string
|
||||
if entity.ChangeStatus != ChangeStatusDeleted {
|
||||
changed, err = ToYalm(entity.Trigger)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
var original string
|
||||
for _, value := range live.Trigger {
|
||||
if value.Name == entity.Trigger.Name {
|
||||
// unset props
|
||||
value.Fingerprint = ""
|
||||
|
||||
original, err = ToYalm(value)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
d, err := ToDiff(original, changed)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
res = append(res, d...)
|
||||
case entity.Variable != nil:
|
||||
res = append(res, " # Variable: "+entity.Variable.Name+" ("+entity.ChangeStatus+")")
|
||||
|
||||
// unset props
|
||||
entity.Variable.Path = ""
|
||||
entity.Variable.Fingerprint = ""
|
||||
entity.Variable.WorkspaceId = ""
|
||||
entity.Variable.TagManagerUrl = ""
|
||||
|
||||
var changed string
|
||||
if entity.ChangeStatus != ChangeStatusDeleted {
|
||||
changed, err = ToYalm(entity.Variable)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
var original string
|
||||
for _, value := range live.Variable {
|
||||
if value.Name == entity.Variable.Name {
|
||||
// unset props
|
||||
value.Fingerprint = ""
|
||||
|
||||
original, err = ToYalm(value)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
d, err := ToDiff(original, changed)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
res = append(res, d...)
|
||||
case entity.Client != nil:
|
||||
res = append(res, " # Client: "+entity.Client.Name+" ("+entity.ChangeStatus+")")
|
||||
|
||||
// unset props
|
||||
entity.Client.Path = ""
|
||||
entity.Client.Fingerprint = ""
|
||||
entity.Client.WorkspaceId = ""
|
||||
entity.Client.TagManagerUrl = ""
|
||||
|
||||
var changed string
|
||||
if entity.ChangeStatus != ChangeStatusDeleted {
|
||||
changed, err = ToYalm(entity.Client)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
var original string
|
||||
for _, value := range live.Client {
|
||||
if value.Name == entity.Client.Name {
|
||||
// unset props
|
||||
value.Fingerprint = ""
|
||||
|
||||
original, err = ToYalm(value)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
d, err := ToDiff(original, changed)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
res = append(res, d...)
|
||||
case entity.GtagConfig != nil:
|
||||
res = append(res, " # GtagConfig: "+entity.GtagConfig.AccountId+" ("+entity.ChangeStatus+")")
|
||||
|
||||
// unset props
|
||||
entity.GtagConfig.Path = ""
|
||||
entity.GtagConfig.Fingerprint = ""
|
||||
entity.GtagConfig.WorkspaceId = ""
|
||||
entity.GtagConfig.TagManagerUrl = ""
|
||||
|
||||
var changed string
|
||||
if entity.ChangeStatus != ChangeStatusDeleted {
|
||||
changed, err = ToYalm(entity.GtagConfig)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
var original string
|
||||
for _, value := range live.GtagConfig {
|
||||
if value.AccountId == entity.GtagConfig.AccountId {
|
||||
// unset props
|
||||
value.Fingerprint = ""
|
||||
|
||||
original, err = ToYalm(value)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
d, err := ToDiff(original, changed)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
res = append(res, d...)
|
||||
case entity.BuiltInVariable != nil:
|
||||
res = append(res, " # BuiltInVariable: "+entity.BuiltInVariable.Name+" ("+entity.ChangeStatus+")")
|
||||
|
||||
// unset props
|
||||
entity.BuiltInVariable.Path = ""
|
||||
entity.BuiltInVariable.WorkspaceId = ""
|
||||
|
||||
var changed string
|
||||
if entity.ChangeStatus != ChangeStatusDeleted {
|
||||
changed, err = ToYalm(entity.BuiltInVariable)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
var original string
|
||||
for _, value := range live.BuiltInVariable {
|
||||
if value.Name == entity.BuiltInVariable.Name {
|
||||
original, err = ToYalm(value)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
d, err := ToDiff(original, changed)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
res = append(res, d...)
|
||||
case entity.CustomTemplate != nil:
|
||||
res = append(res, " # CustomTemplate: "+entity.CustomTemplate.Name+" ("+entity.ChangeStatus+")")
|
||||
|
||||
// unset props
|
||||
entity.CustomTemplate.Path = ""
|
||||
entity.CustomTemplate.Fingerprint = ""
|
||||
entity.CustomTemplate.WorkspaceId = ""
|
||||
entity.CustomTemplate.TagManagerUrl = ""
|
||||
|
||||
var changed string
|
||||
if entity.ChangeStatus != ChangeStatusDeleted {
|
||||
changed, err = ToYalm(entity.CustomTemplate)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
var original string
|
||||
for _, value := range live.CustomTemplate {
|
||||
if value.Name == entity.CustomTemplate.Name {
|
||||
// unset props
|
||||
value.Fingerprint = ""
|
||||
|
||||
original, err = ToYalm(value)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
d, err := ToDiff(original, changed)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
res = append(res, d...)
|
||||
case entity.Transformation != nil:
|
||||
res = append(res, " # Transformation: "+entity.Transformation.Name+" ("+entity.ChangeStatus+")")
|
||||
|
||||
// unset props
|
||||
entity.Transformation.Path = ""
|
||||
entity.Transformation.Fingerprint = ""
|
||||
entity.Transformation.WorkspaceId = ""
|
||||
entity.Transformation.TagManagerUrl = ""
|
||||
|
||||
var changed string
|
||||
if entity.ChangeStatus != ChangeStatusDeleted {
|
||||
changed, err = ToYalm(entity.Transformation)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
var original string
|
||||
for _, value := range live.Transformation {
|
||||
if value.Name == entity.Transformation.Name {
|
||||
// unset props
|
||||
value.Fingerprint = ""
|
||||
|
||||
original, err = ToYalm(value)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
d, err := ToDiff(original, changed)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
res = append(res, d...)
|
||||
default:
|
||||
l.Warn("unknown entity type", "entity", entity)
|
||||
}
|
||||
}
|
||||
return strings.Join(res, " ---\n"), nil
|
||||
}
|
||||
|
||||
type Marshelable interface {
|
||||
MarshalJSON() ([]byte, error)
|
||||
}
|
||||
|
||||
func ToDiff(original, changed string) ([]string, error) {
|
||||
yamls1, err := yamldiff.Load(original)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
yamls2, err := yamldiff.Load(changed)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var ret []string
|
||||
for _, d := range yamldiff.Do(yamls1, yamls2) {
|
||||
if value := d.Dump(); len(value) > 4 {
|
||||
ret = append(ret, value)
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func ToYalm(m Marshelable) (string, error) {
|
||||
if m == nil {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
out, err := m.MarshalJSON()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var ret bytes.Buffer
|
||||
if err := json2yaml.Convert(&ret, bytes.NewBuffer(out)); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return ret.String(), nil
|
||||
}
|
||||
68
cmd/diff/server.go
Normal file
68
cmd/diff/server.go
Normal file
@ -0,0 +1,68 @@
|
||||
package diff
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
pkgcmd "github.com/foomo/sesamy-cli/pkg/cmd"
|
||||
"github.com/foomo/sesamy-cli/pkg/tagmanager"
|
||||
"github.com/foomo/sesamy-cli/pkg/utils"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// NewServer represents the server command
|
||||
func NewServer(l *slog.Logger) *cobra.Command {
|
||||
c := viper.New()
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "server",
|
||||
Short: "Print Google Tag Manager Server Container status diff",
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
l.Info("☕ Retrieving Server Container status")
|
||||
|
||||
cfg, err := pkgcmd.ReadConfig(l, c, cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tm, err := tagmanager.New(
|
||||
cmd.Context(),
|
||||
l,
|
||||
cfg.GoogleTagManager.AccountID,
|
||||
cfg.GoogleTagManager.ServerContainer,
|
||||
tagmanager.WithRequestQuota(cfg.GoogleAPI.RequestQuota),
|
||||
tagmanager.WithClientOptions(cfg.GoogleAPI.GetClientOption()),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tm.EnsureWorkspaceID(cmd.Context()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
out, err := diff(cmd.Context(), l, tm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !c.GetBool("raw") {
|
||||
out = utils.Highlight(out)
|
||||
}
|
||||
_, err = fmt.Println(out)
|
||||
return err
|
||||
},
|
||||
}
|
||||
|
||||
flags := cmd.Flags()
|
||||
|
||||
flags.Bool("raw", false, "print raw output")
|
||||
_ = c.BindPFlag("raw", flags.Lookup("raw"))
|
||||
|
||||
flags.StringSliceP("config", "c", []string{"sesamy.yaml"}, "config files (default is sesamy.yaml)")
|
||||
_ = c.BindPFlag("config", flags.Lookup("config"))
|
||||
|
||||
return cmd
|
||||
}
|
||||
68
cmd/diff/web.go
Normal file
68
cmd/diff/web.go
Normal file
@ -0,0 +1,68 @@
|
||||
package diff
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
pkgcmd "github.com/foomo/sesamy-cli/pkg/cmd"
|
||||
"github.com/foomo/sesamy-cli/pkg/tagmanager"
|
||||
"github.com/foomo/sesamy-cli/pkg/utils"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// NewWeb represents the web command
|
||||
func NewWeb(l *slog.Logger) *cobra.Command {
|
||||
c := viper.New()
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "web",
|
||||
Short: "Print Google Tag Manager Web Container status diff",
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
l.Info("☕ Retrieving Web Container status")
|
||||
|
||||
cfg, err := pkgcmd.ReadConfig(l, c, cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tm, err := tagmanager.New(
|
||||
cmd.Context(),
|
||||
l,
|
||||
cfg.GoogleTagManager.AccountID,
|
||||
cfg.GoogleTagManager.WebContainer,
|
||||
tagmanager.WithRequestQuota(cfg.GoogleAPI.RequestQuota),
|
||||
tagmanager.WithClientOptions(cfg.GoogleAPI.GetClientOption()),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tm.EnsureWorkspaceID(cmd.Context()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
out, err := diff(cmd.Context(), l, tm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !c.GetBool("raw") {
|
||||
out = utils.Highlight(out)
|
||||
}
|
||||
_, err = fmt.Println(out)
|
||||
return err
|
||||
},
|
||||
}
|
||||
|
||||
flags := cmd.Flags()
|
||||
|
||||
flags.Bool("raw", false, "print raw output")
|
||||
_ = c.BindPFlag("raw", flags.Lookup("raw"))
|
||||
|
||||
flags.StringSliceP("config", "c", []string{"sesamy.yaml"}, "config files (default is sesamy.yaml)")
|
||||
_ = c.BindPFlag("config", flags.Lookup("config"))
|
||||
|
||||
return cmd
|
||||
}
|
||||
@ -5,42 +5,34 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/chroma/quick"
|
||||
"github.com/foomo/sesamy-cli/pkg/tagmanager"
|
||||
"github.com/itchyny/json2yaml"
|
||||
)
|
||||
|
||||
func dump(i interface{ MarshalJSON() ([]byte, error) }, err error) error {
|
||||
func dump(i interface{ MarshalJSON() ([]byte, error) }, err error) (string, error) {
|
||||
if err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
out, err := i.MarshalJSON()
|
||||
if err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
// if err := json.Indent(ret, out, "", " "); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// fmt.Println(ret.String())
|
||||
|
||||
var output strings.Builder
|
||||
if err := json2yaml.Convert(&output, bytes.NewBuffer(out)); err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
// fmt.Print(output.String())
|
||||
return quick.Highlight(os.Stdout, output.String(), "yaml", "terminal", "monokai")
|
||||
return output.String(), nil
|
||||
}
|
||||
|
||||
func list(ctx context.Context, l *slog.Logger, tm *tagmanager.TagManager, resource string) error {
|
||||
func list(ctx context.Context, l *slog.Logger, tm *tagmanager.TagManager, resource string) (string, error) {
|
||||
switch resource {
|
||||
case "environments":
|
||||
return dump(tm.Service().Accounts.Containers.Environments.List(tm.ContainerPath()).Context(ctx).Do())
|
||||
case "workspaces":
|
||||
return dump(tm.Service().Accounts.Containers.Workspaces.List(tm.ContainerPath()).Context(ctx).Do())
|
||||
case "status":
|
||||
return dump(tm.Service().Accounts.Containers.Workspaces.GetStatus(tm.WorkspacePath()).Context(ctx).Do())
|
||||
case "clients":
|
||||
return dump(tm.Service().Accounts.Containers.Workspaces.Clients.List(tm.WorkspacePath()).Context(ctx).Do())
|
||||
case "tags":
|
||||
@ -56,13 +48,14 @@ func list(ctx context.Context, l *slog.Logger, tm *tagmanager.TagManager, resour
|
||||
case "templates-data":
|
||||
r, err := tm.Service().Accounts.Containers.Workspaces.Templates.List(tm.WorkspacePath()).Context(ctx).Do()
|
||||
if err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
var ret strings.Builder
|
||||
for _, template := range r.Template {
|
||||
l.Info("---- Template data: " + template.Name + " ----------------------")
|
||||
fmt.Println(template.TemplateData)
|
||||
ret.WriteString("---- Template data: " + template.Name + " ----------------------\n")
|
||||
ret.WriteString(template.TemplateData + "\n")
|
||||
}
|
||||
return nil
|
||||
return ret.String(), nil
|
||||
case "gtag-config":
|
||||
return dump(tm.Service().Accounts.Containers.Workspaces.GtagConfig.List(tm.WorkspacePath()).Context(ctx).Do())
|
||||
case "triggers":
|
||||
@ -72,6 +65,6 @@ func list(ctx context.Context, l *slog.Logger, tm *tagmanager.TagManager, resour
|
||||
case "zones":
|
||||
return dump(tm.Service().Accounts.Containers.Workspaces.Zones.List(tm.WorkspacePath()).Context(ctx).Do())
|
||||
default:
|
||||
return fmt.Errorf("unknown resource %s", resource)
|
||||
return "", fmt.Errorf("unknown resource %s", resource)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
package list
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
pkgcmd "github.com/foomo/sesamy-cli/pkg/cmd"
|
||||
"github.com/foomo/sesamy-cli/pkg/tagmanager"
|
||||
"github.com/foomo/sesamy-cli/pkg/utils"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
@ -58,12 +60,24 @@ func NewServer(l *slog.Logger) *cobra.Command {
|
||||
return err
|
||||
}
|
||||
|
||||
return list(cmd.Context(), l, tm, resource)
|
||||
out, err := list(cmd.Context(), l, tm, resource)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !c.GetBool("raw") {
|
||||
out = utils.Highlight(out)
|
||||
}
|
||||
_, err = fmt.Println(out)
|
||||
return err
|
||||
},
|
||||
}
|
||||
|
||||
flags := cmd.Flags()
|
||||
|
||||
flags.Bool("raw", false, "print raw output")
|
||||
_ = c.BindPFlag("raw", flags.Lookup("raw"))
|
||||
|
||||
flags.StringSliceP("config", "c", []string{"sesamy.yaml"}, "config files (default is sesamy.yaml)")
|
||||
_ = c.BindPFlag("config", flags.Lookup("config"))
|
||||
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
package list
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
pkgcmd "github.com/foomo/sesamy-cli/pkg/cmd"
|
||||
"github.com/foomo/sesamy-cli/pkg/tagmanager"
|
||||
"github.com/foomo/sesamy-cli/pkg/utils"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
@ -57,12 +59,24 @@ func NewWeb(l *slog.Logger) *cobra.Command {
|
||||
return err
|
||||
}
|
||||
|
||||
return list(cmd.Context(), l, tm, resource)
|
||||
out, err := list(cmd.Context(), l, tm, resource)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !c.GetBool("raw") {
|
||||
out = utils.Highlight(out)
|
||||
}
|
||||
_, err = fmt.Println(out)
|
||||
return err
|
||||
},
|
||||
}
|
||||
|
||||
flags := cmd.Flags()
|
||||
|
||||
flags.Bool("raw", false, "print raw output")
|
||||
_ = c.BindPFlag("raw", flags.Lookup("raw"))
|
||||
|
||||
flags.StringSliceP("config", "c", []string{"sesamy.yaml"}, "config files (default is sesamy.yaml)")
|
||||
_ = c.BindPFlag("config", flags.Lookup("config"))
|
||||
|
||||
|
||||
71
cmd/open.go
Normal file
71
cmd/open.go
Normal file
@ -0,0 +1,71 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
pkgcmd "github.com/foomo/sesamy-cli/pkg/cmd"
|
||||
"github.com/pkg/browser"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// NewOpen represents the open command
|
||||
func NewOpen(l *slog.Logger) *cobra.Command {
|
||||
c := viper.New()
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "open",
|
||||
Short: "Open links in the browser",
|
||||
Args: cobra.OnlyValidArgs,
|
||||
ValidArgs: []cobra.Completion{
|
||||
"ga",
|
||||
"gtm-web",
|
||||
"gtm-server",
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
cfg, err := pkgcmd.ReadConfig(l, c, cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var url string
|
||||
switch args[0] {
|
||||
case "ga":
|
||||
if cfg.GoogleAnalytics.PropertyID == "" {
|
||||
return errors.New("missing Google Analytics Property ID")
|
||||
}
|
||||
url = fmt.Sprintf(
|
||||
"https://analytics.google.com/analytics/web/#/p%s/",
|
||||
cfg.GoogleAnalytics.PropertyID,
|
||||
)
|
||||
case "gtm-web":
|
||||
url = fmt.Sprintf(
|
||||
"https://tagmanager.google.com/#/container/accounts/%s/containers/%s/",
|
||||
cfg.GoogleTagManager.AccountID,
|
||||
cfg.GoogleTagManager.WebContainer.ContainerID,
|
||||
)
|
||||
case "gtm-server":
|
||||
url = fmt.Sprintf(
|
||||
"https://tagmanager.google.com/#/container/accounts/%s/containers/%s/",
|
||||
cfg.GoogleTagManager.AccountID,
|
||||
cfg.GoogleTagManager.ServerContainer.ContainerID,
|
||||
)
|
||||
default:
|
||||
return fmt.Errorf("invalid container type: %s", args[0])
|
||||
}
|
||||
|
||||
l.Info("↗ Navigating to Google Tag Manager Container: " + url)
|
||||
|
||||
return browser.OpenURL(url)
|
||||
},
|
||||
}
|
||||
|
||||
flags := cmd.Flags()
|
||||
|
||||
flags.StringSliceP("config", "c", []string{"sesamy.yaml"}, "config files (default is sesamy.yaml)")
|
||||
_ = c.BindPFlag("config", flags.Lookup("config"))
|
||||
|
||||
return cmd
|
||||
}
|
||||
@ -14,6 +14,7 @@ import (
|
||||
googletagmanagerprovider "github.com/foomo/sesamy-cli/pkg/provider/googletagmanager"
|
||||
microsoftadsprovider "github.com/foomo/sesamy-cli/pkg/provider/microsoftads"
|
||||
mixpanelprovider "github.com/foomo/sesamy-cli/pkg/provider/mixpanel"
|
||||
pinterestprovider "github.com/foomo/sesamy-cli/pkg/provider/pinterest"
|
||||
tracifyprovider "github.com/foomo/sesamy-cli/pkg/provider/tracify"
|
||||
umamiprovider "github.com/foomo/sesamy-cli/pkg/provider/umami"
|
||||
ptermx "github.com/foomo/sesamy-cli/pkg/pterm"
|
||||
@ -144,6 +145,13 @@ func NewServer(l *slog.Logger) *cobra.Command {
|
||||
}
|
||||
}
|
||||
|
||||
if cfg.Pinterest.Enabled && utils.Tag(pinterestprovider.Tag, tags) {
|
||||
l.Info("🅿️ Running provider", "name", pinterestprovider.Name, "tag", pinterestprovider.Tag)
|
||||
if err := pinterestprovider.Server(cmd.Context(), l, tm, cfg.Pinterest); err != nil {
|
||||
return errors.Wrap(err, "failed to provision mixpanel")
|
||||
}
|
||||
}
|
||||
|
||||
if missed := tm.Missed(); len(tags) == 0 && len(missed) > 0 {
|
||||
tree := pterm.TreeNode{
|
||||
Text: "♻️ Missed resources (potentially garbage)",
|
||||
|
||||
44
cmd/tags.go
44
cmd/tags.go
@ -2,6 +2,8 @@ package cmd
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"maps"
|
||||
"slices"
|
||||
|
||||
"github.com/foomo/sesamy-cli/pkg/provider/conversionlinker"
|
||||
"github.com/foomo/sesamy-cli/pkg/provider/cookiebot"
|
||||
@ -16,6 +18,7 @@ import (
|
||||
"github.com/foomo/sesamy-cli/pkg/provider/hotjar"
|
||||
"github.com/foomo/sesamy-cli/pkg/provider/microsoftads"
|
||||
"github.com/foomo/sesamy-cli/pkg/provider/mixpanel"
|
||||
"github.com/foomo/sesamy-cli/pkg/provider/pinterest"
|
||||
"github.com/foomo/sesamy-cli/pkg/provider/tracify"
|
||||
"github.com/foomo/sesamy-cli/pkg/provider/umami"
|
||||
"github.com/pterm/pterm"
|
||||
@ -28,26 +31,29 @@ func NewTags(l *slog.Logger) *cobra.Command {
|
||||
Use: "tags",
|
||||
Short: "Print out all available tags",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
// Define the data for the first table
|
||||
data := pterm.TableData{
|
||||
{"Name", "Tag"},
|
||||
{conversionlinker.Name, conversionlinker.Tag},
|
||||
{cookiebot.Name, cookiebot.Tag},
|
||||
{criteo.Name, criteo.Tag},
|
||||
{emarsys.Name, emarsys.Tag},
|
||||
{facebook.Name, facebook.Tag},
|
||||
{googleads.Name, googleads.Tag},
|
||||
{googleanalytics.Name, googleanalytics.Tag},
|
||||
{googletag.Name, googletag.Tag},
|
||||
{googleconsent.Name, googleconsent.Tag},
|
||||
{googletagmanager.Name, googletagmanager.Tag},
|
||||
{hotjar.Name, hotjar.Tag},
|
||||
{microsoftads.Name, microsoftads.Tag},
|
||||
{mixpanel.Name, mixpanel.Tag},
|
||||
{tracify.Name, tracify.Tag},
|
||||
{umami.Name, umami.Tag},
|
||||
tags := map[string]string{
|
||||
conversionlinker.Name: conversionlinker.Tag,
|
||||
cookiebot.Name: cookiebot.Tag,
|
||||
criteo.Name: criteo.Tag,
|
||||
emarsys.Name: emarsys.Tag,
|
||||
facebook.Name: facebook.Tag,
|
||||
googleads.Name: googleads.Tag,
|
||||
googleanalytics.Name: googleanalytics.Tag,
|
||||
googletag.Name: googletag.Tag,
|
||||
googleconsent.Name: googleconsent.Tag,
|
||||
googletagmanager.Name: googletagmanager.Tag,
|
||||
hotjar.Name: hotjar.Tag,
|
||||
microsoftads.Name: microsoftads.Tag,
|
||||
mixpanel.Name: mixpanel.Tag,
|
||||
tracify.Name: tracify.Tag,
|
||||
umami.Name: umami.Tag,
|
||||
pinterest.Name: pinterest.Tag,
|
||||
}
|
||||
// Define the data for the first table
|
||||
data := pterm.TableData{{"Name", "Tag"}}
|
||||
for _, name := range slices.Sorted(maps.Keys(tags)) {
|
||||
data = append(data, []string{name, tags[name]})
|
||||
}
|
||||
|
||||
return pterm.DefaultTable.WithHasHeader().WithData(data).Render()
|
||||
},
|
||||
}
|
||||
|
||||
79
go.mod
79
go.mod
@ -1,6 +1,6 @@
|
||||
module github.com/foomo/sesamy-cli
|
||||
|
||||
go 1.24.3
|
||||
go 1.25.1
|
||||
|
||||
require (
|
||||
github.com/Code-Hex/Neo-cowsay/v2 v2.0.4
|
||||
@ -8,31 +8,33 @@ require (
|
||||
github.com/fatih/structtag v1.2.0
|
||||
github.com/foomo/go v0.0.3
|
||||
github.com/foomo/gocontemplate v0.2.0
|
||||
github.com/foomo/sesamy-go v0.11.1
|
||||
github.com/foomo/sesamy-go v0.11.2
|
||||
github.com/invopop/jsonschema v0.13.0
|
||||
github.com/itchyny/json2yaml v0.1.4
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/knadh/koanf/parsers/yaml v1.0.0
|
||||
github.com/knadh/koanf/parsers/yaml v1.1.0
|
||||
github.com/knadh/koanf/providers/file v1.2.0
|
||||
github.com/knadh/koanf/providers/rawbytes v1.0.0
|
||||
github.com/knadh/koanf/v2 v2.2.0
|
||||
github.com/knadh/koanf/v2 v2.2.2
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/pterm/pterm v0.12.80
|
||||
github.com/spf13/cobra v1.9.1
|
||||
github.com/spf13/viper v1.20.1
|
||||
github.com/stoewer/go-strcase v1.3.0
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/wissance/stringFormatter v1.4.1
|
||||
google.golang.org/api v0.234.0
|
||||
github.com/pterm/pterm v0.12.81
|
||||
github.com/spf13/cobra v1.10.1
|
||||
github.com/spf13/viper v1.21.0
|
||||
github.com/sters/yaml-diff v1.4.1
|
||||
github.com/stoewer/go-strcase v1.3.1
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/wissance/stringFormatter v1.5.0
|
||||
google.golang.org/api v0.249.0
|
||||
)
|
||||
|
||||
require (
|
||||
atomicgo.dev/cursor v0.2.0 // indirect
|
||||
atomicgo.dev/keyboard v0.2.9 // indirect
|
||||
atomicgo.dev/schedule v0.1.0 // indirect
|
||||
cloud.google.com/go/auth v0.16.1 // indirect
|
||||
cloud.google.com/go/auth v0.16.5 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.7.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.8.0 // indirect
|
||||
github.com/Code-Hex/go-wordwrap v1.0.0 // indirect
|
||||
github.com/bahlo/generic-list-go v0.2.0 // indirect
|
||||
github.com/buger/jsonparser v1.1.1 // indirect
|
||||
@ -42,14 +44,15 @@ require (
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/foomo/gostandards v0.2.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||
github.com/goccy/go-yaml v1.15.6 // indirect
|
||||
github.com/google/s2a-go v0.1.9 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.14.2 // indirect
|
||||
github.com/gookit/color v1.5.4 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.15.0 // indirect
|
||||
github.com/gookit/color v1.6.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/knadh/koanf/maps v0.1.2 // indirect
|
||||
github.com/lithammer/fuzzysearch v1.1.8 // indirect
|
||||
@ -61,32 +64,32 @@ require (
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/sagikazarmark/locafero v0.9.0 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.14.0 // indirect
|
||||
github.com/spf13/cast v1.8.0 // indirect
|
||||
github.com/spf13/pflag v1.0.6 // indirect
|
||||
github.com/sagikazarmark/locafero v0.11.0 // indirect
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
|
||||
github.com/spf13/afero v1.15.0 // indirect
|
||||
github.com/spf13/cast v1.10.0 // indirect
|
||||
github.com/spf13/pflag v1.0.10 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
|
||||
go.opentelemetry.io/otel v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.36.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/crypto v0.38.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
|
||||
go.opentelemetry.io/otel v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.37.0 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/crypto v0.41.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect
|
||||
golang.org/x/mod v0.24.0 // indirect
|
||||
golang.org/x/net v0.40.0 // indirect
|
||||
golang.org/x/mod v0.27.0 // indirect
|
||||
golang.org/x/net v0.43.0 // indirect
|
||||
golang.org/x/oauth2 v0.30.0 // indirect
|
||||
golang.org/x/sync v0.14.0 // indirect
|
||||
golang.org/x/sys v0.33.0 // indirect
|
||||
golang.org/x/term v0.32.0 // indirect
|
||||
golang.org/x/text v0.25.0 // indirect
|
||||
golang.org/x/tools v0.31.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 // indirect
|
||||
google.golang.org/grpc v1.72.1 // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
golang.org/x/sync v0.17.0 // indirect
|
||||
golang.org/x/sys v0.36.0 // indirect
|
||||
golang.org/x/term v0.35.0 // indirect
|
||||
golang.org/x/text v0.29.0 // indirect
|
||||
golang.org/x/tools v0.36.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c // indirect
|
||||
google.golang.org/grpc v1.75.0 // indirect
|
||||
google.golang.org/protobuf v1.36.8 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
175
go.sum
175
go.sum
@ -6,12 +6,12 @@ atomicgo.dev/keyboard v0.2.9 h1:tOsIid3nlPLZ3lwgG8KZMp/SFmr7P0ssEN5JUsm78K8=
|
||||
atomicgo.dev/keyboard v0.2.9/go.mod h1:BC4w9g00XkxH/f1HXhW2sXmJFOCWbKn9xrOunSFtExQ=
|
||||
atomicgo.dev/schedule v0.1.0 h1:nTthAbhZS5YZmgYbb2+DH8uQIZcTlIrd4eYr3UQxEjs=
|
||||
atomicgo.dev/schedule v0.1.0/go.mod h1:xeUa3oAkiuHYh8bKiQBRojqAMq3PXXbJujjb0hw8pEU=
|
||||
cloud.google.com/go/auth v0.16.1 h1:XrXauHMd30LhQYVRHLGvJiYeczweKQXZxsTbV9TiguU=
|
||||
cloud.google.com/go/auth v0.16.1/go.mod h1:1howDHJ5IETh/LwYs3ZxvlkXF48aSqqJUM+5o02dNOI=
|
||||
cloud.google.com/go/auth v0.16.5 h1:mFWNQ2FEVWAliEQWpAdH80omXFokmrnbDhUS9cBywsI=
|
||||
cloud.google.com/go/auth v0.16.5/go.mod h1:utzRfHMP+Vv0mpOkTRQoWD2q3BatTOoWbA7gCc2dUhQ=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
|
||||
cloud.google.com/go/compute/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU=
|
||||
cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo=
|
||||
cloud.google.com/go/compute/metadata v0.8.0 h1:HxMRIbao8w17ZX6wBnjhcDkW6lTFpgcaobyVfZWqRLA=
|
||||
cloud.google.com/go/compute/metadata v0.8.0/go.mod h1:sYOGTp851OV9bOFJ9CH7elVvyzopvWQFNNghtDQ/Biw=
|
||||
github.com/Code-Hex/Neo-cowsay/v2 v2.0.4 h1:y80Hd9hmB+rsEH/p4c5ti5PbO0PhBmxw4NgbpFZvoHg=
|
||||
github.com/Code-Hex/Neo-cowsay/v2 v2.0.4/go.mod h1:6k40Pwrc2FazLf1BUbmAC36E9LvT+DErjZr30isbXhg=
|
||||
github.com/Code-Hex/go-wordwrap v1.0.0 h1:yl5fLyZEz3+hPGbpTRlTQ8mQJ1HXWcTq1FCNR1ch6zM=
|
||||
@ -53,19 +53,21 @@ github.com/foomo/gocontemplate v0.2.0 h1:YbgNUwZ9mK9Wj05cGVTPamCpMuxlaL4qegkbZv2
|
||||
github.com/foomo/gocontemplate v0.2.0/go.mod h1:VOYIvxPPAT7HxrderRexS0EttcT8pyfSRkCMvS8rtxA=
|
||||
github.com/foomo/gostandards v0.2.0 h1:Ryd7TI9yV3Xk5B84DcUDB7KcL3LzQ8NS+TVOrFxTYfA=
|
||||
github.com/foomo/gostandards v0.2.0/go.mod h1:XQx7Ur6vyvxaIe2cQvAthuhPYDe+d2soibqVcXDXOh4=
|
||||
github.com/foomo/sesamy-go v0.11.1 h1:AIwcNVWacq0dPvGXBafw2u6bY2IGPsXiqdZgqmBSYoE=
|
||||
github.com/foomo/sesamy-go v0.11.1/go.mod h1:3xnen0BWauXGBXq/7K7hDcc+Gxc3/HXHIlBX7ff2YGk=
|
||||
github.com/foomo/sesamy-go v0.11.2 h1:P405IMMDzW/4hMKbAbvCVBaFjOARb26/PdG1wTBAxBM=
|
||||
github.com/foomo/sesamy-go v0.11.2/go.mod h1:yORAeN0fDaZ0irXx4QdMp61wuDBAeEBHD0bTN4JjKxA=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss=
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/goccy/go-yaml v1.15.6 h1:gy5kf1yjMia3/c3wWD+u1z3lU5XlhpT8FZGaLJU9cOA=
|
||||
github.com/goccy/go-yaml v1.15.6/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
@ -77,12 +79,14 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
|
||||
github.com/googleapis/gax-go/v2 v2.14.2 h1:eBLnkZ9635krYIPD+ag1USrOAI0Nr0QYF3+/3GqO0k0=
|
||||
github.com/googleapis/gax-go/v2 v2.14.2/go.mod h1:ON64QhlJkhVtSqp4v1uaK92VyZ2gmvDQsweuyLV+8+w=
|
||||
github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo=
|
||||
github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc=
|
||||
github.com/gookit/assert v0.1.1 h1:lh3GcawXe/p+cU7ESTZ5Ui3Sm/x8JWpIis4/1aF0mY0=
|
||||
github.com/gookit/assert v0.1.1/go.mod h1:jS5bmIVQZTIwk42uXl4lyj4iaaxx32tqH16CFj0VX2E=
|
||||
github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ=
|
||||
github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo=
|
||||
github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0=
|
||||
github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w=
|
||||
github.com/gookit/color v1.6.0 h1:JjJXBTk1ETNyqyilJhkTXJYYigHG24TM9Xa2M1xAhRA=
|
||||
github.com/gookit/color v1.6.0/go.mod h1:9ACFc7/1IpHGBW8RwuDm/0YEnhg3dwwXpoMsmtyHfjs=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E=
|
||||
@ -98,14 +102,14 @@ github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y7
|
||||
github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
|
||||
github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo=
|
||||
github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI=
|
||||
github.com/knadh/koanf/parsers/yaml v1.0.0 h1:PXyeHCRhAMKyfLJaoTWsqUTxIFeDMmdAKz3XVEslZV4=
|
||||
github.com/knadh/koanf/parsers/yaml v1.0.0/go.mod h1:Q63VAOh/s6XaQs6a0TB2w9GFUuuPGvfYrCSWb9eWAQU=
|
||||
github.com/knadh/koanf/parsers/yaml v1.1.0 h1:3ltfm9ljprAHt4jxgeYLlFPmUaunuCgu1yILuTXRdM4=
|
||||
github.com/knadh/koanf/parsers/yaml v1.1.0/go.mod h1:HHmcHXUrp9cOPcuC+2wrr44GTUB0EC+PyfN3HZD9tFg=
|
||||
github.com/knadh/koanf/providers/file v1.2.0 h1:hrUJ6Y9YOA49aNu/RSYzOTFlqzXSCpmYIDXI7OJU6+U=
|
||||
github.com/knadh/koanf/providers/file v1.2.0/go.mod h1:bp1PM5f83Q+TOUu10J/0ApLBd9uIzg+n9UgthfY+nRA=
|
||||
github.com/knadh/koanf/providers/rawbytes v1.0.0 h1:MrKDh/HksJlKJmaZjgs4r8aVBb/zsJyc/8qaSnzcdNI=
|
||||
github.com/knadh/koanf/providers/rawbytes v1.0.0/go.mod h1:KxwYJf1uezTKy6PBtfE+m725NGp4GPVA7XoNTJ/PtLo=
|
||||
github.com/knadh/koanf/v2 v2.2.0 h1:FZFwd9bUjpb8DyCWARUBy5ovuhDs1lI87dOEn2K8UVU=
|
||||
github.com/knadh/koanf/v2 v2.2.0/go.mod h1:PSFru3ufQgTsI7IF+95rf9s8XA1+aHxKuO/W+dPoHEY=
|
||||
github.com/knadh/koanf/v2 v2.2.2 h1:ghbduIkpFui3L587wavneC9e3WIliCgiCgdxYO/wd7A=
|
||||
github.com/knadh/koanf/v2 v2.2.2/go.mod h1:abWQc0cBXLSF/PSOMCB/SK+T13NXDsPvOksbpi5e/9Q=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
@ -129,6 +133,8 @@ github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zx
|
||||
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
@ -141,32 +147,35 @@ github.com/pterm/pterm v0.12.31/go.mod h1:32ZAWZVXD7ZfG0s8qqHXePte42kdz8ECtRyEej
|
||||
github.com/pterm/pterm v0.12.33/go.mod h1:x+h2uL+n7CP/rel9+bImHD5lF3nM9vJj80k9ybiiTTE=
|
||||
github.com/pterm/pterm v0.12.36/go.mod h1:NjiL09hFhT/vWjQHSj1athJpx6H8cjpHXNAK5bUw8T8=
|
||||
github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s=
|
||||
github.com/pterm/pterm v0.12.80 h1:mM55B+GnKUnLMUSqhdINe4s6tOuVQIetQ3my8JGyAIg=
|
||||
github.com/pterm/pterm v0.12.80/go.mod h1:c6DeF9bSnOSeFPZlfs4ZRAFcf5SCoTwvwQ5xaKGQlHo=
|
||||
github.com/pterm/pterm v0.12.81 h1:ju+j5I2++FO1jBKMmscgh5h5DPFDFMB7epEjSoKehKA=
|
||||
github.com/pterm/pterm v0.12.81/go.mod h1:TyuyrPjnxfwP+ccJdBTeWHtd/e0ybQHkOS/TakajZCw=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sagikazarmark/locafero v0.9.0 h1:GbgQGNtTrEmddYDSAH9QLRyfAHY12md+8YFTqyMTC9k=
|
||||
github.com/sagikazarmark/locafero v0.9.0/go.mod h1:UBUyz37V+EdMS3hDF3QWIiVr/2dPrx49OMO0Bn0hJqk=
|
||||
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
|
||||
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
|
||||
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
|
||||
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
||||
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
|
||||
github.com/spf13/afero v1.14.0 h1:9tH6MapGnn/j0eb0yIXiLjERO8RB6xIVZRDCX7PtqWA=
|
||||
github.com/spf13/afero v1.14.0/go.mod h1:acJQ8t0ohCGuMN3O+Pv0V0hgMxNYDlvdk+VTfyZmbYo=
|
||||
github.com/spf13/cast v1.8.0 h1:gEN9K4b8Xws4EX0+a0reLmhq8moKn7ntRlQYgjPeCDk=
|
||||
github.com/spf13/cast v1.8.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
|
||||
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
|
||||
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4=
|
||||
github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4=
|
||||
github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs=
|
||||
github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=
|
||||
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
|
||||
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
|
||||
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
|
||||
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
|
||||
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
|
||||
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
|
||||
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/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=
|
||||
github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=
|
||||
github.com/sters/yaml-diff v1.4.1 h1:0W3jnFKCu8/DV7nh2aXSDA2VVfxfHu2+qdh81CuFmZo=
|
||||
github.com/sters/yaml-diff v1.4.1/go.mod h1:K286Xp2z+aGkok7z9k3zXcq0ZsrDaDp7/wyGwFjM9Y8=
|
||||
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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
@ -176,12 +185,12 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
github.com/wissance/stringFormatter v1.4.1 h1:E/xiKQz5ZmLPwnUc89u9ez6LW+SabJQNUFbR00CBbbU=
|
||||
github.com/wissance/stringFormatter v1.4.1/go.mod h1:H7Mz15+5i8ypmv6bLknM/uD+U1teUW99PlW0DNCNscA=
|
||||
github.com/wissance/stringFormatter v1.5.0 h1:hiGpYEJS3B3H/6M03HecqW8nDO0OXgQ75REVTXp6reM=
|
||||
github.com/wissance/stringFormatter v1.5.0/go.mod h1:H7Mz15+5i8ypmv6bLknM/uD+U1teUW99PlW0DNCNscA=
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc=
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw=
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
|
||||
@ -190,43 +199,43 @@ github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJu
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ=
|
||||
go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
|
||||
go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
|
||||
go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
|
||||
go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
|
||||
go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
|
||||
go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
|
||||
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
|
||||
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
|
||||
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
|
||||
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
|
||||
go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
|
||||
go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
|
||||
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
|
||||
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
|
||||
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
|
||||
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw=
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
|
||||
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
|
||||
golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ=
|
||||
golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
|
||||
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
|
||||
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
||||
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
||||
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
||||
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
|
||||
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
|
||||
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -238,43 +247,45 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
|
||||
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
|
||||
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
|
||||
golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ=
|
||||
golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
|
||||
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
|
||||
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
|
||||
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
|
||||
golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
|
||||
golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=
|
||||
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.234.0 h1:d3sAmYq3E9gdr2mpmiWGbm9pHsA/KJmyiLkwKfHBqU4=
|
||||
google.golang.org/api v0.234.0/go.mod h1:QpeJkemzkFKe5VCE/PMv7GsUfn9ZF+u+q1Q7w6ckxTg=
|
||||
google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 h1:1tXaIXCracvtsRxSBsYDiSBN0cuJvM7QYW+MrpIRY78=
|
||||
google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:49MsLSx0oWMOZqcpB3uL8ZOkAh1+TndpJ8ONoCBWiZk=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 h1:vPV0tzlsK6EzEDHNNH5sa7Hs9bd7iXR7B1tSiPepkV0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:pKLAc5OolXC3ViWGI62vvC0n10CpwAtRcTNCFwTKBEw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 h1:cJfm9zPbe1e873mHJzmQ1nwVEeRDU/T1wXDK2kUSU34=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||
google.golang.org/grpc v1.72.1 h1:HR03wO6eyZ7lknl75XlxABNVLLFc2PAb6mHlYh756mA=
|
||||
google.golang.org/grpc v1.72.1/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
|
||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||
google.golang.org/api v0.249.0 h1:0VrsWAKzIZi058aeq+I86uIXbNhm9GxSHpbmZ92a38w=
|
||||
google.golang.org/api v0.249.0/go.mod h1:dGk9qyI0UYPwO/cjt2q06LG/EhUpwZGdAbYF14wHHrQ=
|
||||
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4=
|
||||
google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7 h1:FiusG7LWj+4byqhbvmB+Q93B/mOxJLN2DTozDuZm4EU=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:kXqgZtrWaf6qS3jZOCnCH7WYfrvFjkC51bM8fz3RsCA=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c h1:qXWI/sQtv5UKboZ/zUk7h+mrf/lXORyI+n9DKDAusdg=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c/go.mod h1:gw1tLEfykwDz2ET4a12jcXt4couGAm7IwsVaTy0Sflo=
|
||||
google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4=
|
||||
google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ=
|
||||
google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc=
|
||||
google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
|
||||
2
main.go
2
main.go
@ -19,6 +19,8 @@ func main() {
|
||||
root.AddCommand(
|
||||
cmd.NewConfig(l),
|
||||
cmd.NewList(l),
|
||||
cmd.NewDiff(l),
|
||||
cmd.NewOpen(l),
|
||||
cmd.NewProvision(l),
|
||||
cmd.NewTags(l),
|
||||
cmd.NewTypeScript(l),
|
||||
|
||||
@ -28,6 +28,8 @@ type Config struct {
|
||||
MicrosoftAds MicrosoftAds `json:"microsoftAds" yaml:"microsoftAds"`
|
||||
// Mixpanel provider settings
|
||||
Mixpanel Mixpanel `json:"mixpanel" yaml:"mixpanel"`
|
||||
// Pinterest provider settings
|
||||
Pinterest Pinterest `json:"pinterest" yaml:"pinterest"`
|
||||
// Emarsys provider settings
|
||||
Emarsys Emarsys `json:"emarsys" yaml:"emarsys"`
|
||||
// Hotjar provider settings
|
||||
|
||||
@ -5,4 +5,6 @@ type ConversionLinker struct {
|
||||
Enabled bool `json:"enabled" yaml:"enabled"`
|
||||
// Google Consent settings
|
||||
GoogleConsent GoogleConsent `json:"googleConsent" yaml:"googleConsent"`
|
||||
// Accept incoming linker parameters
|
||||
EnableLinkerParams bool `json:"enableLinkerParams" yaml:"enableLinkerParams"`
|
||||
}
|
||||
|
||||
@ -7,6 +7,10 @@ import (
|
||||
type GoogleAnalytics struct {
|
||||
// Enable provider
|
||||
Enabled bool `json:"enabled" yaml:"enabled"`
|
||||
// Google Analytics account id
|
||||
AccountID string `json:"accountId" yaml:"accountId"`
|
||||
// Google Analytics property id
|
||||
PropertyID string `json:"propertyId" yaml:"propertyId"`
|
||||
// Google Consent settings
|
||||
GoogleConsent GoogleConsent `json:"googleConsent" yaml:"googleConsent"`
|
||||
// GTag.js override configuration
|
||||
|
||||
20
pkg/config/pinterest.go
Normal file
20
pkg/config/pinterest.go
Normal file
@ -0,0 +1,20 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/foomo/gocontemplate/pkg/contemplate"
|
||||
)
|
||||
|
||||
type Pinterest struct {
|
||||
// Enable provider
|
||||
Enabled bool `json:"enabled" yaml:"enabled"`
|
||||
// Pinterest advertiser id
|
||||
AdvertiserID string `json:"advertiserId" yaml:"advertiserId"`
|
||||
// Pinterest API access token
|
||||
APIAccessToken string `json:"apiAccessToken" yaml:"apiAccessToken"`
|
||||
// Enable test mode
|
||||
TestModeEnabled bool `json:"testModeEnabled" yaml:"testModeEnabled"`
|
||||
// Google Consent settings
|
||||
GoogleConsent GoogleConsent `json:"googleConsent" yaml:"googleConsent"`
|
||||
// Google Tag Manager server container settings
|
||||
ServerContainer contemplate.Config `json:"serverContainer" yaml:"serverContainer"`
|
||||
}
|
||||
@ -35,7 +35,7 @@ func Server(ctx context.Context, tm *tagmanager.TagManager, cfg config.Conversio
|
||||
return errors.Wrap(err, "failed to upsert event trigger: "+NameConversionLinkerTrigger)
|
||||
}
|
||||
|
||||
if _, err := tm.UpsertTag(ctx, folder, containertag.NewConversionLinker(Name, eventTrigger)); err != nil {
|
||||
if _, err := tm.UpsertTag(ctx, folder, containertag.NewConversionLinker(Name, cfg.EnableLinkerParams, eventTrigger)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
package tag
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/foomo/sesamy-cli/pkg/utils"
|
||||
"google.golang.org/api/tagmanager/v2"
|
||||
)
|
||||
|
||||
func NewConversionLinker(name string, triggers ...*tagmanager.Trigger) *tagmanager.Tag {
|
||||
func NewConversionLinker(name string, enableLinkerParams bool, triggers ...*tagmanager.Trigger) *tagmanager.Tag {
|
||||
return &tagmanager.Tag{
|
||||
FiringTriggerId: utils.TriggerIDs(triggers),
|
||||
Name: name,
|
||||
@ -14,7 +16,7 @@ func NewConversionLinker(name string, triggers ...*tagmanager.Trigger) *tagmanag
|
||||
{
|
||||
Key: "enableLinkerParams",
|
||||
Type: "boolean",
|
||||
Value: "false",
|
||||
Value: strconv.FormatBool(enableLinkerParams),
|
||||
},
|
||||
{
|
||||
Key: "enableCookieOverrides",
|
||||
|
||||
@ -113,7 +113,7 @@ const headerList = ["referer", "user-agent"];
|
||||
const requestUrl = merchantUrl+'?'+serializeData(mappedData);
|
||||
const requestOptions = {
|
||||
headers: generateRequestHeaders(headerList, cookieList),
|
||||
timeout: 500,
|
||||
timeout: 1000,
|
||||
};
|
||||
|
||||
return sendHttpGet(requestUrl, requestOptions).then((result) => {
|
||||
|
||||
@ -13,6 +13,7 @@ import (
|
||||
commonvariable "github.com/foomo/sesamy-cli/pkg/tagmanager/common/variable"
|
||||
"github.com/foomo/sesamy-cli/pkg/utils"
|
||||
"github.com/pkg/errors"
|
||||
tagmanager2 "google.golang.org/api/tagmanager/v2"
|
||||
)
|
||||
|
||||
func Server(ctx context.Context, l *slog.Logger, tm *tagmanager.TagManager, cfg config.Facebook) error {
|
||||
@ -31,9 +32,13 @@ func Server(ctx context.Context, l *slog.Logger, tm *tagmanager.TagManager, cfg
|
||||
return err
|
||||
}
|
||||
|
||||
testEventToken, err := tm.UpsertVariable(ctx, folder, commonvariable.NewConstant(NameTestEventTokenConstant, cfg.TestEventToken))
|
||||
if err != nil {
|
||||
return err
|
||||
var testEventToken *tagmanager2.Variable
|
||||
if cfg.TestEventToken != "" {
|
||||
var err error
|
||||
testEventToken, err = tm.UpsertVariable(ctx, folder, commonvariable.NewConstant(NameTestEventTokenConstant, cfg.TestEventToken))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
template, err := tm.LookupTemplate(ctx, NameConversionsAPITagTemplate)
|
||||
|
||||
@ -13,42 +13,48 @@ func ConversionsAPITagName(v string) string {
|
||||
}
|
||||
|
||||
func NewConversionsAPITag(name string, pixelID, apiAccessToken, testEventCode *tagmanager.Variable, settings config.FacebookConversionAPITag, template *tagmanager.CustomTemplate, triggers ...*tagmanager.Trigger) *tagmanager.Tag {
|
||||
params := []*tagmanager.Parameter{
|
||||
{
|
||||
Key: "pixelId",
|
||||
Type: "template",
|
||||
Value: "{{" + pixelID.Name + "}}",
|
||||
},
|
||||
{
|
||||
Key: "apiAccessToken",
|
||||
Type: "template",
|
||||
Value: "{{" + apiAccessToken.Name + "}}",
|
||||
},
|
||||
{
|
||||
Key: "enableEventEnhancement",
|
||||
Type: "boolean",
|
||||
Value: strconv.FormatBool(settings.EnableEventEnhancement),
|
||||
},
|
||||
{
|
||||
Key: "extendCookies",
|
||||
Type: "boolean",
|
||||
Value: strconv.FormatBool(settings.ExtendCookies),
|
||||
},
|
||||
{
|
||||
Key: "actionSource",
|
||||
Type: "template",
|
||||
Value: "website",
|
||||
},
|
||||
}
|
||||
|
||||
if testEventCode != nil {
|
||||
params = append(params, &tagmanager.Parameter{
|
||||
Key: "testEventCode",
|
||||
Type: "template",
|
||||
Value: "{{" + testEventCode.Name + "}}",
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
return &tagmanager.Tag{
|
||||
FiringTriggerId: utils.TriggerIDs(triggers),
|
||||
Name: ConversionsAPITagName(name),
|
||||
TagFiringOption: "oncePerEvent",
|
||||
Parameter: []*tagmanager.Parameter{
|
||||
{
|
||||
Key: "pixelId",
|
||||
Type: "template",
|
||||
Value: "{{" + pixelID.Name + "}}",
|
||||
},
|
||||
{
|
||||
Key: "apiAccessToken",
|
||||
Type: "template",
|
||||
Value: "{{" + apiAccessToken.Name + "}}",
|
||||
},
|
||||
{
|
||||
Key: "testEventCode",
|
||||
Type: "template",
|
||||
Value: "{{" + testEventCode.Name + "}}",
|
||||
},
|
||||
{
|
||||
Key: "enableEventEnhancement",
|
||||
Type: "boolean",
|
||||
Value: strconv.FormatBool(settings.EnableEventEnhancement),
|
||||
},
|
||||
{
|
||||
Key: "extendCookies",
|
||||
Type: "boolean",
|
||||
Value: strconv.FormatBool(settings.ExtendCookies),
|
||||
},
|
||||
{
|
||||
Key: "actionSource",
|
||||
Type: "template",
|
||||
Value: "website",
|
||||
},
|
||||
},
|
||||
Type: utils.TemplateType(template),
|
||||
Parameter: params,
|
||||
Type: utils.TemplateType(template),
|
||||
}
|
||||
}
|
||||
|
||||
@ -531,7 +531,7 @@ if (data.activateLogs) {
|
||||
|
||||
return sendHttpGet(url, {
|
||||
headers: {key: 'value'},
|
||||
timeout: 500,
|
||||
timeout: 1000,
|
||||
}).then((result) => {
|
||||
if (result.statusCode >= 200 && result.statusCode < 300) {
|
||||
data.gtmOnSuccess();
|
||||
|
||||
7
pkg/provider/pinterest/constants.go
Normal file
7
pkg/provider/pinterest/constants.go
Normal file
@ -0,0 +1,7 @@
|
||||
package pinterest
|
||||
|
||||
const (
|
||||
Tag = "pinterest"
|
||||
Name = "Pinterest"
|
||||
NameTagTemplate = "Pinterest API for Conversions Tag"
|
||||
)
|
||||
62
pkg/provider/pinterest/server.go
Normal file
62
pkg/provider/pinterest/server.go
Normal file
@ -0,0 +1,62 @@
|
||||
package pinterest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
|
||||
"github.com/foomo/sesamy-cli/pkg/config"
|
||||
"github.com/foomo/sesamy-cli/pkg/provider/googleconsent"
|
||||
googleconsentvariable "github.com/foomo/sesamy-cli/pkg/provider/googleconsent/server/variable"
|
||||
containertag "github.com/foomo/sesamy-cli/pkg/provider/pinterest/server/tag"
|
||||
"github.com/foomo/sesamy-cli/pkg/provider/pinterest/server/trigger"
|
||||
"github.com/foomo/sesamy-cli/pkg/tagmanager"
|
||||
"github.com/foomo/sesamy-cli/pkg/utils"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func Server(ctx context.Context, l *slog.Logger, tm *tagmanager.TagManager, cfg config.Pinterest) error {
|
||||
folder, err := tm.UpsertFolder(ctx, "Sesamy - "+Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
template, err := tm.LookupTemplate(ctx, NameTagTemplate)
|
||||
if err != nil {
|
||||
if errors.Is(err, tagmanager.ErrNotFound) {
|
||||
l.Warn("Please install the 'Pinterest API for Conversions Ta' Tag Template manually first")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
{ // create tags
|
||||
eventParameters, err := utils.LoadEventParams(ctx, cfg.ServerContainer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for event := range eventParameters {
|
||||
var eventTriggerOpts []trigger.EventOption
|
||||
if cfg.GoogleConsent.Enabled {
|
||||
if err := googleconsent.ServerEnsure(ctx, tm); err != nil {
|
||||
return err
|
||||
}
|
||||
consentVariable, err := tm.LookupVariable(ctx, googleconsentvariable.GoogleConsentModeName(cfg.GoogleConsent.Mode))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
eventTriggerOpts = append(eventTriggerOpts, trigger.ConversionWithConsentMode(consentVariable))
|
||||
}
|
||||
|
||||
eventTrigger, err := tm.UpsertTrigger(ctx, folder, trigger.NewConversion(event, eventTriggerOpts...))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to upsert event trigger: "+event)
|
||||
}
|
||||
|
||||
if _, err := tm.UpsertTag(ctx, folder, containertag.NewConversion(event, cfg, template, eventTrigger)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
59
pkg/provider/pinterest/server/tag/conversion.go
Normal file
59
pkg/provider/pinterest/server/tag/conversion.go
Normal file
@ -0,0 +1,59 @@
|
||||
package tag
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/foomo/sesamy-cli/pkg/config"
|
||||
"github.com/foomo/sesamy-cli/pkg/utils"
|
||||
"google.golang.org/api/tagmanager/v2"
|
||||
)
|
||||
|
||||
func ConversionName(v string) string {
|
||||
return "Pinterest Conversion - " + v
|
||||
}
|
||||
|
||||
func NewConversion(name string, cfg config.Pinterest, template *tagmanager.CustomTemplate, triggers ...*tagmanager.Trigger) *tagmanager.Tag {
|
||||
return &tagmanager.Tag{
|
||||
FiringTriggerId: utils.TriggerIDs(triggers),
|
||||
Name: ConversionName(name),
|
||||
TagFiringOption: "oncePerEvent",
|
||||
Parameter: []*tagmanager.Parameter{
|
||||
{
|
||||
Key: "apiAccessToken",
|
||||
Type: "template",
|
||||
Value: cfg.APIAccessToken,
|
||||
},
|
||||
{
|
||||
Key: "testMode",
|
||||
Type: "boolean",
|
||||
Value: strconv.FormatBool(cfg.TestModeEnabled),
|
||||
},
|
||||
{
|
||||
Key: "eventName",
|
||||
Type: "template",
|
||||
Value: "inherit",
|
||||
},
|
||||
{
|
||||
Key: "logMode",
|
||||
Type: "template",
|
||||
Value: func(testMode bool) string {
|
||||
if testMode {
|
||||
return "log"
|
||||
}
|
||||
return "donotlog"
|
||||
}(cfg.TestModeEnabled),
|
||||
},
|
||||
{
|
||||
Key: "overrideMode",
|
||||
Type: "boolean",
|
||||
Value: "false",
|
||||
},
|
||||
{
|
||||
Key: "advertiserId",
|
||||
Type: "template",
|
||||
Value: cfg.AdvertiserID,
|
||||
},
|
||||
},
|
||||
Type: utils.TemplateType(template),
|
||||
}
|
||||
}
|
||||
83
pkg/provider/pinterest/server/trigger/conversion.go
Normal file
83
pkg/provider/pinterest/server/trigger/conversion.go
Normal file
@ -0,0 +1,83 @@
|
||||
package trigger
|
||||
|
||||
import (
|
||||
"google.golang.org/api/tagmanager/v2"
|
||||
)
|
||||
|
||||
func ConversionName(v string) string {
|
||||
return "Pinterest Conversion - " + v
|
||||
}
|
||||
|
||||
type (
|
||||
EventOptions struct {
|
||||
consentMode *tagmanager.Variable
|
||||
}
|
||||
EventOption func(*EventOptions)
|
||||
)
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ~ Options
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
func ConversionWithConsentMode(mode *tagmanager.Variable) EventOption {
|
||||
return func(o *EventOptions) {
|
||||
o.consentMode = mode
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ~ Constructor
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
func NewConversion(name string, opts ...EventOption) *tagmanager.Trigger {
|
||||
o := &EventOptions{}
|
||||
for _, opt := range opts {
|
||||
if opt != nil {
|
||||
opt(o)
|
||||
}
|
||||
}
|
||||
|
||||
var filter []*tagmanager.Condition
|
||||
if o.consentMode != nil {
|
||||
filter = append(filter,
|
||||
&tagmanager.Condition{
|
||||
Parameter: []*tagmanager.Parameter{
|
||||
{
|
||||
Key: "arg0",
|
||||
Type: "template",
|
||||
Value: "{{" + o.consentMode.Name + "}}",
|
||||
},
|
||||
{
|
||||
Key: "arg1",
|
||||
Type: "template",
|
||||
Value: "granted",
|
||||
},
|
||||
},
|
||||
Type: "equals",
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
return &tagmanager.Trigger{
|
||||
Type: "customEvent",
|
||||
Name: ConversionName(name),
|
||||
CustomEventFilter: []*tagmanager.Condition{
|
||||
{
|
||||
Parameter: []*tagmanager.Parameter{
|
||||
{
|
||||
Key: "arg0",
|
||||
Type: "template",
|
||||
Value: "{{_event}}",
|
||||
},
|
||||
{
|
||||
Key: "arg1",
|
||||
Type: "template",
|
||||
Value: name,
|
||||
},
|
||||
},
|
||||
Type: "equals",
|
||||
},
|
||||
},
|
||||
Filter: filter,
|
||||
}
|
||||
}
|
||||
@ -129,7 +129,7 @@ if (!isConsentGivenOrNotRequired()) {
|
||||
const options = {
|
||||
headers: {'tracify-token': data.token},
|
||||
method: 'POST',
|
||||
timeout: 500,
|
||||
timeout: 1000,
|
||||
};
|
||||
const body = mapEventData();
|
||||
|
||||
|
||||
98
pkg/utils/highlight.go
Normal file
98
pkg/utils/highlight.go
Normal file
@ -0,0 +1,98 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"github.com/alecthomas/chroma"
|
||||
"github.com/alecthomas/chroma/formatters"
|
||||
"github.com/alecthomas/chroma/lexers"
|
||||
"github.com/alecthomas/chroma/styles"
|
||||
"github.com/pterm/pterm"
|
||||
)
|
||||
|
||||
func Highlight(source string) string {
|
||||
out := &numberWriter{
|
||||
w: bytes.NewBufferString(""),
|
||||
currentLine: 1,
|
||||
}
|
||||
// Determine lexer.
|
||||
l := lexers.Get("yaml")
|
||||
if l == nil {
|
||||
l = lexers.Analyse(source)
|
||||
}
|
||||
if l == nil {
|
||||
l = lexers.Fallback
|
||||
}
|
||||
l = chroma.Coalesce(l)
|
||||
|
||||
// Determine formatter.
|
||||
f := formatters.Get("terminal256")
|
||||
if f == nil {
|
||||
f = formatters.Fallback
|
||||
}
|
||||
|
||||
// Determine style.
|
||||
s := styles.Get("monokai")
|
||||
if s == nil {
|
||||
s = styles.Fallback
|
||||
}
|
||||
|
||||
it, err := l.Tokenise(nil, source)
|
||||
if err != nil {
|
||||
pterm.Error.Println(err.Error())
|
||||
}
|
||||
|
||||
if err = f.Format(out, s, it); err != nil {
|
||||
pterm.Error.Println(err.Error())
|
||||
}
|
||||
|
||||
return out.w.String()
|
||||
}
|
||||
|
||||
type numberWriter struct {
|
||||
w *bytes.Buffer
|
||||
currentLine uint64
|
||||
buf []byte
|
||||
}
|
||||
|
||||
func (w *numberWriter) Write(p []byte) (int, error) {
|
||||
// Early return.
|
||||
// Can't calculate the line numbers until the line breaks are made, so store them all in a buffer.
|
||||
if !bytes.Contains(p, []byte{'\n'}) {
|
||||
w.buf = append(w.buf, p...)
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
var (
|
||||
original = p
|
||||
tokenLen uint
|
||||
)
|
||||
for i, c := range original {
|
||||
tokenLen++
|
||||
if c != '\n' {
|
||||
continue
|
||||
}
|
||||
|
||||
token := p[:tokenLen]
|
||||
p = original[i+1:]
|
||||
tokenLen = 0
|
||||
|
||||
format := "%4d |\t%s%s"
|
||||
if w.currentLine > 9999 {
|
||||
format = "%d |\t%s%s"
|
||||
}
|
||||
format = "\033[34m" + format + "\033[0m"
|
||||
|
||||
if _, err := fmt.Fprintf(w.w, format, w.currentLine, string(w.buf), string(token)); err != nil {
|
||||
return i + 1, err
|
||||
}
|
||||
w.buf = w.buf[:0]
|
||||
w.currentLine++
|
||||
}
|
||||
|
||||
if len(p) > 0 {
|
||||
w.buf = append(w.buf, p...)
|
||||
}
|
||||
return len(original), nil
|
||||
}
|
||||
@ -105,6 +105,10 @@
|
||||
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.Mixpanel",
|
||||
"description": "Mixpanel provider settings"
|
||||
},
|
||||
"pinterest": {
|
||||
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.Pinterest",
|
||||
"description": "Pinterest provider settings"
|
||||
},
|
||||
"emarsys": {
|
||||
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.Emarsys",
|
||||
"description": "Emarsys provider settings"
|
||||
@ -141,6 +145,10 @@
|
||||
"googleConsent": {
|
||||
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.GoogleConsent",
|
||||
"description": "Google Consent settings"
|
||||
},
|
||||
"enableLinkerParams": {
|
||||
"type": "boolean",
|
||||
"description": "Accept incoming linker parameters"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
@ -434,6 +442,14 @@
|
||||
"type": "boolean",
|
||||
"description": "Enable provider"
|
||||
},
|
||||
"accountId": {
|
||||
"type": "string",
|
||||
"description": "Google Analytics account id"
|
||||
},
|
||||
"propertyId": {
|
||||
"type": "string",
|
||||
"description": "Google Analytics property id"
|
||||
},
|
||||
"googleConsent": {
|
||||
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.GoogleConsent",
|
||||
"description": "Google Consent settings"
|
||||
@ -733,6 +749,36 @@
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"github.com.foomo.sesamy-cli.pkg.config.Pinterest": {
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enable provider"
|
||||
},
|
||||
"advertiserId": {
|
||||
"type": "string",
|
||||
"description": "Pinterest advertiser id"
|
||||
},
|
||||
"apiAccessToken": {
|
||||
"type": "string",
|
||||
"description": "Pinterest API access token"
|
||||
},
|
||||
"testModeEnabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enable test mode"
|
||||
},
|
||||
"googleConsent": {
|
||||
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.GoogleConsent",
|
||||
"description": "Google Consent settings"
|
||||
},
|
||||
"serverContainer": {
|
||||
"$ref": "#/$defs/github.com.foomo.gocontemplate.pkg.contemplate.Config",
|
||||
"description": "Google Tag Manager server container settings"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"github.com.foomo.sesamy-cli.pkg.config.Tracify": {
|
||||
"properties": {
|
||||
"enabled": {
|
||||
|
||||
34
sesamy.yaml
34
sesamy.yaml
@ -225,6 +225,8 @@ conversionLinker:
|
||||
enabled: true
|
||||
# Consent mode name
|
||||
mode: ad_storage
|
||||
# Accept incoming linker parameters
|
||||
enableLinkerParams: true
|
||||
|
||||
# --- Umami settings
|
||||
umami:
|
||||
@ -474,3 +476,35 @@ mixpanel:
|
||||
- ViewCart
|
||||
- ViewItem
|
||||
- ViewItemList
|
||||
|
||||
# --- Pinterest
|
||||
pinterest:
|
||||
# Enable provider
|
||||
enabled: true
|
||||
# Pinterest advertiser id
|
||||
advertiserId: ''
|
||||
# Pinterest API access token
|
||||
apiAccessToken: ''
|
||||
# Enable test mode
|
||||
testModeEnabled: false
|
||||
# Google Consent settings
|
||||
googleConsent:
|
||||
# Enable consent mode
|
||||
enabled: true
|
||||
# Consent mode name
|
||||
mode: analytics_storage
|
||||
# Google Tag Manager server container settings
|
||||
serverContainer:
|
||||
# Directory containing the go.mod file
|
||||
directory: .
|
||||
# Contemplate package config for generated events
|
||||
packages:
|
||||
- path: 'github.com/foomo/sesamy-go/pkg/event'
|
||||
types:
|
||||
- AddToCart
|
||||
- GenerateLead
|
||||
- PageView
|
||||
- Purchase
|
||||
- Search
|
||||
- SignUp
|
||||
- ViewItemList
|
||||
|
||||
Loading…
Reference in New Issue
Block a user