npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

team-connect

v0.1.0

Published

SharePoint file browser for React/Next.js — browse, upload, download, and manage files via a local Go proxy with zero Azure AD app registration.

Readme

team-connect

SharePoint file browser for React / Next.js — browse, upload, download and manage files through a local Go proxy.
No Azure AD app registration required. Auth is handled by gosip's interactive browser login (FedAuth cookies).


How it works

┌──────────────┐       ┌──────────────┐       ┌───────────────────┐
│  React app   │──────▶│  Go proxy    │──────▶│  SharePoint REST  │
│  (port 3000) │  HTTP │  (port 8080) │ Auth  │  API (/_api/web)  │
└──────────────┘       └──────────────┘       └───────────────────┘
  1. The Go proxy starts, opens Chrome, you log in with SSO — gosip captures the FedAuth cookie.
  2. All SharePoint REST calls from your React app go through http://localhost:8080/sp/….
  3. The proxy injects auth headers and forwards requests to SharePoint.

Quick start

1. Install

npm install team-connect

2. Set up the Go proxy

Prerequisites: Go 1.19+

# Clone gosip-sandbox (provides the ondemand auth strategy)
git clone https://github.com/koltyakov/gosip-sandbox.git

# Copy the proxy from the package (or from the repo)
cp -r node_modules/team-connect/proxy ./team-connect-proxy
cd team-connect-proxy

Edit config/private.json with your SharePoint site URL:

{
  "siteUrl": "https://yourtenant.sharepoint.com/sites/YourSite"
}

Update the replace directive in go.mod to point to your local gosip-sandbox path:

replace github.com/koltyakov/gosip-sandbox => /path/to/gosip-sandbox

Build and run:

go build -o proxy .
./proxy

Chrome will open — log in with your org account. The proxy will confirm:

Connected to: Your Site (https://yourtenant.sharepoint.com/sites/YourSite)
Proxy listening on http://localhost:8080

3. Add environment variables

In your Next.js .env.local:

NEXT_PUBLIC_PROXY_URL=http://localhost:8080
NEXT_PUBLIC_SHAREPOINT_DOCUMENT_LIBRARY=Shared Documents
NEXT_PUBLIC_SHAREPOINT_FOLDER_PATH=Your Folder Name

4. Use in your app

Option A: Drop-in file browser (full UI)

"use client";

import { useEffect } from "react";
import { useFiles, AuthBar, FileBrowser } from "team-connect";

export default function Page() {
  const fileState = useFiles();

  useEffect(() => {
    fileState.checkConnection().then((ok) => {
      if (ok) fileState.fetchFiles("");
    });
  }, []);

  return (
    <div>
      <AuthBar proxyConnected={fileState.proxyConnected} />
      <FileBrowser fileState={fileState} />
    </div>
  );
}

Option B: Headless — just the hook

"use client";

import { useFiles } from "team-connect";

export default function MyComponent() {
  const {
    files,
    loading,
    currentPath,
    proxyConnected,
    checkConnection,
    fetchFiles,
    uploadFile,
    createNewFolder,
    deleteFile,
    downloadFile,
    search,
  } = useFiles();

  // Build your own UI using the file state and actions
}

Option C: Direct API (no React)

import {
  checkProxyHealth,
  listFiles,
  uploadFile,
  downloadFile,
  createFolder,
  deleteItem,
  searchFiles,
} from "team-connect";

// Check proxy is running
const ok = await checkProxyHealth();

// List files in a subfolder
const files = await listFiles("Reports/Q1");

// Upload a file
await uploadFile(myFile, "Reports/Q1");

// Download
await downloadFile("/sites/MySite/Shared Documents/report.pdf", "report.pdf");

// Create folder
await createFolder("Q2", "Reports");

// Delete
await deleteItem("/sites/MySite/Shared Documents/old.xlsx", false);

// Search
const results = await searchFiles("invoice");

Components

| Component | Props | Description | |-----------|-------|-------------| | AuthBar | proxyConnected: boolean \| null | Top bar with connection status indicator (green/yellow/red) | | FileBrowser | fileState: UseFilesReturn | Full file browser with breadcrumbs, search, upload zone, file list | | FileList | files, loading, onFolderClick, onDownload, onDelete | Table of files and folders with actions | | Breadcrumbs | items: BreadcrumbItem[], onNavigate | Clickable path breadcrumbs | | SearchBar | onSearch, onClear | Debounced search input | | UploadZone | onUpload, uploading? | Drag-and-drop file upload area |

All components use Tailwind CSS classes. Make sure Tailwind is configured in your project.


Hook: useFiles()

Returns:

| Property | Type | Description | |----------|------|-------------| | files | FileItem[] | Current file listing | | loading | boolean | Loading state | | currentPath | string | Current subfolder path | | proxyConnected | boolean \| null | Proxy status (null = checking) | | checkConnection() | () => Promise<boolean> | Ping the proxy health endpoint | | fetchFiles(path) | (path: string) => Promise<void> | Load files at path | | uploadFile(file, path) | (file: File, path: string) => Promise<void> | Upload a file | | createNewFolder(name, path) | (name: string, path: string) => Promise<void> | Create a folder | | deleteFile(url, name, isFolder) | (...) => Promise<void> | Delete a file or folder | | downloadFile(url, name) | (...) => Promise<void> | Download a file | | search(query) | (query: string) => Promise<void> | Search files by name |


Types

interface FileItem {
  id: string;
  name: string;
  size: number;
  lastModifiedDateTime: string;
  lastModifiedBy: { displayName: string; email?: string };
  webUrl: string;
  serverRelativeUrl: string;
  isFolder: boolean;
  mimeType?: string;
}

interface BreadcrumbItem {
  name: string;
  path: string;
}

Proxy API

The Go proxy exposes two endpoints:

| Endpoint | Description | |----------|-------------| | GET /health | Returns { status, siteUrl, serverRelativeUrl } | | * /sp/… | Proxies any request to {siteUrl}/… with auth injected |

Proxy flags

./proxy --strategy ondemand --config ./config/private.json --port 8080

| Flag | Default | Description | |------|---------|-------------| | --strategy | ondemand | gosip auth strategy | | --config | ./config/private.json | Path to auth config | | --port | 8080 | Proxy listen port |


Styling

Components use Tailwind CSS utility classes. Ensure your project has Tailwind configured. The components use only standard Tailwind classes — no custom theme extensions required.


Project structure

team-connect/
├── index.ts              # Library entry point
├── types/index.ts        # TypeScript types
├── lib/
│   ├── sp-client.ts      # SharePoint REST API client
│   └── utils.ts          # Formatting helpers
├── hooks/
│   └── useFiles.ts       # React hook
├── components/
│   ├── AuthBar.tsx        # Connection status bar
│   ├── Breadcrumbs.tsx    # Path navigation
│   ├── FileBrowser.tsx    # Main file browser
│   ├── FileList.tsx       # File table
│   ├── SearchBar.tsx      # Search input
│   └── UploadZone.tsx     # Drag-and-drop upload
├── proxy/
│   ├── main.go            # Go proxy server
│   ├── go.mod
│   └── config/
│       └── private.json   # SharePoint site URL
├── app/                   # Demo Next.js app
│   ├── page.tsx
│   └── layout.tsx
└── smoke-test.sh          # Connectivity test

Running the demo app

# Terminal 1: Start the proxy
cd proxy && ./team-connect-proxy

# Terminal 2: Start Next.js
npm run dev
# Open http://localhost:3000

Smoke test

# With the proxy running:
bash smoke-test.sh

License

MIT