Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Add File Upload Support

未关闭
#36 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
5/5
预计耗时
一周以上
新手友好度
30/100
Issue 类型
功能
描述清晰度
基本清楚
活跃度
停滞
技术栈
react, typescript
领域
frontend

调研方向

首先定位现有的 useStacValue hook 及其当前的 URL 获取路径;该 issue 未指定源文件或测试路径。比较提议的 file、URL 和 JSON 输入,然后为加载、无效 file、验证、并发输入和 file 大小添加有针对性的覆盖,并补充关于 upload 和拖放用法的文档。

由索引模型根据 Issue 内容生成。

描述

Problem

stac-react currently only supports fetching STAC resources from URLs. There's no support for:

  • Loading STAC JSON from uploaded files
  • Exploring local STAC catalogs
  • Working with STAC files without hosting them
  • Development and testing with local files

Projects like stac-map need to allow users to drag-and-drop or upload STAC JSON files for immediate visualization without requiring the files to be hosted.

Current Behavior

// Only URL-based fetching is supported
const { collection } = useCollection('collection-id'); // Requires API
const { item } = useItem('https://example.com/item.json'); // Requires URL

No way to load from File objects or FileList.

Desired Behavior

import { useStacValue } from '@developmentseed/stac-react';

function StacFileUploader() {
  const [file, setFile] = useState<File | null>(null);
  
  const { value, isLoading, error } = useStacValue({
    file: file,
  });
  
  return (
    <div>
      <input 
        type="file" 
        accept=".json,application/json"
        onChange={(e) => setFile(e.target.files?.[0])}
      />
      {value && <StacViewer value={value} />}
    </div>
  );
}

Use Cases from stac-map

stac-map supports file uploads via:

const fileUpload = useFileUpload({ maxFiles: 1 });

const { value, error } = useStacValue({
  href,
  fileUpload, // Handles uploaded files
});

// In the UI:
<FileUpload.Dropzone>
  <Map value={value} />
</FileUpload.Dropzone>

Proposed Solution

Enhanced Hook Signature
type UseStacValueOptions = {
  // URL-based
  url?: string;
  
  // File-based
  file?: File;
  
  // Raw JSON
  json?: object;
  
  // Fetch options (for URL)
  headers?: Record<string, string>;
  method?: 'GET' | 'POST';
  body?: unknown;
};

function useStacValue(options: UseStacValueOptions): UseStacValueResult;
Implementation
import { useQuery } from '@tanstack/react-query';

function useStacValue(options: UseStacValueOptions): UseStacValueResult {
  const { url, file, json, headers, method, body } = options;
  
  const { data, error, isLoading, isFetching, refetch } = useQuery({
    queryKey: ['stac-value', url, file?.name, json, method],
    queryFn: async () => {
      let value: any;
      
      if (json) {
        // Direct JSON object
        value = json;
      } else if (file) {
        // File upload
        const text = await file.text();
        value = JSON.parse(text);
      } else if (url) {
        // URL fetch
        const response = await fetch(url, {
          method: method || 'GET',
          headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
            ...headers,
          },
          body: body ? JSON.stringify(body) : undefined,
        });
        
        if (!response.ok) {
          throw new ApiError(
            response.statusText,
            response.status,
            await response.text(),
            response.url
          );
        }
        
        value = await response.json();
      } else {
        throw new Error('Must provide url, file, or json');
      }
      
      return {
        value,
        type: determineStacType(value),
      };
    },
    enabled: !!(url || file || json),
    retry: false,
  });

  return {
    value: data?.value,
    type: data?.type,
    isLoading,
    isFetching,
    error,
    refetch,
  };
}
Example Usage Patterns
1. File Input
function FileUploadExample() {
  const [file, setFile] = useState<File | null>(null);
  const { value, isLoading, error } = useStacValue({ file });
  
  return (
    <div>
      <input 
        type="file" 
        onChange={(e) => setFile(e.target.files?.[0] || null)}
      />
      {isLoading && <p>Loading...</p>}
      {error && <p>Error: {error.message}</p>}
      {value && <pre>{JSON.stringify(value, null, 2)}</pre>}
    </div>
  );
}
2. Drag and Drop
function DragDropExample() {
  const [file, setFile] = useState<File | null>(null);
  const { value } = useStacValue({ file });
  
  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault();
    const droppedFile = e.dataTransfer.files[0];
    if (droppedFile?.type === 'application/json') {
      setFile(droppedFile);
    }
  };
  
  return (
    <div 
      onDrop={handleDrop}
      onDragOver={(e) => e.preventDefault()}
    >
      Drop STAC JSON file here
      {value && <StacViewer value={value} />}
    </div>
  );
}
3. Combined URL and File
function FlexibleLoader({ url, file }) {
  // Automatically uses file if provided, otherwise URL
  const { value, isLoading } = useStacValue({ 
    url: !file ? url : undefined,
    file: file,
  });
  
  return <div>{/* ... */}</div>;
}

File Validation

Add optional validation:

function validateStacFile(file: File): Promise<boolean> {
  return new Promise((resolve) => {
    if (!file.name.endsWith('.json')) {
      resolve(false);
      return;
    }
    
    const reader = new FileReader();
    reader.onload = (e) => {
      try {
        const json = JSON.parse(e.target?.result as string);
        // Check for STAC required fields
        resolve(
          json.type && 
          json.stac_version &&
          json.links
        );
      } catch {
        resolve(false);
      }
    };
    reader.readAsText(file);
  });
}

Benefits

  • ✅ Load STAC from uploaded files
  • ✅ Support drag-and-drop workflows
  • ✅ Enable offline/local STAC exploration
  • ✅ Simplify development and testing
  • ✅ Support in-memory STAC objects
  • ✅ Maintain URL-based fetching

Breaking Changes

None - this extends existing functionality with backward compatibility.

Testing Requirements

  • Test loading from File objects
  • Test loading from URL
  • Test loading from JSON objects
  • Test error handling for invalid files
  • Test file validation
  • Test with different file sizes
  • Test concurrent file and URL loading

Documentation Requirements

  • Document file upload patterns
  • Provide drag-and-drop examples
  • Document file validation
  • Show integration with file input libraries
  • Document security considerations
主要语言
TypeScript
星标
35
派生
4
PR 合并指标
30 天内没有已合并 PR

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

developmentseed/stac-react 的其他 Issue

查看 developmentseed/stac-react 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。