Skip to content
This repository has been archived by the owner on Dec 3, 2024. It is now read-only.

feat: Add Wallets #1

Merged
merged 1 commit into from
Jan 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: release
on:
push:
tags:
- "v*.*.*"
env:
CGO_ENABLED: 0

jobs:
release-binary:
runs-on: ubuntu-latest
steps:
# This fails for invalid semver strings
- name: Parse semver string
id: semver_parser
uses: booxmedialtd/ws-action-parse-semver@966a26512c94239a00aa10b1b0c196906f7e1909
with:
input_string: ${{github.ref_name}}
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version-file: go.mod
cache: true
- name: Run GoReleaser Dry-Run
uses: goreleaser/goreleaser-action@v4
with:
version: latest
args: release --rm-dist --skip-validate --skip-publish --skip-sign
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v4
with:
version: latest
args: release --rm-dist --skip-sign
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
38 changes: 38 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: test

on:
push:
branches:
- main
pull_request:
branches: [main]

jobs:
test:
timeout-minutes: 30
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 2
- name: Set up Go 1.x
uses: actions/setup-go@v3
with:
go-version-file: go.mod
cache: true
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: v1.50.1
- name: Get dependencies
run: go get -t -d ./...
- name: Build
run: go build .
- name: Test
run: make test
- name: gen
if: github.event_name == 'pull_request'
run: make gen
- name: Fail if generation updated files
if: github.event_name == 'pull_request'
run: test "$(git status -s | wc -l)" -eq 0 || (git status -s; exit 1)
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,8 @@

# Dependency directories (remove the comment below to include it)
# vendor/


.DS_Store

cq-source-plaid
35 changes: 35 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
before:
hooks:
- go mod download
builds:
- flags:
- -buildmode=exe
env:
- CGO_ENABLED=0
- GO111MODULE=on
ldflags:
- -s -w -X github.com/cloudquery/cq-source-plaid/plugin.Version={{.Version}}
goos:
- windows
- linux
- darwin
goarch:
- amd64
- arm64
ignore:
- goos: windows
goarch: arm64
archives:
- name_template: "{{ .Binary }}_{{ .Os }}_{{ .Arch }}"
format: zip
checksum:
name_template: "checksums.txt"
changelog:
sort: asc
filters:
exclude:
- "^docs:"
- "^test:"

release:
prerelease: auto
16 changes: 16 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.PHONY: test
test:
go test -timeout 3m ./...

.PHONY: lint
lint:
@golangci-lint run --timeout 10m

.PHONY: gen-docs
gen-docs:
rm -rf ./docs/tables/*
go run main.go doc ./docs/tables

# All gen targets
.PHONY: gen
gen: gen-docs
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# CloudQuery plaid Source Plugin
49 changes: 49 additions & 0 deletions client/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package client

import (
"context"
"fmt"

"github.com/cloudquery/plugin-sdk/plugins/source"
"github.com/cloudquery/plugin-sdk/schema"
"github.com/cloudquery/plugin-sdk/specs"
"github.com/plaid/plaid-go/v10/plaid"
"github.com/rs/zerolog"
)

type Client struct {
Logger zerolog.Logger
Services *plaid.APIClient
ClientId string
Secret string
}

func (c *Client) ID() string {
return "plaid"
}

func New(ctx context.Context, logger zerolog.Logger, s specs.Source, opts source.Options) (schema.ClientMeta, error) {
var pluginSpec Spec

if err := s.UnmarshalSpec(&pluginSpec); err != nil {
return nil, fmt.Errorf("failed to unmarshal plugin spec: %w", err)
}

pluginSpec.SetDefaults()
if err := pluginSpec.Validate(); err != nil {
return nil, err
}

configuration := plaid.NewConfiguration()
configuration.AddDefaultHeader("PLAID-CLIENT-ID", pluginSpec.ClientId)
configuration.AddDefaultHeader("PLAID-SECRET", pluginSpec.Secret)
configuration.UseEnvironment(Environments[pluginSpec.Environment])
client := plaid.NewAPIClient(configuration)

return &Client{
Logger: logger,
Services: client,
ClientId: pluginSpec.ClientId,
Secret: pluginSpec.Secret,
}, nil
}
51 changes: 51 additions & 0 deletions client/spec.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package client

import (
"fmt"
"sort"
"strings"

"github.com/plaid/plaid-go/v10/plaid"
"golang.org/x/exp/maps"
)

var Environments = map[string]plaid.Environment{
"sandbox": plaid.Sandbox,
"development": plaid.Development,
"production": plaid.Production,
}

type Spec struct {
ClientId string `json:"client_id"`
Secret string `json:"secret"`
Environment string `json:"environment"`
}

func (s *Spec) SetDefaults() {
if s.Environment == "" {
s.Environment = "sandbox"
}
}

func (s *Spec) Validate() error {
errors := make([]string, 0)
if s.ClientId == "" {
errors = append(errors, `"client_id" is required`)
}

if s.Secret == "" {
errors = append(errors, `"secret" is required`)
}

if _, ok := Environments[s.Environment]; !ok {
validValues := maps.Keys(Environments)
sort.Strings(validValues)
errors = append(errors, fmt.Sprintf(`invalid "environment". Expected one of %q, got %q`, validValues, s.Environment))
}

if len(errors) > 0 {
return fmt.Errorf("invalid plugin spec: %s", strings.Join(errors, ". "))
}

return nil
}
62 changes: 62 additions & 0 deletions client/testing.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package client

import (
"context"
"net/http/httptest"
"os"
"strings"
"testing"
"time"

"github.com/cloudquery/plugin-sdk/plugins/source"
"github.com/cloudquery/plugin-sdk/schema"
"github.com/cloudquery/plugin-sdk/specs"
"github.com/plaid/plaid-go/v10/plaid"
"github.com/rs/zerolog"
)

func TestHelper(t *testing.T, table *schema.Table, ts *httptest.Server) {
version := "vDev"
table.IgnoreInTests = false
t.Helper()
l := zerolog.New(zerolog.NewTestWriter(t)).Output(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.StampMicro}).Level(zerolog.DebugLevel).With().Timestamp().Logger()

newTestExecutionClient := func(ctx context.Context, logger zerolog.Logger, spec specs.Source, opts source.Options) (schema.ClientMeta, error) {
configuration := plaid.NewConfiguration()
configuration.UseEnvironment(plaid.Development)
urlParts := strings.Split(ts.URL, "://")
configuration.Scheme = urlParts[0]
configuration.Host = urlParts[1]
client := plaid.NewAPIClient(configuration)
s := Spec{
ClientId: "test",
Secret: "test",
}
s.SetDefaults()
err := s.Validate()
if err != nil {
return nil, err
}
return &Client{
Logger: l,
Services: client,
ClientId: s.ClientId,
Secret: s.Secret,
}, nil
}
p := source.NewPlugin(
table.Name,
version,
[]*schema.Table{
table,
},
newTestExecutionClient)
p.SetLogger(l)
source.TestPluginSync(t, p, specs.Source{
Name: "dev",
Path: "cloudquery/dev",
Version: version,
Tables: []string{table.Name},
Destinations: []string{"mock-destination"},
})
}
5 changes: 5 additions & 0 deletions docs/tables/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Source Plugin: plaid

## Tables

- [plaid_wallets](plaid_wallets.md)
17 changes: 17 additions & 0 deletions docs/tables/plaid_wallets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Table: plaid_wallets

The primary key for this table is **wallet_id**.

## Columns

| Name | Type |
| ------------- | ------------- |
|_cq_source_name|String|
|_cq_sync_time|Timestamp|
|_cq_id|UUID|
|_cq_parent_id|UUID|
|wallet_id (PK)|String|
|balance|JSON|
|numbers|JSON|
|recipient_id|String|
|additional_properties|JSON|
36 changes: 36 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
module github.com/cloudquery/cq-source-plaid

go 1.19

require (
github.com/cloudquery/plugin-sdk v1.28.0
github.com/plaid/plaid-go/v10 v10.3.0
github.com/rs/zerolog v1.28.0
golang.org/x/exp v0.0.0-20221230185412-738e83a70c30
)

require (
github.com/getsentry/sentry-go v0.16.0 // indirect
github.com/ghodss/yaml v1.0.0 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware/providers/zerolog/v2 v2.0.0-rc.3 // indirect
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/cobra v1.6.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/thoas/go-funk v0.9.3 // indirect
golang.org/x/net v0.4.0 // indirect
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.3.0 // indirect
golang.org/x/text v0.5.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef // indirect
google.golang.org/grpc v1.51.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)
Loading