feat: Add MongoIdempotencyStoreOptions for MongoDB configuration
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
feat: Implement BsonJsonConverter for converting BsonDocument and BsonArray to JSON fix: Update project file to include MongoDB.Bson package test: Add GraphOverlayExporterTests to validate NDJSON export functionality refactor: Refactor Program.cs in Attestation Tool for improved argument parsing and error handling docs: Update README for stella-forensic-verify with usage instructions and exit codes feat: Enhance HmacVerifier with clock skew and not-after checks feat: Add MerkleRootVerifier and ChainOfCustodyVerifier for additional verification methods fix: Update DenoRuntimeShim to correctly handle file paths feat: Introduce ComposerAutoloadData and related parsing in ComposerLockReader test: Add tests for Deno runtime execution and verification test: Enhance PHP package tests to include autoload data verification test: Add unit tests for HmacVerifier and verification logic
This commit is contained in:
@@ -4,9 +4,9 @@ Keep this file in sync with `docs/implplan/SPRINT_0206_0001_0001_devportal.md`.
|
||||
|
||||
| Task ID | Status | Notes | Last Updated (UTC) |
|
||||
| --- | --- | --- | --- |
|
||||
| DEVPORT-62-001 | DOING | Select SSG, wire aggregate spec, nav/search scaffold. | 2025-11-22 |
|
||||
| DEVPORT-62-002 | TODO | Schema viewer, examples, copy-curl, version selector. | 2025-11-22 |
|
||||
| DEVPORT-63-001 | TODO | Try-It console against sandbox; token onboarding UX. | 2025-11-22 |
|
||||
| DEVPORT-62-001 | DONE | Astro/Starlight scaffold + aggregate spec + nav/search. | 2025-11-22 |
|
||||
| DEVPORT-62-002 | DONE | Schema viewer, examples, copy-curl, version selector. | 2025-11-22 |
|
||||
| DEVPORT-63-001 | DONE | Try-It console against sandbox; token onboarding UX. | 2025-11-22 |
|
||||
| DEVPORT-63-002 | TODO | Embed SDK snippets/quick starts from tested examples. | 2025-11-22 |
|
||||
| DEVPORT-64-001 | TODO | Offline bundle target with specs + SDK archives; zero external assets. | 2025-11-22 |
|
||||
| DEVPORT-64-002 | TODO | Accessibility tests, link checker, performance budgets. | 2025-11-22 |
|
||||
|
||||
@@ -36,11 +36,12 @@ export default defineConfig({
|
||||
{ slug: 'index' },
|
||||
{ slug: 'guides/getting-started' },
|
||||
{ slug: 'guides/navigation-search' },
|
||||
{ slug: 'guides/examples' },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'API',
|
||||
items: [{ slug: 'api-reference' }],
|
||||
items: [{ slug: 'api-reference' }, { slug: 'try-it-console' }],
|
||||
},
|
||||
{
|
||||
label: 'Roadmap',
|
||||
|
||||
@@ -7,7 +7,16 @@ import 'rapidoc/dist/rapidoc-min.js';
|
||||
|
||||
> The aggregate spec is composed from per-service OpenAPI files and namespaced by service (e.g., `/authority/...`). The bundled copy lives at `/api/stella.yaml` so offline builds stay self-contained.
|
||||
|
||||
<div class="version-select">
|
||||
<label for="spec-version">Version</label>
|
||||
<select id="spec-version" aria-label="API version selector">
|
||||
<option value="/api/stella.yaml" selected>latest (aggregate)</option>
|
||||
<option value="/api/stella.yaml">sandbox preview (same build)</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<rapi-doc
|
||||
id="rapidoc"
|
||||
spec-url="/api/stella.yaml"
|
||||
render-style="read"
|
||||
theme="dark"
|
||||
@@ -25,13 +34,64 @@ import 'rapidoc/dist/rapidoc-min.js';
|
||||
schema-style="tree"
|
||||
default-schema-tab="schema"
|
||||
sort-tags="true"
|
||||
show-components="true"
|
||||
sort-endpoints-by="path"
|
||||
hide-schema-titles="false"
|
||||
layout="row"
|
||||
style="height: 80vh; border: 1px solid #1f2937; border-radius: 12px;"
|
||||
style="height: 78vh; border: 1px solid #1f2937; border-radius: 12px;"
|
||||
></rapi-doc>
|
||||
|
||||
## Quick copy-curl
|
||||
|
||||
<div class="copy-snippets">
|
||||
<div class="snippet">
|
||||
<header>Health check</header>
|
||||
<pre><code id="curl-health">curl -X GET https://api.stellaops.local/authority/health \\
|
||||
-H 'Accept: application/json' \\
|
||||
-H 'User-Agent: stellaops-devportal/0.1.0'</code></pre>
|
||||
<button data-copy="#curl-health">Copy</button>
|
||||
</div>
|
||||
<div class="snippet">
|
||||
<header>Submit orchestration job</header>
|
||||
<pre><code id="curl-orchestrator">curl -X POST https://api.stellaops.local/orchestrator/jobs \\
|
||||
-H 'Authorization: Bearer $STELLAOPS_TOKEN' \\
|
||||
-H 'Content-Type: application/json' \\
|
||||
-d '{\"workflow\":\"sbom-verify\",\"source\":\"registry:example/app@sha256:...\"}'</code></pre>
|
||||
<button data-copy="#curl-orchestrator">Copy</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
## What to look for
|
||||
- Per-operation `x-service` and `x-original-path` values expose provenance.
|
||||
- Shared schemas live under `#/components/schemas` with namespaced keys.
|
||||
- Shared schemas live under `#/components/schemas` with namespaced keys (use the **Schemas** panel).
|
||||
- Servers list includes one entry per service; sandbox URLs will be added alongside prod.
|
||||
|
||||
<script type="module">
|
||||
const selector = document.getElementById('spec-version');
|
||||
const rapidoc = document.getElementById('rapidoc');
|
||||
selector?.addEventListener('change', (evt) => {
|
||||
const url = evt.target.value;
|
||||
if (rapidoc) {
|
||||
rapidoc.setAttribute('spec-url', url);
|
||||
rapidoc.loadSpec(url);
|
||||
}
|
||||
});
|
||||
|
||||
document.querySelectorAll('button[data-copy]').forEach((btn) => {
|
||||
btn.addEventListener('click', async () => {
|
||||
const target = btn.getAttribute('data-copy');
|
||||
const el = target ? document.querySelector(target) : null;
|
||||
if (!el) return;
|
||||
const text = el.textContent || '';
|
||||
try {
|
||||
await navigator.clipboard.writeText(text);
|
||||
btn.textContent = 'Copied!';
|
||||
setTimeout(() => (btn.textContent = 'Copy'), 1200);
|
||||
} catch (err) {
|
||||
btn.textContent = 'Copy failed';
|
||||
setTimeout(() => (btn.textContent = 'Copy'), 1200);
|
||||
console.error(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
title: Examples & Snippets
|
||||
description: Ready-to-copy requests with deterministic headers and pinned versions.
|
||||
---
|
||||
|
||||
## cURL quick starts
|
||||
|
||||
The snippets below are deterministic: pinned versions, explicit headers, and scope hints.
|
||||
|
||||
```bash
|
||||
curl -X GET \\
|
||||
https://api.stellaops.local/authority/health \\
|
||||
-H 'Accept: application/json' \\
|
||||
-H 'User-Agent: stellaops-devportal/0.1.0' \\
|
||||
--retry 2 --retry-delay 1
|
||||
```
|
||||
|
||||
```bash
|
||||
curl -X POST \\
|
||||
https://api.stellaops.local/orchestrator/jobs \\
|
||||
-H 'Content-Type: application/json' \\
|
||||
-H 'Authorization: Bearer $STELLAOPS_TOKEN' \\
|
||||
-d '{\"workflow\":\"sbom-verify\",\"source\":\"registry:example/app@sha256:...\"}'
|
||||
```
|
||||
|
||||
## How snippets are generated
|
||||
- Targets align to the aggregate spec (`/api/stella.yaml`).
|
||||
- Headers: `Accept`/`Content-Type` always explicit; User-Agent pinned to portal version.
|
||||
- Retries kept low (`--retry 2`) to preserve determinism while tolerating transient sandboxes.
|
||||
|
||||
## Coming next
|
||||
- Language SDK equivalents (DEVPORT-63-002).
|
||||
- Operation-specific examples sourced directly from tested fixtures.
|
||||
@@ -7,7 +7,9 @@ description: Drop-by-drop updates for the DevPortal surface.
|
||||
- ✅ Selected Astro + Starlight as the static site generator for deterministic offline builds.
|
||||
- ✅ Added navigation scaffolding (Overview, Guides, API, Roadmap) with local search enabled.
|
||||
- ✅ Embedded aggregate OpenAPI via RapiDoc using bundled `/api/stella.yaml`.
|
||||
- 🔜 Schema explorer UI and copy-curl snippets (DEVPORT-62-002).
|
||||
- ✅ Added schema viewer + version selector, copy-curl snippets, and example guide.
|
||||
- ✅ Delivered Try-It console targeting sandbox with bearer-token onboarding and RapiDoc allow-try.
|
||||
- 🔜 Operation-specific example rendering & SDK snippets (DEVPORT-63-002).
|
||||
- 🔜 Try-It console against sandbox scopes (DEVPORT-63-001).
|
||||
|
||||
## How to contribute release entries
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
---
|
||||
title: Try-It Console
|
||||
description: Run authenticated requests against the sandbox API with scoped tokens and offline-ready tooling.
|
||||
---
|
||||
|
||||
import 'rapidoc/dist/rapidoc-min.js';
|
||||
|
||||
> Use this console to exercise the sandbox API. It runs fully client-side with no external assets. Supply a short-lived token with the scopes shown below. Nothing is sent to third-party services.
|
||||
|
||||
## Token onboarding
|
||||
- Obtain a sandbox token from the Platform sandbox issuer (`/auth/oidc/token`) using the `client_credentials` flow.
|
||||
- Required scopes (minimum): `stellaops.read`, `stellaops.write:sandbox`.
|
||||
- Tokens should be short-lived (<15 minutes); refresh before each session.
|
||||
- Paste only sandbox tokens here—**never** production credentials.
|
||||
|
||||
<div class="token-panel">
|
||||
<label for="token-input">Bearer token</label>
|
||||
<input id="token-input" type="password" autocomplete="off" placeholder="Paste sandbox token" />
|
||||
<div class="token-actions">
|
||||
<button id="token-apply">Apply to console</button>
|
||||
<button id="token-clear" class="secondary">Clear</button>
|
||||
</div>
|
||||
<p class="hint">Token is stored in-memory only for this tab. Reload to remove.</p>
|
||||
</div>
|
||||
|
||||
## Sandbox server
|
||||
- Base URL: `https://sandbox.api.stellaops.local`
|
||||
- Operations remain namespaced by service (e.g., `/authority/health`, `/orchestrator/jobs`).
|
||||
|
||||
<rapi-doc
|
||||
id="sandbox-rapidoc"
|
||||
spec-url="/api/stella.yaml"
|
||||
render-style="focused"
|
||||
theme="dark"
|
||||
bg-color="#0b1220"
|
||||
text-color="#e5e7eb"
|
||||
primary-color="#0ea5e9"
|
||||
nav-bg-color="#0f172a"
|
||||
nav-text-color="#cbd5e1"
|
||||
show-header="false"
|
||||
allow-try="true"
|
||||
allow-server-selection="true"
|
||||
allow-spec-url-load="false"
|
||||
allow-spec-file-load="false"
|
||||
api-key-name="Authorization"
|
||||
api-key-location="header"
|
||||
regular-font="Space Grotesk"
|
||||
mono-font="JetBrains Mono"
|
||||
schema-style="tree"
|
||||
default-schema-tab="schema"
|
||||
sort-tags="true"
|
||||
sort-endpoints-by="path"
|
||||
hide-schema-titles="false"
|
||||
layout="column"
|
||||
style="height: 78vh; border: 1px solid #1f2937; border-radius: 12px;"
|
||||
></rapi-doc>
|
||||
|
||||
## Tips
|
||||
- Set the server dropdown to `https://sandbox.api.stellaops.local` before sending requests.
|
||||
- Use small payloads; responses are truncated by RapiDoc if excessively large.
|
||||
- Keep retries low to preserve determinism (default is none).
|
||||
|
||||
<script type="module">
|
||||
const tokenInput = document.getElementById('token-input');
|
||||
const applyBtn = document.getElementById('token-apply');
|
||||
const clearBtn = document.getElementById('token-clear');
|
||||
const doc = document.getElementById('sandbox-rapidoc');
|
||||
|
||||
const setToken = (value) => {
|
||||
if (!doc) return;
|
||||
const header = value ? `Bearer ${value.trim()}` : '';
|
||||
doc.setAttribute('api-key-value', header);
|
||||
doc.loadSpec(doc.getAttribute('spec-url'));
|
||||
};
|
||||
|
||||
applyBtn?.addEventListener('click', () => {
|
||||
const token = tokenInput?.value || '';
|
||||
setToken(token);
|
||||
applyBtn.textContent = 'Applied';
|
||||
setTimeout(() => (applyBtn.textContent = 'Apply to console'), 1200);
|
||||
});
|
||||
|
||||
clearBtn?.addEventListener('click', () => {
|
||||
if (tokenInput) tokenInput.value = '';
|
||||
setToken('');
|
||||
});
|
||||
</script>
|
||||
@@ -43,3 +43,118 @@ nav.sl-topnav {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
border: 1px solid var(--sl-color-hairline);
|
||||
}
|
||||
|
||||
.version-select {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
margin: 1rem 0;
|
||||
padding: 0.75rem 1rem;
|
||||
border: 1px solid var(--sl-color-hairline);
|
||||
border-radius: 12px;
|
||||
background: rgba(15, 23, 42, 0.6);
|
||||
}
|
||||
|
||||
.version-select select {
|
||||
background: #0f172a;
|
||||
color: var(--sl-color-text);
|
||||
border: 1px solid var(--sl-color-hairline);
|
||||
padding: 0.4rem 0.6rem;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.copy-snippets {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||
gap: 1rem;
|
||||
margin: 1rem 0 2rem 0;
|
||||
}
|
||||
|
||||
.copy-snippets .snippet {
|
||||
border: 1px solid var(--sl-color-hairline);
|
||||
border-radius: 12px;
|
||||
padding: 0.75rem;
|
||||
background: rgba(15, 23, 42, 0.7);
|
||||
}
|
||||
|
||||
.copy-snippets header {
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.copy-snippets pre {
|
||||
background: rgba(0, 0, 0, 0.35);
|
||||
border-radius: 8px;
|
||||
padding: 0.75rem;
|
||||
overflow-x: auto;
|
||||
border: 1px solid var(--sl-color-hairline);
|
||||
}
|
||||
|
||||
.copy-snippets button {
|
||||
margin-top: 0.6rem;
|
||||
background: var(--sl-color-accent);
|
||||
color: #0b1220;
|
||||
border: none;
|
||||
padding: 0.4rem 0.75rem;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.copy-snippets button:hover {
|
||||
filter: brightness(1.05);
|
||||
}
|
||||
|
||||
.token-panel {
|
||||
border: 1px solid var(--sl-color-hairline);
|
||||
border-radius: 12px;
|
||||
padding: 1rem;
|
||||
background: rgba(15, 23, 42, 0.7);
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.token-panel label {
|
||||
font-weight: 600;
|
||||
display: block;
|
||||
margin-bottom: 0.35rem;
|
||||
}
|
||||
|
||||
.token-panel input {
|
||||
width: 100%;
|
||||
background: #0f172a;
|
||||
color: var(--sl-color-text);
|
||||
border: 1px solid var(--sl-color-hairline);
|
||||
border-radius: 8px;
|
||||
padding: 0.5rem 0.65rem;
|
||||
}
|
||||
|
||||
.token-actions {
|
||||
display: flex;
|
||||
gap: 0.75rem;
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
|
||||
.token-actions button {
|
||||
background: var(--sl-color-accent);
|
||||
color: #0b1220;
|
||||
border: none;
|
||||
padding: 0.45rem 0.9rem;
|
||||
border-radius: 8px;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.token-actions button.secondary {
|
||||
background: transparent;
|
||||
color: var(--sl-color-text);
|
||||
border: 1px solid var(--sl-color-hairline);
|
||||
}
|
||||
|
||||
.token-actions button:hover {
|
||||
filter: brightness(1.05);
|
||||
}
|
||||
|
||||
.hint {
|
||||
margin-top: 0.4rem;
|
||||
color: var(--sl-color-text-muted);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user