@databiosphere/findable-ui 50.6.0 → 50.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +6 -1
- package/.eslintignore +0 -5
- package/.eslintrc.json +0 -79
- package/.github/copilot-instructions.md +0 -176
- package/.github/workflows/release-please.yml +0 -49
- package/.github/workflows/run-checks.yml +0 -57
- package/.husky/commit-msg +0 -18
- package/.husky/pre-commit +0 -43
- package/.prettierignore +0 -19
- package/.prettierrc.json +0 -1
- package/.release-please-manifest.json +0 -3
- package/.storybook/main.ts +0 -10
- package/.storybook/preview-head.html +0 -4
- package/.storybook/preview.js +0 -6
- package/CHANGELOG.md +0 -1117
- package/CLAUDE.md +0 -214
- package/backend/README.md +0 -64
- package/backend/__init__.py +0 -0
- package/backend/controllers/__init__.py +0 -0
- package/backend/controllers/facets_controller.py +0 -16
- package/backend/controllers/models.py +0 -11
- package/backend/main.py +0 -8
- package/backend/requirements.txt +0 -4
- package/backend/services/__init__.py +0 -0
- package/backend/services/facets_service.py +0 -68
- package/backend/services/models.py +0 -43
- package/commitlint.config.js +0 -1
- package/docs/TRUSTED_PUBLISHING.md +0 -132
- package/jest.config.js +0 -6
- package/release-please-config.json +0 -23
- package/tests/azulFileDownload.test.tsx +0 -96
- package/tests/buildCategoryViews.test.ts +0 -282
- package/tests/buildRequestFilters.test.ts +0 -60
- package/tests/buildRequestManifest.test.ts +0 -103
- package/tests/chart.test.tsx +0 -274
- package/tests/chartSortUtils.test.ts +0 -119
- package/tests/chartView.test.tsx +0 -48
- package/tests/dataDictionaryColumnFilters.test.tsx +0 -101
- package/tests/dataDictionary_utils.test.ts +0 -153
- package/tests/fetchApi.test.ts +0 -93
- package/tests/filter.test.tsx +0 -100
- package/tests/filterMenu.test.ts +0 -100
- package/tests/filterRange.test.tsx +0 -372
- package/tests/filterSortUtils.test.ts +0 -180
- package/tests/filters.test.tsx +0 -61
- package/tests/getFacetedMinMaxValues.test.ts +0 -166
- package/tests/getFilterSortType.test.ts +0 -45
- package/tests/getProfileStatus.test.ts +0 -290
- package/tests/linkCell.test.tsx +0 -89
- package/tests/markdownCell.test.tsx +0 -52
- package/tests/provider.test.tsx +0 -189
- package/tests/research.chatState.test.ts +0 -463
- package/tests/research.fetchResponse.test.ts +0 -164
- package/tests/research.queryProvider.test.ts +0 -321
- package/tests/research.useKeyShortCuts.test.ts +0 -256
- package/tests/rowSelectionValidation.test.ts +0 -282
- package/tests/setup.ts +0 -19
- package/tests/stepIcon.test.tsx +0 -42
- package/tests/tableFilter.test.tsx +0 -90
- package/tests/terraProfileProvider.test.tsx +0 -117
- package/tests/theme.test.ts +0 -465
- package/tests/toggleButtonGroupProvider.test.tsx +0 -125
- package/tests/transformRoute.test.ts +0 -21
- package/tests/tsconfig.json +0 -8
- package/tests/useFileLocation.test.ts +0 -36
- package/tests/useRequestManifest.test.ts +0 -201
- package/tests/useRouteHistory.test.ts +0 -97
- package/tests/useSessionActive.test.ts +0 -106
- package/tests/useWindowResize.test.ts +0 -130
- package/tests/viewModelBuilders_utils.test.ts +0 -58
- package/tests/viewToggle.test.tsx +0 -54
- package/tsconfig.json +0 -25
package/CLAUDE.md
DELETED
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
# CLAUDE.md
|
|
2
|
-
|
|
3
|
-
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
-
|
|
5
|
-
## Repository Overview
|
|
6
|
-
|
|
7
|
-
This is a TypeScript library package (`@databiosphere/findable-ui`) that provides reusable UI components and utilities for Data Biosphere applications, particularly the Data Browser. It compiles TypeScript source from `src/` to JavaScript in `lib/` for distribution as an npm package.
|
|
8
|
-
|
|
9
|
-
**Key Facts:**
|
|
10
|
-
|
|
11
|
-
- **Node Version:** 22.12.0 (enforced by package.json)
|
|
12
|
-
- **UI Framework:** React 18 with Material-UI v7 and Emotion for styling
|
|
13
|
-
- **Build System:** TypeScript compiler (`tsc`) with strict mode enabled
|
|
14
|
-
- **Import Pattern:** External apps import as `@databiosphere/findable-ui/lib/<path>`
|
|
15
|
-
|
|
16
|
-
## Development Commands
|
|
17
|
-
|
|
18
|
-
### Essential Commands
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
# Install dependencies (use ci for clean install)
|
|
22
|
-
npm ci
|
|
23
|
-
|
|
24
|
-
# Compile TypeScript to lib/ directory
|
|
25
|
-
npx tsc
|
|
26
|
-
|
|
27
|
-
# Run all validation checks
|
|
28
|
-
npm run check-format # Prettier formatting check
|
|
29
|
-
npm run lint # ESLint with TypeScript and SonarJS plugins
|
|
30
|
-
npm run test # Jest with React Testing Library
|
|
31
|
-
npm run test-compile # TypeScript compilation check (no emit)
|
|
32
|
-
|
|
33
|
-
# Development tools
|
|
34
|
-
npm run storybook # Launch Storybook on port 6006
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
### Running Single Tests
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
# Run specific test file
|
|
41
|
-
npm test -- path/to/file.test.ts
|
|
42
|
-
|
|
43
|
-
# Run tests in watch mode
|
|
44
|
-
npm test -- --watch
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
### Local Development with Data Browser
|
|
48
|
-
|
|
49
|
-
When developing alongside the Data Browser:
|
|
50
|
-
|
|
51
|
-
1. Clone both repos in the same parent directory
|
|
52
|
-
2. In findable-ui: `npm update && npx tsc`
|
|
53
|
-
3. In data-browser/explorer: `npm link ../findable-ui`
|
|
54
|
-
4. Rerun `npm link` if you install/uninstall packages (symlink gets removed)
|
|
55
|
-
5. May need to comment out `@tanstack/react-table` in Data Browser's `next.config.mjs` webpack config
|
|
56
|
-
|
|
57
|
-
**Important:** Run `npx tsc` whenever you make changes to source files that need testing in consuming apps.
|
|
58
|
-
|
|
59
|
-
## Code Architecture
|
|
60
|
-
|
|
61
|
-
### Directory Structure
|
|
62
|
-
|
|
63
|
-
- **`/src`** - TypeScript source (compiles to `/lib`)
|
|
64
|
-
- `/components` - React UI components (organized by feature)
|
|
65
|
-
- `/hooks` - Custom React hooks (useAsync, useExploreMode, etc.)
|
|
66
|
-
- `/providers` - React context providers for state management
|
|
67
|
-
- `/theme` - MUI theme configuration
|
|
68
|
-
- `/config` - Configuration entities and utilities
|
|
69
|
-
- `/apis` - API client code (e.g., Azul API integration)
|
|
70
|
-
- `/entity` - Entity service layer (api, service, common, tsv, apicf subdirectories)
|
|
71
|
-
- `/viewModelBuilders` - Transform API responses to view models
|
|
72
|
-
- `/views` - Page-level components
|
|
73
|
-
- `/utils` - Utility functions
|
|
74
|
-
- `/types` - TypeScript type definitions
|
|
75
|
-
- `/routes` - Routing utilities
|
|
76
|
-
- `/services` - Business logic services
|
|
77
|
-
- `/common` - Shared utilities (analytics, categories, filters, etc.)
|
|
78
|
-
- `/styles` - Global styles
|
|
79
|
-
- **`/tests`** - Jest test files (separate from src, not co-located)
|
|
80
|
-
- **`/lib`** - Compiled JavaScript output (git-ignored, generated by tsc)
|
|
81
|
-
|
|
82
|
-
### Key Architectural Patterns
|
|
83
|
-
|
|
84
|
-
**Entity Service Layer:** The `/entity` directory contains a service-oriented architecture for data fetching and transformation:
|
|
85
|
-
|
|
86
|
-
- `api/` - API-based entity services
|
|
87
|
-
- `service/` - Service factory and models
|
|
88
|
-
- `common/` - Shared client utilities
|
|
89
|
-
- `tsv/` - TSV-specific services
|
|
90
|
-
- `apicf/` - API custom field services
|
|
91
|
-
|
|
92
|
-
**Configuration-Driven Components:** Many components are driven by config objects defined in `/config/entities.ts`. This includes analytics, authentication, export methods, and layout configuration.
|
|
93
|
-
|
|
94
|
-
**Provider Architecture:** State management uses React Context providers (authentication, exploreState, fileManifestState, dataDictionary, etc.) located in `/providers`.
|
|
95
|
-
|
|
96
|
-
**Analytics:** Google Analytics 4 integration via `src/common/analytics/`. Events are defined in entities.ts and tracked via the `track` function. See `src/common/analytics/readme-analytics.md` for event inventory.
|
|
97
|
-
|
|
98
|
-
## Code Style Requirements
|
|
99
|
-
|
|
100
|
-
### TypeScript Standards
|
|
101
|
-
|
|
102
|
-
**Strict Mode Enforcement:**
|
|
103
|
-
|
|
104
|
-
- All TypeScript strict checks enabled
|
|
105
|
-
- **Explicit return types required** for all functions (except `.styles.ts(x)` files)
|
|
106
|
-
- No `any` type (exceptions allowed in test files)
|
|
107
|
-
- Strict null checks enforced
|
|
108
|
-
|
|
109
|
-
**Sorting Requirements (ESLint enforced):**
|
|
110
|
-
|
|
111
|
-
- Object keys must be sorted alphabetically
|
|
112
|
-
- Destructured keys must be sorted
|
|
113
|
-
- Interface properties must be sorted
|
|
114
|
-
- String enums must be sorted
|
|
115
|
-
- Imports auto-organized by prettier-plugin-organize-imports
|
|
116
|
-
|
|
117
|
-
**File Naming:** Use kebab-case (e.g., `my-component.tsx`)
|
|
118
|
-
|
|
119
|
-
### JSDoc Documentation
|
|
120
|
-
|
|
121
|
-
**Required for all functions:**
|
|
122
|
-
|
|
123
|
-
```typescript
|
|
124
|
-
/**
|
|
125
|
-
* Transforms a route by removing inactivity parameters.
|
|
126
|
-
* @param routes - Array of route strings to transform.
|
|
127
|
-
* @returns The first non-login route without inactivity param, or undefined.
|
|
128
|
-
*/
|
|
129
|
-
function transformRoute(routes: string[]): string | undefined {
|
|
130
|
-
// implementation
|
|
131
|
-
}
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
**Requirements:**
|
|
135
|
-
|
|
136
|
-
- Function description
|
|
137
|
-
- `@param` tags with descriptions (hyphen required before description)
|
|
138
|
-
- `@returns` tag with description
|
|
139
|
-
|
|
140
|
-
### React Patterns
|
|
141
|
-
|
|
142
|
-
- Use functional components with hooks
|
|
143
|
-
- **react-hooks/exhaustive-deps is enforced** - include all dependencies in useEffect, useCallback, useMemo
|
|
144
|
-
- Styling: Use Emotion styled components in `.styles.ts` or `.styles.tsx` files
|
|
145
|
-
- Component structure: Keep components focused and single-responsibility
|
|
146
|
-
|
|
147
|
-
## Testing
|
|
148
|
-
|
|
149
|
-
**Test Location:** Tests live in `/tests` directory (not co-located with source)
|
|
150
|
-
|
|
151
|
-
**Test Framework:** Jest with `@testing-library/react` in jsdom environment
|
|
152
|
-
|
|
153
|
-
**Test Naming:** Use `.test.ts` or `.test.tsx` extension
|
|
154
|
-
|
|
155
|
-
**Global Mocks:** Pre-configured for ResizeObserver, TextEncoder, TextDecoder (see `tests/setup.ts`)
|
|
156
|
-
|
|
157
|
-
**Test Structure:**
|
|
158
|
-
|
|
159
|
-
```typescript
|
|
160
|
-
describe("ComponentName", () => {
|
|
161
|
-
it("should do something specific", () => {
|
|
162
|
-
// Arrange
|
|
163
|
-
const input = "test";
|
|
164
|
-
|
|
165
|
-
// Act
|
|
166
|
-
const result = functionUnderTest(input);
|
|
167
|
-
|
|
168
|
-
// Assert
|
|
169
|
-
expect(result).toBe("expected");
|
|
170
|
-
});
|
|
171
|
-
});
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
## Dependency Management
|
|
175
|
-
|
|
176
|
-
**This is a library package - use peer dependencies carefully.**
|
|
177
|
-
|
|
178
|
-
**Peer Dependencies:** Consuming applications must provide:
|
|
179
|
-
|
|
180
|
-
- React 18.3+
|
|
181
|
-
- Material-UI v7 (@mui/material, @mui/icons-material)
|
|
182
|
-
- Next.js 14.2+ and next-auth
|
|
183
|
-
- Emotion (@emotion/react, @emotion/styled)
|
|
184
|
-
- TanStack Table and Virtual
|
|
185
|
-
- Various utilities (ky, uuid, yup, etc.)
|
|
186
|
-
|
|
187
|
-
**Critical:** New dependencies should go in `peerDependencies` or `devDependencies`, NOT `dependencies`.
|
|
188
|
-
|
|
189
|
-
## Pre-Commit and CI Checks
|
|
190
|
-
|
|
191
|
-
**All PRs must pass:**
|
|
192
|
-
|
|
193
|
-
- Prettier formatting (`npm run check-format`)
|
|
194
|
-
- ESLint with no errors (`npm run lint`)
|
|
195
|
-
- All Jest tests passing (`npm test`)
|
|
196
|
-
- TypeScript compilation (`npm run test-compile`)
|
|
197
|
-
|
|
198
|
-
**Husky hooks:** Pre-commit hooks configured in `.husky/`
|
|
199
|
-
|
|
200
|
-
## Common Pitfalls
|
|
201
|
-
|
|
202
|
-
1. **Don't import from lib/** - Always import from `src/` during development
|
|
203
|
-
2. **Don't add to dependencies** - Use peerDependencies or devDependencies
|
|
204
|
-
3. **Don't disable ESLint rules** without justification
|
|
205
|
-
4. **Don't skip JSDoc** - Required for all public functions
|
|
206
|
-
5. **Don't commit lib/ directory** - It's build output and git-ignored
|
|
207
|
-
6. **Don't skip return types** - Explicit return types required (except .styles files)
|
|
208
|
-
7. **Maintain backward compatibility** - This is a library; breaking changes require major version bumps
|
|
209
|
-
|
|
210
|
-
## Special Notes
|
|
211
|
-
|
|
212
|
-
- **Release Management:** Uses release-please for automated versioning and changelog
|
|
213
|
-
- **Storybook:** Available for component development and visual testing
|
|
214
|
-
- **Import Paths:** Base URL is `./src` (configured in tsconfig.json), allowing absolute imports within src
|
package/backend/README.md
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
# Findable Backend (FastAPI)
|
|
2
|
-
|
|
3
|
-
This folder contains a minimal FastAPI backend that exposes a stubbed **query-to-facets** endpoint for experimentation and PoC work.
|
|
4
|
-
|
|
5
|
-
## Requirements
|
|
6
|
-
|
|
7
|
-
- Python 3.9+
|
|
8
|
-
- `pip`
|
|
9
|
-
|
|
10
|
-
## Set up a Python virtual environment
|
|
11
|
-
|
|
12
|
-
From the repo root:
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
python -m venv backend/.venv
|
|
16
|
-
source backend/.venv/bin/activate
|
|
17
|
-
python -m pip install --upgrade pip
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
## Install dependencies
|
|
21
|
-
|
|
22
|
-
From the repo root:
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
pip install -r backend/requirements.txt
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## Run the server
|
|
29
|
-
|
|
30
|
-
From the repo root:
|
|
31
|
-
|
|
32
|
-
```bash
|
|
33
|
-
uvicorn backend.main:app --reload
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
The app will start on `http://127.0.0.1:8000` by default.
|
|
37
|
-
|
|
38
|
-
## Format code
|
|
39
|
-
|
|
40
|
-
From the repo root:
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
python -m black backend
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### Endpoint
|
|
47
|
-
|
|
48
|
-
- **Method:** `POST`
|
|
49
|
-
- **Path:** `/api/v0/facets`
|
|
50
|
-
- **Request body:**
|
|
51
|
-
|
|
52
|
-
```json
|
|
53
|
-
{ "query": "string" }
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
- **Example request:**
|
|
57
|
-
|
|
58
|
-
```bash
|
|
59
|
-
curl -sS -X POST "http://127.0.0.1:8000/api/v0/facets" \
|
|
60
|
-
-H "Content-Type: application/json" \
|
|
61
|
-
-d '{ "query": "public bam files for latino patients with diabetes" }'
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
- **Response:** currently returns a **hard-coded** JSON structure representing resolved facets for the query. This is intentionally stubbed for PoC and will be replaced by a real implementation later.
|
package/backend/__init__.py
DELETED
|
File without changes
|
|
File without changes
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
from fastapi import APIRouter
|
|
2
|
-
|
|
3
|
-
from backend.services.facets_service import compute_facets_from_query
|
|
4
|
-
from backend.services.models import FacetsResponse
|
|
5
|
-
|
|
6
|
-
from backend.controllers.models import FacetsRequest
|
|
7
|
-
|
|
8
|
-
router = APIRouter(prefix="/api/v0/facets", tags=["facets"])
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
@router.post("")
|
|
12
|
-
def get_facets(payload: FacetsRequest) -> FacetsResponse:
|
|
13
|
-
"""
|
|
14
|
-
Return a stubbed query-to-facets response for PoC purposes.
|
|
15
|
-
"""
|
|
16
|
-
return compute_facets_from_query()
|
package/backend/main.py
DELETED
package/backend/requirements.txt
DELETED
|
File without changes
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from backend.services.models import FacetsResponse
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def compute_facets_from_query() -> FacetsResponse:
|
|
7
|
-
"""Return a stubbed query-to-facets response for PoC purposes.
|
|
8
|
-
|
|
9
|
-
This function will later be replaced by a real implementation that uses
|
|
10
|
-
LLM-backed intent parsing and facet resolution.
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
|
-
return FacetsResponse.model_validate(
|
|
14
|
-
{
|
|
15
|
-
"query": "public bam files for latino foobar patients with diabetes or foobaz",
|
|
16
|
-
"facets": [
|
|
17
|
-
{
|
|
18
|
-
"facet": "Access",
|
|
19
|
-
"selectedValues": [
|
|
20
|
-
{
|
|
21
|
-
"term": "Granted",
|
|
22
|
-
"mention": "public",
|
|
23
|
-
}
|
|
24
|
-
],
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
"facet": "Diagnosis",
|
|
28
|
-
"selectedValues": [
|
|
29
|
-
{
|
|
30
|
-
"term": "MONDO:0005015",
|
|
31
|
-
"mention": "diabetes", # Mention resolved but value does not exist in dev
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
"term": "unknown",
|
|
35
|
-
"mention": "foobaz", # Mention resolved to a disease but does not match a known term
|
|
36
|
-
},
|
|
37
|
-
],
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
"facet": "File Format",
|
|
41
|
-
"selectedValues": [
|
|
42
|
-
{
|
|
43
|
-
"term": ".bam",
|
|
44
|
-
"mention": "bam",
|
|
45
|
-
}
|
|
46
|
-
],
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
"facet": "Reported Ethnicity",
|
|
50
|
-
"selectedValues": [
|
|
51
|
-
{
|
|
52
|
-
"term": "Hispanic or Latino",
|
|
53
|
-
"mention": "latino",
|
|
54
|
-
},
|
|
55
|
-
],
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
"facet": "unknown",
|
|
59
|
-
"selectedValues": [
|
|
60
|
-
{
|
|
61
|
-
"term": "unknown",
|
|
62
|
-
"mention": "foobar", # Mention not resolved to a facet or facet term
|
|
63
|
-
}
|
|
64
|
-
],
|
|
65
|
-
},
|
|
66
|
-
],
|
|
67
|
-
}
|
|
68
|
-
)
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
from pydantic import BaseModel
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
# Model of a selected facet value and its mention (that is, the original query text that resolved to the value).
|
|
5
|
-
class SelectedValue(BaseModel):
|
|
6
|
-
"""
|
|
7
|
-
Represents a selected facet value and its mention in the original query text.
|
|
8
|
-
|
|
9
|
-
Attributes:
|
|
10
|
-
term (str): The resolved facet value.
|
|
11
|
-
mention (str): The original query text that resolved to the value.
|
|
12
|
-
"""
|
|
13
|
-
|
|
14
|
-
term: str
|
|
15
|
-
mention: str
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
# Model of a selected facet and its resolved values.
|
|
19
|
-
class FacetSelection(BaseModel):
|
|
20
|
-
"""
|
|
21
|
-
Represents a selected facet and its resolved values.
|
|
22
|
-
|
|
23
|
-
Attributes:
|
|
24
|
-
facet (str): The name of the facet.
|
|
25
|
-
selectedValues (list[SelectedValue]): The list of selected values for this facet.
|
|
26
|
-
"""
|
|
27
|
-
|
|
28
|
-
facet: str
|
|
29
|
-
selectedValues: list[SelectedValue]
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
# Model of the selected facets for a given query, resolved and normalized via LLM.
|
|
33
|
-
class FacetsResponse(BaseModel):
|
|
34
|
-
"""
|
|
35
|
-
Represents the selected facets for a given query, resolved and normalized via LLM.
|
|
36
|
-
|
|
37
|
-
Attributes:
|
|
38
|
-
query (str): The original query string.
|
|
39
|
-
facets (list[FacetSelection]): The list of selected facets and their values.
|
|
40
|
-
"""
|
|
41
|
-
|
|
42
|
-
query: str
|
|
43
|
-
facets: list[FacetSelection]
|
package/commitlint.config.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = { extends: ["@commitlint/config-conventional"] };
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
# Trusted Publishing Setup for NPM
|
|
2
|
-
|
|
3
|
-
This repository uses GitHub's trusted publishing workflow to securely publish packages to npm without using long-lived access tokens.
|
|
4
|
-
|
|
5
|
-
## What is Trusted Publishing?
|
|
6
|
-
|
|
7
|
-
Trusted publishing is a security feature that allows GitHub Actions to publish packages to npm using short-lived, automatically generated tokens via OpenID Connect (OIDC). This eliminates the need to store long-lived npm tokens as repository secrets, reducing the attack surface and improving supply chain security.
|
|
8
|
-
|
|
9
|
-
## Configuration
|
|
10
|
-
|
|
11
|
-
### GitHub Actions Workflow
|
|
12
|
-
|
|
13
|
-
The `.github/workflows/release-please.yml` workflow is configured with the following settings for trusted publishing:
|
|
14
|
-
|
|
15
|
-
#### Required Permissions
|
|
16
|
-
|
|
17
|
-
```yaml
|
|
18
|
-
permissions:
|
|
19
|
-
contents: write # Required for release-please to create releases
|
|
20
|
-
pull-requests: write # Required for release-please to create PRs
|
|
21
|
-
id-token: write # Required for trusted publishing to npm
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
The `id-token: write` permission enables the workflow to request OIDC tokens from GitHub's OIDC provider.
|
|
25
|
-
|
|
26
|
-
#### Node.js Setup
|
|
27
|
-
|
|
28
|
-
```yaml
|
|
29
|
-
- uses: actions/setup-node@v4
|
|
30
|
-
with:
|
|
31
|
-
node-version: "22.12.0"
|
|
32
|
-
registry-url: "https://registry.npmjs.org"
|
|
33
|
-
always-auth: true # Enable authentication for trusted publishing
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
The `always-auth: true` setting ensures that authentication is enabled when publishing packages.
|
|
37
|
-
|
|
38
|
-
#### Publishing with Provenance
|
|
39
|
-
|
|
40
|
-
```yaml
|
|
41
|
-
- name: Publish to NPM
|
|
42
|
-
run: npm publish --provenance --access public
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
The `--provenance` flag enables build provenance, which creates a publicly verifiable link between the package and its source code and build. The `--access public` flag ensures the package is published as public.
|
|
46
|
-
|
|
47
|
-
## NPM Setup Requirements
|
|
48
|
-
|
|
49
|
-
To enable trusted publishing for this package on npm, you need to:
|
|
50
|
-
|
|
51
|
-
1. **Log in to npm** and navigate to the package settings for `@databiosphere/findable-ui`
|
|
52
|
-
2. **Add a GitHub Actions Publishing Workflow**:
|
|
53
|
-
- Go to the package's publishing settings
|
|
54
|
-
- Click "Add GitHub Actions Publishing Workflow"
|
|
55
|
-
- Configure the trusted publisher with:
|
|
56
|
-
- **Repository**: `DataBiosphere/findable-ui`
|
|
57
|
-
- **Workflow**: `.github/workflows/release-please.yml`
|
|
58
|
-
- **Environment**: (leave blank, no environment is used)
|
|
59
|
-
|
|
60
|
-
3. **Verify the Configuration**:
|
|
61
|
-
- Ensure the trusted publisher is listed in the package settings
|
|
62
|
-
- The workflow will use OIDC to authenticate automatically when publishing
|
|
63
|
-
|
|
64
|
-
## Security Benefits
|
|
65
|
-
|
|
66
|
-
- **No Long-Lived Tokens**: Eliminates the need to store npm access tokens as GitHub secrets
|
|
67
|
-
- **Automatic Rotation**: Tokens are short-lived and automatically generated for each workflow run
|
|
68
|
-
- **Build Provenance**: The `--provenance` flag creates verifiable attestations linking the package to its source
|
|
69
|
-
- **Reduced Attack Surface**: Compromised secrets cannot be used outside the workflow context
|
|
70
|
-
- **Audit Trail**: All publishes are tied to specific GitHub Actions workflow runs
|
|
71
|
-
|
|
72
|
-
## Migration Notes
|
|
73
|
-
|
|
74
|
-
### Removed Configuration
|
|
75
|
-
|
|
76
|
-
The following configuration is no longer needed with trusted publishing:
|
|
77
|
-
|
|
78
|
-
- **Repository Secret**: `DATABIOSPHERE_FINDABLE_UI_NPM_PUBLISH_TOKEN` - This secret can be safely removed from the repository settings as it is no longer used. **Important**: Only remove this secret after confirming the trusted publishing workflow works successfully in production to avoid disrupting the release process.
|
|
79
|
-
- **NODE_AUTH_TOKEN Environment Variable**: No longer required in the publish step
|
|
80
|
-
|
|
81
|
-
### Workflow Changes
|
|
82
|
-
|
|
83
|
-
1. Added `id-token: write` permission
|
|
84
|
-
2. Added `always-auth: true` to `setup-node` action
|
|
85
|
-
3. Removed `NODE_AUTH_TOKEN` environment variable from publish step
|
|
86
|
-
4. Added `--provenance` and `--access public` flags to `npm publish`
|
|
87
|
-
|
|
88
|
-
## Testing
|
|
89
|
-
|
|
90
|
-
To test the trusted publishing workflow:
|
|
91
|
-
|
|
92
|
-
1. Create a test commit on a feature branch
|
|
93
|
-
2. Merge to the `main` branch
|
|
94
|
-
3. If the commit triggers a release (based on conventional commits), the workflow will:
|
|
95
|
-
- Create a release PR via release-please
|
|
96
|
-
- Once merged, create a GitHub release
|
|
97
|
-
- Automatically publish to npm using trusted publishing
|
|
98
|
-
|
|
99
|
-
Monitor the workflow run in the Actions tab to verify successful publication.
|
|
100
|
-
|
|
101
|
-
## References
|
|
102
|
-
|
|
103
|
-
- [npm Trusted Publishers Documentation](https://docs.npmjs.com/trusted-publishers)
|
|
104
|
-
- [GitHub: Publishing Node.js Packages](https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages/publishing-nodejs-packages-from-github-actions)
|
|
105
|
-
- [npm Provenance Documentation](https://docs.npmjs.com/generating-provenance-statements)
|
|
106
|
-
- [OpenID Connect in GitHub Actions](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
|
|
107
|
-
|
|
108
|
-
## Troubleshooting
|
|
109
|
-
|
|
110
|
-
### Publishing Fails with Authentication Error
|
|
111
|
-
|
|
112
|
-
If the workflow fails with an authentication error:
|
|
113
|
-
|
|
114
|
-
1. Verify that trusted publishing is properly configured on npm for the package
|
|
115
|
-
2. Ensure the repository, workflow path, and environment (if any) match exactly in the npm settings
|
|
116
|
-
3. Confirm that the workflow has the `id-token: write` permission
|
|
117
|
-
|
|
118
|
-
### Provenance Attestation Not Generated
|
|
119
|
-
|
|
120
|
-
If the package is published but provenance is not attached:
|
|
121
|
-
|
|
122
|
-
1. Ensure the `--provenance` flag is included in the `npm publish` command
|
|
123
|
-
2. Verify that the workflow has `id-token: write` permission
|
|
124
|
-
3. Check that the package is being published from a supported environment (GitHub Actions)
|
|
125
|
-
|
|
126
|
-
### Package Access Issues
|
|
127
|
-
|
|
128
|
-
If the package fails to publish due to access issues:
|
|
129
|
-
|
|
130
|
-
1. Ensure the `--access public` flag is set (for public packages)
|
|
131
|
-
2. Verify that the npm package settings allow public access
|
|
132
|
-
3. Confirm that the organization and package name are correct
|
package/jest.config.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"monorepo-tags": false,
|
|
3
|
-
"packages": {
|
|
4
|
-
".": {
|
|
5
|
-
"release-type": "node",
|
|
6
|
-
"component": "",
|
|
7
|
-
"include-component-in-tag": false
|
|
8
|
-
}
|
|
9
|
-
},
|
|
10
|
-
"changelog-sections": [
|
|
11
|
-
{ "type": "feat", "section": "Features" },
|
|
12
|
-
{ "type": "fix", "section": "Bug Fixes" },
|
|
13
|
-
{ "type": "chore", "section": "Chores" },
|
|
14
|
-
{ "type": "content", "section": "Content" },
|
|
15
|
-
{ "type": "docs", "section": "Documentation" },
|
|
16
|
-
{ "type": "style", "section": "Styles" },
|
|
17
|
-
{ "type": "refactor", "section": "Code Refactoring" },
|
|
18
|
-
{ "type": "perf", "section": "Performance Improvements" },
|
|
19
|
-
{ "type": "test", "section": "Tests" },
|
|
20
|
-
{ "type": "build", "section": "Build System" },
|
|
21
|
-
{ "type": "ci", "section": "Continuous Integration" }
|
|
22
|
-
]
|
|
23
|
-
}
|