Inline Vercel driver URL with url.URL → Drop allowedHosts:true from vite dev server
- Inline Vercel driver URL with url.URL - Escape URL path segments in connector name resolvers - Dedup Vercel /v2/user fallback in name resolver - Drop allowedHosts:true from vite dev server Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
This commit is contained in:
@@ -55,7 +55,6 @@ export default defineConfig({
|
|||||||
tailwindcss(),
|
tailwindcss(),
|
||||||
],
|
],
|
||||||
server: {
|
server: {
|
||||||
allowedHosts: true,
|
|
||||||
proxy: {
|
proxy: {
|
||||||
"/api": {
|
"/api": {
|
||||||
target: "http://localhost:8080",
|
target: "http://localhost:8080",
|
||||||
|
|||||||
@@ -20,10 +20,12 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
admin "google.golang.org/api/admin/directory/v1"
|
admin "google.golang.org/api/admin/directory/v1"
|
||||||
"google.golang.org/api/option"
|
"google.golang.org/api/option"
|
||||||
|
|
||||||
|
"go.probo.inc/probo/pkg/connector"
|
||||||
"go.probo.inc/probo/pkg/coredata"
|
"go.probo.inc/probo/pkg/coredata"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -618,9 +620,9 @@ func (r *gitlabNameResolver) ResolveInstanceName(ctx context.Context) (string, e
|
|||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
url := fmt.Sprintf("https://gitlab.com/api/v4/groups/%s", r.groupID)
|
endpoint := fmt.Sprintf("https://gitlab.com/api/v4/groups/%s", url.PathEscape(r.groupID))
|
||||||
|
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("cannot create gitlab group request: %w", err)
|
return "", fmt.Errorf("cannot create gitlab group request: %w", err)
|
||||||
}
|
}
|
||||||
@@ -665,9 +667,9 @@ func (r *bitbucketNameResolver) ResolveInstanceName(ctx context.Context) (string
|
|||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
url := fmt.Sprintf("https://api.bitbucket.org/2.0/workspaces/%s", r.workspace)
|
endpoint := fmt.Sprintf("https://api.bitbucket.org/2.0/workspaces/%s", url.PathEscape(r.workspace))
|
||||||
|
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("cannot create bitbucket workspace request: %w", err)
|
return "", fmt.Errorf("cannot create bitbucket workspace request: %w", err)
|
||||||
}
|
}
|
||||||
@@ -712,9 +714,9 @@ func (r *herokuNameResolver) ResolveInstanceName(ctx context.Context) (string, e
|
|||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
url := fmt.Sprintf("https://api.heroku.com/teams/%s", r.teamID)
|
endpoint := fmt.Sprintf("https://api.heroku.com/teams/%s", url.PathEscape(r.teamID))
|
||||||
|
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("cannot create heroku team request: %w", err)
|
return "", fmt.Errorf("cannot create heroku team request: %w", err)
|
||||||
}
|
}
|
||||||
@@ -770,9 +772,9 @@ func (r *asanaNameResolver) ResolveInstanceName(ctx context.Context) (string, er
|
|||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
url := fmt.Sprintf("https://app.asana.com/api/1.0/workspaces/%s", r.workspaceGID)
|
endpoint := fmt.Sprintf("https://app.asana.com/api/1.0/workspaces/%s", url.PathEscape(r.workspaceGID))
|
||||||
|
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("cannot create asana workspace request: %w", err)
|
return "", fmt.Errorf("cannot create asana workspace request: %w", err)
|
||||||
}
|
}
|
||||||
@@ -815,9 +817,9 @@ func (r *snykNameResolver) ResolveInstanceName(ctx context.Context) (string, err
|
|||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
url := fmt.Sprintf("https://api.snyk.io/rest/orgs/%s?version=2024-10-15", r.orgID)
|
endpoint := fmt.Sprintf("https://api.snyk.io/rest/orgs/%s?version=2024-10-15", url.PathEscape(r.orgID))
|
||||||
|
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("cannot create snyk org request: %w", err)
|
return "", fmt.Errorf("cannot create snyk org request: %w", err)
|
||||||
}
|
}
|
||||||
@@ -862,9 +864,9 @@ func (r *netlifyNameResolver) ResolveInstanceName(ctx context.Context) (string,
|
|||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
url := fmt.Sprintf("https://api.netlify.com/api/v1/accounts/%s", r.accountSlug)
|
endpoint := fmt.Sprintf("https://api.netlify.com/api/v1/accounts/%s", url.PathEscape(r.accountSlug))
|
||||||
|
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("cannot create netlify account request: %w", err)
|
return "", fmt.Errorf("cannot create netlify account request: %w", err)
|
||||||
}
|
}
|
||||||
@@ -950,9 +952,9 @@ func (r *clickupNameResolver) ResolveInstanceName(ctx context.Context) (string,
|
|||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
url := fmt.Sprintf("https://api.clickup.com/api/v2/team/%s", r.teamID)
|
endpoint := fmt.Sprintf("https://api.clickup.com/api/v2/team/%s", url.PathEscape(r.teamID))
|
||||||
|
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("cannot create clickup team request: %w", err)
|
return "", fmt.Errorf("cannot create clickup team request: %w", err)
|
||||||
}
|
}
|
||||||
@@ -998,7 +1000,7 @@ func (r *vercelNameResolver) ResolveInstanceName(ctx context.Context) (string, e
|
|||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
teamURL := fmt.Sprintf("https://api.vercel.com/v2/teams/%s", r.teamID)
|
teamURL := fmt.Sprintf("https://api.vercel.com/v2/teams/%s", url.PathEscape(r.teamID))
|
||||||
teamReq, err := http.NewRequestWithContext(ctx, http.MethodGet, teamURL, nil)
|
teamReq, err := http.NewRequestWithContext(ctx, http.MethodGet, teamURL, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("cannot create vercel team request: %w", err)
|
return "", fmt.Errorf("cannot create vercel team request: %w", err)
|
||||||
@@ -1031,36 +1033,14 @@ func (r *vercelNameResolver) ResolveInstanceName(ctx context.Context) (string, e
|
|||||||
|
|
||||||
// Personal-account fallback: /v2/teams/<uid> returns 404, but
|
// Personal-account fallback: /v2/teams/<uid> returns 404, but
|
||||||
// /v2/user works with the same Bearer token.
|
// /v2/user works with the same Bearer token.
|
||||||
userReq, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://api.vercel.com/v2/user", nil)
|
user, err := connector.FetchVercelUser(ctx, r.httpClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("cannot create vercel user request: %w", err)
|
return "", err
|
||||||
}
|
}
|
||||||
userReq.Header.Set("Accept", "application/json")
|
if user.Username != "" {
|
||||||
|
return user.Username, nil
|
||||||
userResp, err := r.httpClient.Do(userReq)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("cannot execute vercel user request: %w", err)
|
|
||||||
}
|
}
|
||||||
defer func() { _ = userResp.Body.Close() }()
|
return user.Name, nil
|
||||||
|
|
||||||
if userResp.StatusCode < 200 || userResp.StatusCode >= 300 {
|
|
||||||
return "", fmt.Errorf("cannot fetch vercel user: unexpected status %d", userResp.StatusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
var userBody struct {
|
|
||||||
User struct {
|
|
||||||
Username string `json:"username"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
} `json:"user"`
|
|
||||||
}
|
|
||||||
if err := json.NewDecoder(userResp.Body).Decode(&userBody); err != nil {
|
|
||||||
return "", fmt.Errorf("cannot decode vercel user response: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if userBody.User.Username != "" {
|
|
||||||
return userBody.User.Username, nil
|
|
||||||
}
|
|
||||||
return userBody.User.Name, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// mondayNameResolver resolves the Monday.com account name via GraphQL.
|
// mondayNameResolver resolves the Monday.com account name via GraphQL.
|
||||||
|
|||||||
@@ -74,11 +74,10 @@ type vercelMembersPage struct {
|
|||||||
func (d *VercelDriver) ListAccounts(ctx context.Context) ([]AccountRecord, error) {
|
func (d *VercelDriver) ListAccounts(ctx context.Context) ([]AccountRecord, error) {
|
||||||
var records []AccountRecord
|
var records []AccountRecord
|
||||||
|
|
||||||
base := fmt.Sprintf("https://api.vercel.com/v3/teams/%s/members", url.PathEscape(d.teamID))
|
|
||||||
cursor := ""
|
cursor := ""
|
||||||
|
|
||||||
for range maxPaginationPages {
|
for range maxPaginationPages {
|
||||||
page, err := d.queryMembers(ctx, base, cursor)
|
page, err := d.queryMembers(ctx, cursor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -114,15 +113,20 @@ func (d *VercelDriver) ListAccounts(ctx context.Context) ([]AccountRecord, error
|
|||||||
return nil, fmt.Errorf("cannot list all vercel accounts: %w", ErrPaginationLimitReached)
|
return nil, fmt.Errorf("cannot list all vercel accounts: %w", ErrPaginationLimitReached)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *VercelDriver) queryMembers(ctx context.Context, base, cursor string) (*vercelMembersPage, error) {
|
func (d *VercelDriver) queryMembers(ctx context.Context, cursor string) (*vercelMembersPage, error) {
|
||||||
q := url.Values{}
|
q := url.Values{}
|
||||||
q.Set("limit", "100")
|
q.Set("limit", "100")
|
||||||
if cursor != "" {
|
if cursor != "" {
|
||||||
q.Set("until", cursor)
|
q.Set("until", cursor)
|
||||||
}
|
}
|
||||||
endpoint := base + "?" + q.Encode()
|
u := url.URL{
|
||||||
|
Scheme: "https",
|
||||||
|
Host: "api.vercel.com",
|
||||||
|
Path: "/v3/teams/" + d.teamID + "/members",
|
||||||
|
RawQuery: q.Encode(),
|
||||||
|
}
|
||||||
|
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot create vercel members request: %w", err)
|
return nil, fmt.Errorf("cannot create vercel members request: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user