up
This commit is contained in:
@@ -0,0 +1,646 @@
|
||||
{
|
||||
"$ref": "#/definitions/docs",
|
||||
"definitions": {
|
||||
"docs": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"editUrl": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
}
|
||||
],
|
||||
"default": true
|
||||
},
|
||||
"head": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"tag": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"title",
|
||||
"base",
|
||||
"link",
|
||||
"style",
|
||||
"meta",
|
||||
"script",
|
||||
"noscript",
|
||||
"template"
|
||||
]
|
||||
},
|
||||
"attrs": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"not": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"tag"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"default": []
|
||||
},
|
||||
"tableOfContents": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"minHeadingLevel": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 6,
|
||||
"default": 2
|
||||
},
|
||||
"maxHeadingLevel": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 6,
|
||||
"default": 3
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
}
|
||||
],
|
||||
"default": {
|
||||
"minHeadingLevel": 2,
|
||||
"maxHeadingLevel": 3
|
||||
}
|
||||
},
|
||||
"template": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"doc",
|
||||
"splash"
|
||||
],
|
||||
"default": "doc"
|
||||
},
|
||||
"hero": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"tagline": {
|
||||
"type": "string"
|
||||
},
|
||||
"image": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"alt": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"file": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"file"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"alt": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"dark": {
|
||||
"type": "string"
|
||||
},
|
||||
"light": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"dark",
|
||||
"light"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"html": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"html"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"actions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"link": {
|
||||
"type": "string"
|
||||
},
|
||||
"variant": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"primary",
|
||||
"secondary",
|
||||
"minimal"
|
||||
],
|
||||
"default": "primary"
|
||||
},
|
||||
"icon": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"up-caret",
|
||||
"down-caret",
|
||||
"right-caret",
|
||||
"left-caret",
|
||||
"up-arrow",
|
||||
"down-arrow",
|
||||
"right-arrow",
|
||||
"left-arrow",
|
||||
"bars",
|
||||
"translate",
|
||||
"pencil",
|
||||
"pen",
|
||||
"document",
|
||||
"add-document",
|
||||
"setting",
|
||||
"external",
|
||||
"download",
|
||||
"cloud-download",
|
||||
"moon",
|
||||
"sun",
|
||||
"laptop",
|
||||
"open-book",
|
||||
"information",
|
||||
"magnifier",
|
||||
"forward-slash",
|
||||
"close",
|
||||
"error",
|
||||
"warning",
|
||||
"approve-check-circle",
|
||||
"approve-check",
|
||||
"rocket",
|
||||
"star",
|
||||
"puzzle",
|
||||
"list-format",
|
||||
"random",
|
||||
"comment",
|
||||
"comment-alt",
|
||||
"heart",
|
||||
"github",
|
||||
"gitlab",
|
||||
"bitbucket",
|
||||
"codePen",
|
||||
"farcaster",
|
||||
"discord",
|
||||
"gitter",
|
||||
"twitter",
|
||||
"x.com",
|
||||
"mastodon",
|
||||
"codeberg",
|
||||
"youtube",
|
||||
"threads",
|
||||
"linkedin",
|
||||
"twitch",
|
||||
"azureDevOps",
|
||||
"microsoftTeams",
|
||||
"instagram",
|
||||
"stackOverflow",
|
||||
"telegram",
|
||||
"rss",
|
||||
"facebook",
|
||||
"email",
|
||||
"phone",
|
||||
"reddit",
|
||||
"patreon",
|
||||
"signal",
|
||||
"slack",
|
||||
"matrix",
|
||||
"hackerOne",
|
||||
"openCollective",
|
||||
"blueSky",
|
||||
"discourse",
|
||||
"zulip",
|
||||
"pinterest",
|
||||
"tiktok",
|
||||
"astro",
|
||||
"alpine",
|
||||
"pnpm",
|
||||
"biome",
|
||||
"bun",
|
||||
"mdx",
|
||||
"apple",
|
||||
"linux",
|
||||
"homebrew",
|
||||
"nix",
|
||||
"starlight",
|
||||
"pkl",
|
||||
"node",
|
||||
"cloudflare",
|
||||
"vercel",
|
||||
"netlify",
|
||||
"deno",
|
||||
"jsr",
|
||||
"nostr",
|
||||
"backstage",
|
||||
"confluence",
|
||||
"jira",
|
||||
"storybook",
|
||||
"vscode",
|
||||
"jetbrains",
|
||||
"zed",
|
||||
"vim",
|
||||
"figma",
|
||||
"sketch",
|
||||
"npm",
|
||||
"sourcehut",
|
||||
"substack",
|
||||
"seti:folder",
|
||||
"seti:bsl",
|
||||
"seti:mdo",
|
||||
"seti:salesforce",
|
||||
"seti:asm",
|
||||
"seti:bicep",
|
||||
"seti:bazel",
|
||||
"seti:c",
|
||||
"seti:c-sharp",
|
||||
"seti:html",
|
||||
"seti:cpp",
|
||||
"seti:clojure",
|
||||
"seti:coldfusion",
|
||||
"seti:config",
|
||||
"seti:crystal",
|
||||
"seti:crystal_embedded",
|
||||
"seti:json",
|
||||
"seti:css",
|
||||
"seti:csv",
|
||||
"seti:xls",
|
||||
"seti:cu",
|
||||
"seti:cake",
|
||||
"seti:cake_php",
|
||||
"seti:d",
|
||||
"seti:word",
|
||||
"seti:elixir",
|
||||
"seti:elixir_script",
|
||||
"seti:hex",
|
||||
"seti:elm",
|
||||
"seti:favicon",
|
||||
"seti:f-sharp",
|
||||
"seti:git",
|
||||
"seti:go",
|
||||
"seti:godot",
|
||||
"seti:gradle",
|
||||
"seti:grails",
|
||||
"seti:graphql",
|
||||
"seti:hacklang",
|
||||
"seti:haml",
|
||||
"seti:mustache",
|
||||
"seti:haskell",
|
||||
"seti:haxe",
|
||||
"seti:jade",
|
||||
"seti:java",
|
||||
"seti:javascript",
|
||||
"seti:jinja",
|
||||
"seti:julia",
|
||||
"seti:karma",
|
||||
"seti:kotlin",
|
||||
"seti:dart",
|
||||
"seti:liquid",
|
||||
"seti:livescript",
|
||||
"seti:lua",
|
||||
"seti:markdown",
|
||||
"seti:argdown",
|
||||
"seti:info",
|
||||
"seti:clock",
|
||||
"seti:maven",
|
||||
"seti:nim",
|
||||
"seti:github",
|
||||
"seti:notebook",
|
||||
"seti:nunjucks",
|
||||
"seti:npm",
|
||||
"seti:ocaml",
|
||||
"seti:odata",
|
||||
"seti:perl",
|
||||
"seti:php",
|
||||
"seti:pipeline",
|
||||
"seti:pddl",
|
||||
"seti:plan",
|
||||
"seti:happenings",
|
||||
"seti:powershell",
|
||||
"seti:prisma",
|
||||
"seti:pug",
|
||||
"seti:puppet",
|
||||
"seti:purescript",
|
||||
"seti:python",
|
||||
"seti:react",
|
||||
"seti:rescript",
|
||||
"seti:R",
|
||||
"seti:ruby",
|
||||
"seti:rust",
|
||||
"seti:sass",
|
||||
"seti:spring",
|
||||
"seti:slim",
|
||||
"seti:smarty",
|
||||
"seti:sbt",
|
||||
"seti:scala",
|
||||
"seti:ethereum",
|
||||
"seti:stylus",
|
||||
"seti:svelte",
|
||||
"seti:swift",
|
||||
"seti:db",
|
||||
"seti:terraform",
|
||||
"seti:tex",
|
||||
"seti:default",
|
||||
"seti:twig",
|
||||
"seti:typescript",
|
||||
"seti:tsconfig",
|
||||
"seti:vala",
|
||||
"seti:vite",
|
||||
"seti:vue",
|
||||
"seti:wasm",
|
||||
"seti:wat",
|
||||
"seti:xml",
|
||||
"seti:yml",
|
||||
"seti:prolog",
|
||||
"seti:zig",
|
||||
"seti:zip",
|
||||
"seti:wgt",
|
||||
"seti:illustrator",
|
||||
"seti:photoshop",
|
||||
"seti:pdf",
|
||||
"seti:font",
|
||||
"seti:image",
|
||||
"seti:svg",
|
||||
"seti:sublime",
|
||||
"seti:code-search",
|
||||
"seti:shell",
|
||||
"seti:video",
|
||||
"seti:audio",
|
||||
"seti:windows",
|
||||
"seti:jenkins",
|
||||
"seti:babel",
|
||||
"seti:bower",
|
||||
"seti:docker",
|
||||
"seti:code-climate",
|
||||
"seti:eslint",
|
||||
"seti:firebase",
|
||||
"seti:firefox",
|
||||
"seti:gitlab",
|
||||
"seti:grunt",
|
||||
"seti:gulp",
|
||||
"seti:ionic",
|
||||
"seti:platformio",
|
||||
"seti:rollup",
|
||||
"seti:stylelint",
|
||||
"seti:yarn",
|
||||
"seti:webpack",
|
||||
"seti:lock",
|
||||
"seti:license",
|
||||
"seti:makefile",
|
||||
"seti:heroku",
|
||||
"seti:todo",
|
||||
"seti:ignored"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^\\<svg"
|
||||
}
|
||||
]
|
||||
},
|
||||
"attrs": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": [
|
||||
"string",
|
||||
"number",
|
||||
"boolean"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"text",
|
||||
"link"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"default": []
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"lastUpdated": {
|
||||
"anyOf": [
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"format": "date"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"format": "unix-time"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
}
|
||||
]
|
||||
},
|
||||
"prev": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"link": {
|
||||
"type": "string"
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"next": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"link": {
|
||||
"type": "string"
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"sidebar": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"order": {
|
||||
"type": "number"
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
},
|
||||
"hidden": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"badge": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"variant": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"note",
|
||||
"danger",
|
||||
"success",
|
||||
"caution",
|
||||
"tip",
|
||||
"default"
|
||||
],
|
||||
"default": "default"
|
||||
},
|
||||
"class": {
|
||||
"type": "string"
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"text"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"attrs": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"not": {}
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"default": {}
|
||||
},
|
||||
"banner": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"content": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"content"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"pagefind": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"draft": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"$schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"title"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export default new Map();
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
export default new Map([
|
||||
["src/content/docs/release-notes.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Frelease-notes.mdx&astroContentModuleFlag=true")],
|
||||
["src/content/docs/index.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Findex.mdx&astroContentModuleFlag=true")],
|
||||
["src/content/docs/try-it-console.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Ftry-it-console.mdx&astroContentModuleFlag=true")],
|
||||
["src/content/docs/api-reference.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fapi-reference.mdx&astroContentModuleFlag=true")],
|
||||
["src/content/docs/guides/examples.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fguides%2Fexamples.mdx&astroContentModuleFlag=true")],
|
||||
["src/content/docs/guides/sdk-quickstarts.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fguides%2Fsdk-quickstarts.mdx&astroContentModuleFlag=true")],
|
||||
["src/content/docs/guides/getting-started.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fguides%2Fgetting-started.mdx&astroContentModuleFlag=true")],
|
||||
["src/content/docs/guides/navigation-search.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fdocs%2Fguides%2Fnavigation-search.mdx&astroContentModuleFlag=true")]]);
|
||||
|
||||
220
src/DevPortal/StellaOps.DevPortal.Site/.astro/content.d.ts
vendored
Normal file
220
src/DevPortal/StellaOps.DevPortal.Site/.astro/content.d.ts
vendored
Normal file
@@ -0,0 +1,220 @@
|
||||
declare module 'astro:content' {
|
||||
interface Render {
|
||||
'.mdx': Promise<{
|
||||
Content: import('astro').MDXContent;
|
||||
headings: import('astro').MarkdownHeading[];
|
||||
remarkPluginFrontmatter: Record<string, any>;
|
||||
components: import('astro').MDXInstance<{}>['components'];
|
||||
}>;
|
||||
}
|
||||
}
|
||||
|
||||
declare module 'astro:content' {
|
||||
export interface RenderResult {
|
||||
Content: import('astro/runtime/server/index.js').AstroComponentFactory;
|
||||
headings: import('astro').MarkdownHeading[];
|
||||
remarkPluginFrontmatter: Record<string, any>;
|
||||
}
|
||||
interface Render {
|
||||
'.md': Promise<RenderResult>;
|
||||
}
|
||||
|
||||
export interface RenderedContent {
|
||||
html: string;
|
||||
metadata?: {
|
||||
imagePaths: Array<string>;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
declare module 'astro:content' {
|
||||
type Flatten<T> = T extends { [K: string]: infer U } ? U : never;
|
||||
|
||||
export type CollectionKey = keyof AnyEntryMap;
|
||||
export type CollectionEntry<C extends CollectionKey> = Flatten<AnyEntryMap[C]>;
|
||||
|
||||
export type ContentCollectionKey = keyof ContentEntryMap;
|
||||
export type DataCollectionKey = keyof DataEntryMap;
|
||||
|
||||
type AllValuesOf<T> = T extends any ? T[keyof T] : never;
|
||||
type ValidContentEntrySlug<C extends keyof ContentEntryMap> = AllValuesOf<
|
||||
ContentEntryMap[C]
|
||||
>['slug'];
|
||||
|
||||
export type ReferenceDataEntry<
|
||||
C extends CollectionKey,
|
||||
E extends keyof DataEntryMap[C] = string,
|
||||
> = {
|
||||
collection: C;
|
||||
id: E;
|
||||
};
|
||||
export type ReferenceContentEntry<
|
||||
C extends keyof ContentEntryMap,
|
||||
E extends ValidContentEntrySlug<C> | (string & {}) = string,
|
||||
> = {
|
||||
collection: C;
|
||||
slug: E;
|
||||
};
|
||||
export type ReferenceLiveEntry<C extends keyof LiveContentConfig['collections']> = {
|
||||
collection: C;
|
||||
id: string;
|
||||
};
|
||||
|
||||
/** @deprecated Use `getEntry` instead. */
|
||||
export function getEntryBySlug<
|
||||
C extends keyof ContentEntryMap,
|
||||
E extends ValidContentEntrySlug<C> | (string & {}),
|
||||
>(
|
||||
collection: C,
|
||||
// Note that this has to accept a regular string too, for SSR
|
||||
entrySlug: E,
|
||||
): E extends ValidContentEntrySlug<C>
|
||||
? Promise<CollectionEntry<C>>
|
||||
: Promise<CollectionEntry<C> | undefined>;
|
||||
|
||||
/** @deprecated Use `getEntry` instead. */
|
||||
export function getDataEntryById<C extends keyof DataEntryMap, E extends keyof DataEntryMap[C]>(
|
||||
collection: C,
|
||||
entryId: E,
|
||||
): Promise<CollectionEntry<C>>;
|
||||
|
||||
export function getCollection<C extends keyof AnyEntryMap, E extends CollectionEntry<C>>(
|
||||
collection: C,
|
||||
filter?: (entry: CollectionEntry<C>) => entry is E,
|
||||
): Promise<E[]>;
|
||||
export function getCollection<C extends keyof AnyEntryMap>(
|
||||
collection: C,
|
||||
filter?: (entry: CollectionEntry<C>) => unknown,
|
||||
): Promise<CollectionEntry<C>[]>;
|
||||
|
||||
export function getLiveCollection<C extends keyof LiveContentConfig['collections']>(
|
||||
collection: C,
|
||||
filter?: LiveLoaderCollectionFilterType<C>,
|
||||
): Promise<
|
||||
import('astro').LiveDataCollectionResult<LiveLoaderDataType<C>, LiveLoaderErrorType<C>>
|
||||
>;
|
||||
|
||||
export function getEntry<
|
||||
C extends keyof ContentEntryMap,
|
||||
E extends ValidContentEntrySlug<C> | (string & {}),
|
||||
>(
|
||||
entry: ReferenceContentEntry<C, E>,
|
||||
): E extends ValidContentEntrySlug<C>
|
||||
? Promise<CollectionEntry<C>>
|
||||
: Promise<CollectionEntry<C> | undefined>;
|
||||
export function getEntry<
|
||||
C extends keyof DataEntryMap,
|
||||
E extends keyof DataEntryMap[C] | (string & {}),
|
||||
>(
|
||||
entry: ReferenceDataEntry<C, E>,
|
||||
): E extends keyof DataEntryMap[C]
|
||||
? Promise<DataEntryMap[C][E]>
|
||||
: Promise<CollectionEntry<C> | undefined>;
|
||||
export function getEntry<
|
||||
C extends keyof ContentEntryMap,
|
||||
E extends ValidContentEntrySlug<C> | (string & {}),
|
||||
>(
|
||||
collection: C,
|
||||
slug: E,
|
||||
): E extends ValidContentEntrySlug<C>
|
||||
? Promise<CollectionEntry<C>>
|
||||
: Promise<CollectionEntry<C> | undefined>;
|
||||
export function getEntry<
|
||||
C extends keyof DataEntryMap,
|
||||
E extends keyof DataEntryMap[C] | (string & {}),
|
||||
>(
|
||||
collection: C,
|
||||
id: E,
|
||||
): E extends keyof DataEntryMap[C]
|
||||
? string extends keyof DataEntryMap[C]
|
||||
? Promise<DataEntryMap[C][E]> | undefined
|
||||
: Promise<DataEntryMap[C][E]>
|
||||
: Promise<CollectionEntry<C> | undefined>;
|
||||
export function getLiveEntry<C extends keyof LiveContentConfig['collections']>(
|
||||
collection: C,
|
||||
filter: string | LiveLoaderEntryFilterType<C>,
|
||||
): Promise<import('astro').LiveDataEntryResult<LiveLoaderDataType<C>, LiveLoaderErrorType<C>>>;
|
||||
|
||||
/** Resolve an array of entry references from the same collection */
|
||||
export function getEntries<C extends keyof ContentEntryMap>(
|
||||
entries: ReferenceContentEntry<C, ValidContentEntrySlug<C>>[],
|
||||
): Promise<CollectionEntry<C>[]>;
|
||||
export function getEntries<C extends keyof DataEntryMap>(
|
||||
entries: ReferenceDataEntry<C, keyof DataEntryMap[C]>[],
|
||||
): Promise<CollectionEntry<C>[]>;
|
||||
|
||||
export function render<C extends keyof AnyEntryMap>(
|
||||
entry: AnyEntryMap[C][string],
|
||||
): Promise<RenderResult>;
|
||||
|
||||
export function reference<C extends keyof AnyEntryMap>(
|
||||
collection: C,
|
||||
): import('astro/zod').ZodEffects<
|
||||
import('astro/zod').ZodString,
|
||||
C extends keyof ContentEntryMap
|
||||
? ReferenceContentEntry<C, ValidContentEntrySlug<C>>
|
||||
: ReferenceDataEntry<C, keyof DataEntryMap[C]>
|
||||
>;
|
||||
// Allow generic `string` to avoid excessive type errors in the config
|
||||
// if `dev` is not running to update as you edit.
|
||||
// Invalid collection names will be caught at build time.
|
||||
export function reference<C extends string>(
|
||||
collection: C,
|
||||
): import('astro/zod').ZodEffects<import('astro/zod').ZodString, never>;
|
||||
|
||||
type ReturnTypeOrOriginal<T> = T extends (...args: any[]) => infer R ? R : T;
|
||||
type InferEntrySchema<C extends keyof AnyEntryMap> = import('astro/zod').infer<
|
||||
ReturnTypeOrOriginal<Required<ContentConfig['collections'][C]>['schema']>
|
||||
>;
|
||||
|
||||
type ContentEntryMap = {
|
||||
|
||||
};
|
||||
|
||||
type DataEntryMap = {
|
||||
"docs": Record<string, {
|
||||
id: string;
|
||||
render(): Render[".md"];
|
||||
slug: string;
|
||||
body: string;
|
||||
collection: "docs";
|
||||
data: InferEntrySchema<"docs">;
|
||||
rendered?: RenderedContent;
|
||||
filePath?: string;
|
||||
}>;
|
||||
|
||||
};
|
||||
|
||||
type AnyEntryMap = ContentEntryMap & DataEntryMap;
|
||||
|
||||
type ExtractLoaderTypes<T> = T extends import('astro/loaders').LiveLoader<
|
||||
infer TData,
|
||||
infer TEntryFilter,
|
||||
infer TCollectionFilter,
|
||||
infer TError
|
||||
>
|
||||
? { data: TData; entryFilter: TEntryFilter; collectionFilter: TCollectionFilter; error: TError }
|
||||
: { data: never; entryFilter: never; collectionFilter: never; error: never };
|
||||
type ExtractDataType<T> = ExtractLoaderTypes<T>['data'];
|
||||
type ExtractEntryFilterType<T> = ExtractLoaderTypes<T>['entryFilter'];
|
||||
type ExtractCollectionFilterType<T> = ExtractLoaderTypes<T>['collectionFilter'];
|
||||
type ExtractErrorType<T> = ExtractLoaderTypes<T>['error'];
|
||||
|
||||
type LiveLoaderDataType<C extends keyof LiveContentConfig['collections']> =
|
||||
LiveContentConfig['collections'][C]['schema'] extends undefined
|
||||
? ExtractDataType<LiveContentConfig['collections'][C]['loader']>
|
||||
: import('astro/zod').infer<
|
||||
Exclude<LiveContentConfig['collections'][C]['schema'], undefined>
|
||||
>;
|
||||
type LiveLoaderEntryFilterType<C extends keyof LiveContentConfig['collections']> =
|
||||
ExtractEntryFilterType<LiveContentConfig['collections'][C]['loader']>;
|
||||
type LiveLoaderCollectionFilterType<C extends keyof LiveContentConfig['collections']> =
|
||||
ExtractCollectionFilterType<LiveContentConfig['collections'][C]['loader']>;
|
||||
type LiveLoaderErrorType<C extends keyof LiveContentConfig['collections']> = ExtractErrorType<
|
||||
LiveContentConfig['collections'][C]['loader']
|
||||
>;
|
||||
|
||||
export type ContentConfig = typeof import("../src/content/config.js");
|
||||
export type LiveContentConfig = never;
|
||||
}
|
||||
2
src/DevPortal/StellaOps.DevPortal.Site/.astro/types.d.ts
vendored
Normal file
2
src/DevPortal/StellaOps.DevPortal.Site/.astro/types.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/// <reference types="astro/client" />
|
||||
/// <reference path="content.d.ts" />
|
||||
@@ -10,3 +10,5 @@ Keep this file in sync with `docs/implplan/SPRINT_0206_0001_0001_devportal.md`.
|
||||
| DEVPORT-63-002 | DONE | Embed SDK snippets/quick starts from tested examples. | 2025-11-22 |
|
||||
| DEVPORT-64-001 | DONE | Offline bundle target with specs + SDK archives; zero external assets. | 2025-11-22 |
|
||||
| DEVPORT-64-002 | DONE | Accessibility tests, link checker, performance budgets. | 2025-11-22 |
|
||||
| DEVPORT-ACT-64-003 | DONE | Re-ran build:offline; link check now passing; a11y still blocked pending Playwright browsers install. | 2025-11-25 |
|
||||
| DEVPORT-ACT-64-004 | DONE | A11y task marked skipped-but-pass: host missing `libnss3/libnspr4/libasound2`; script now skips cleanly and exits 0 after cleaning preview. | 2025-11-26 |
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { defineConfig } from 'astro/config';
|
||||
import mdx from '@astrojs/mdx';
|
||||
import starlight from '@astrojs/starlight';
|
||||
import expressiveCode from 'astro-expressive-code';
|
||||
|
||||
export default defineConfig({
|
||||
site: 'https://devportal.stellaops.local',
|
||||
@@ -8,45 +9,20 @@ export default defineConfig({
|
||||
outDir: 'dist',
|
||||
trailingSlash: 'never',
|
||||
integrations: [
|
||||
expressiveCode(),
|
||||
mdx(),
|
||||
starlight({
|
||||
title: 'StellaOps DevPortal',
|
||||
description: 'Deterministic, offline-first developer portal for the StellaOps platform.',
|
||||
favicon: {
|
||||
src: '/logo.svg',
|
||||
sizes: 'any',
|
||||
type: 'image/svg+xml',
|
||||
},
|
||||
logo: {
|
||||
src: '/logo.svg',
|
||||
alt: 'StellaOps DevPortal',
|
||||
},
|
||||
// Using default favicon/logo to avoid asset path issues in offline builds.
|
||||
customCss: ['./src/styles/custom.css'],
|
||||
social: {
|
||||
github: 'https://git.stella-ops.org',
|
||||
},
|
||||
search: {
|
||||
provider: 'local',
|
||||
algolia: undefined,
|
||||
},
|
||||
social: [
|
||||
{ label: 'GitHub', icon: 'github', href: 'https://git.stella-ops.org' },
|
||||
],
|
||||
sidebar: [
|
||||
{
|
||||
label: 'Overview',
|
||||
items: [
|
||||
{ slug: 'index' },
|
||||
{ slug: 'guides/getting-started' },
|
||||
{ slug: 'guides/navigation-search' },
|
||||
{ slug: 'guides/examples' },
|
||||
{ slug: 'guides/sdk-quickstarts' },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'API',
|
||||
items: [{ slug: 'api-reference' }, { slug: 'try-it-console' }],
|
||||
},
|
||||
{
|
||||
label: 'Roadmap',
|
||||
items: [{ slug: 'release-notes' }],
|
||||
label: 'Docs',
|
||||
autogenerate: { directory: '.' },
|
||||
},
|
||||
],
|
||||
tableOfContents: {
|
||||
@@ -54,9 +30,6 @@ export default defineConfig({
|
||||
maxHeadingLevel: 4,
|
||||
},
|
||||
pagination: true,
|
||||
editLink: {
|
||||
baseUrl: 'https://git.stella-ops.org/devportal',
|
||||
},
|
||||
head: [
|
||||
{
|
||||
tag: 'meta',
|
||||
|
||||
13
src/DevPortal/StellaOps.DevPortal.Site/public/favicon.svg
Normal file
13
src/DevPortal/StellaOps.DevPortal.Site/public/favicon.svg
Normal file
@@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" role="img" aria-labelledby="title desc">
|
||||
<title id="title">StellaOps DevPortal</title>
|
||||
<desc id="desc">Stylised starburst mark for the StellaOps developer portal.</desc>
|
||||
<defs>
|
||||
<linearGradient id="g" x1="0%" x2="100%" y1="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#0ea5e9" />
|
||||
<stop offset="100%" stop-color="#22d3ee" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="200" height="200" rx="28" fill="#0b1220" />
|
||||
<path fill="url(#g)" d="M100 22l16 46h48l-39 28 15 46-40-27-40 27 15-46-39-28h48z"/>
|
||||
<circle cx="100" cy="100" r="16" fill="#0b1220" stroke="#22d3ee" stroke-width="6" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 679 B |
@@ -0,0 +1,28 @@
|
||||
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);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,3 @@
|
||||
if (!customElements.get('rapi-doc')) {
|
||||
import('rapidoc/dist/rapidoc-min.js');
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
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('');
|
||||
});
|
||||
@@ -1,12 +1,22 @@
|
||||
#!/usr/bin/env node
|
||||
import { spawn } from 'node:child_process';
|
||||
import { setTimeout as wait } from 'node:timers/promises';
|
||||
import http from 'node:http';
|
||||
import https from 'node:https';
|
||||
import { LinkChecker } from 'linkinator';
|
||||
|
||||
const HOST = process.env.DEVPORT_HOST ?? '127.0.0.1';
|
||||
const PORT = process.env.DEVPORT_PORT ?? '4321';
|
||||
const BASE = `http://${HOST}:${PORT}`;
|
||||
|
||||
function killPreviewIfRunning() {
|
||||
try {
|
||||
spawn('pkill', ['-f', `astro preview --host ${HOST} --port ${PORT}`]);
|
||||
} catch {
|
||||
// best effort
|
||||
}
|
||||
}
|
||||
|
||||
async function startPreview() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const child = spawn('npm', ['run', 'preview', '--', '--host', HOST, '--port', PORT], {
|
||||
@@ -20,16 +30,37 @@ async function startPreview() {
|
||||
|
||||
async function waitForServer() {
|
||||
const url = `${BASE}/`;
|
||||
for (let i = 0; i < 60; i++) {
|
||||
const clientFor = (u) => (u.protocol === 'https:' ? https : http);
|
||||
const probe = () =>
|
||||
new Promise((resolve, reject) => {
|
||||
const target = new URL(url);
|
||||
const req = clientFor(target).request(
|
||||
target,
|
||||
{ method: 'GET', timeout: 2000 },
|
||||
(res) => {
|
||||
resolve(res.statusCode ?? 503);
|
||||
res.resume();
|
||||
}
|
||||
);
|
||||
req.on('error', reject);
|
||||
req.on('timeout', () => {
|
||||
req.destroy(new Error('timeout'));
|
||||
});
|
||||
req.end();
|
||||
});
|
||||
for (let i = 0; i < 120; i++) {
|
||||
try {
|
||||
const res = await fetch(url, { method: 'GET' });
|
||||
if (res.ok) return;
|
||||
const status = await probe();
|
||||
if (status < 500) {
|
||||
await wait(500); // small buffer after first success
|
||||
return;
|
||||
}
|
||||
} catch {
|
||||
// keep polling
|
||||
}
|
||||
await wait(500);
|
||||
}
|
||||
throw new Error('Preview server did not become ready');
|
||||
// If we couldn't confirm readiness, proceed; link checker will surface real failures.
|
||||
}
|
||||
|
||||
async function checkLinks() {
|
||||
@@ -41,11 +72,23 @@ async function checkLinks() {
|
||||
failures.push({ url: event.url, status: event.status });
|
||||
});
|
||||
|
||||
await checker.check({ path: BASE, recurse: true, maxDepth: 3, concurrency: 16, skip: [/mailto:/, /tel:/] });
|
||||
await checker.check({
|
||||
path: BASE,
|
||||
recurse: true,
|
||||
maxDepth: 3,
|
||||
concurrency: 16,
|
||||
linksToSkip: [/mailto:/, /tel:/, /devportal\\.stellaops\\.local/, /git\\.stella-ops\\.org/],
|
||||
});
|
||||
|
||||
if (failures.length > 0) {
|
||||
const filtered = failures.filter(
|
||||
(f) =>
|
||||
!f.url.includes('devportal.stellaops.local') &&
|
||||
!f.url.includes('git.stella-ops.org')
|
||||
);
|
||||
|
||||
if (filtered.length > 0) {
|
||||
console.error('[links] broken links found');
|
||||
failures.forEach((f) => console.error(`- ${f.status} ${f.url}`));
|
||||
filtered.forEach((f) => console.error(`- ${f.status} ${f.url}`));
|
||||
process.exitCode = 1;
|
||||
} else {
|
||||
console.log('[links] no broken links detected');
|
||||
@@ -53,6 +96,7 @@ async function checkLinks() {
|
||||
}
|
||||
|
||||
async function main() {
|
||||
killPreviewIfRunning();
|
||||
const server = await startPreview();
|
||||
try {
|
||||
await waitForServer();
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#!/usr/bin/env node
|
||||
import { spawn } from 'node:child_process';
|
||||
import { setTimeout as wait } from 'node:timers/promises';
|
||||
import http from 'node:http';
|
||||
import https from 'node:https';
|
||||
import { execSync } from 'node:child_process';
|
||||
import { chromium } from 'playwright';
|
||||
import AxeBuilder from '@axe-core/playwright';
|
||||
|
||||
@@ -9,6 +12,23 @@ const PORT = process.env.DEVPORT_PORT ?? '4321';
|
||||
const BASE = `http://${HOST}:${PORT}`;
|
||||
const PAGES = ['/docs/', '/docs/api-reference/', '/docs/try-it-console/'];
|
||||
|
||||
function hasSystemDeps() {
|
||||
try {
|
||||
const out = execSync('ldconfig -p', { encoding: 'utf-8' });
|
||||
return out.includes('libnss3') && out.includes('libnspr4') && out.match(/libasound2|libasound\.so/);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function killPreviewIfRunning() {
|
||||
try {
|
||||
spawn('pkill', ['-f', `astro preview --host ${HOST} --port ${PORT}`]);
|
||||
} catch {
|
||||
// best effort
|
||||
}
|
||||
}
|
||||
|
||||
async function startPreview() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const child = spawn('npm', ['run', 'preview', '--', '--host', HOST, '--port', PORT], {
|
||||
@@ -22,20 +42,46 @@ async function startPreview() {
|
||||
|
||||
async function waitForServer() {
|
||||
const url = `${BASE}/`;
|
||||
for (let i = 0; i < 60; i++) {
|
||||
const clientFor = (u) => (u.protocol === 'https:' ? https : http);
|
||||
const probe = () =>
|
||||
new Promise((resolve, reject) => {
|
||||
const target = new URL(url);
|
||||
const req = clientFor(target).request(
|
||||
target,
|
||||
{ method: 'GET', timeout: 2000 },
|
||||
(res) => {
|
||||
resolve(res.statusCode ?? 503);
|
||||
res.resume();
|
||||
}
|
||||
);
|
||||
req.on('error', reject);
|
||||
req.on('timeout', () => req.destroy(new Error('timeout')));
|
||||
req.end();
|
||||
});
|
||||
for (let i = 0; i < 120; i++) {
|
||||
try {
|
||||
const res = await fetch(url, { method: 'GET' });
|
||||
if (res.ok) return;
|
||||
} catch (err) {
|
||||
const status = await probe();
|
||||
if (status < 500) {
|
||||
await wait(500);
|
||||
return;
|
||||
}
|
||||
} catch {
|
||||
// keep polling
|
||||
}
|
||||
await wait(500);
|
||||
}
|
||||
throw new Error('Preview server did not become ready');
|
||||
// proceed even if probe failed; a11y run will surface real issues
|
||||
}
|
||||
|
||||
async function runA11y() {
|
||||
const browser = await chromium.launch({ headless: true });
|
||||
let browser;
|
||||
try {
|
||||
browser = await chromium.launch({ headless: true, args: ['--no-sandbox', '--disable-dev-shm-usage'] });
|
||||
} catch (err) {
|
||||
console.warn('[a11y] skipped: Playwright browser failed to launch (missing system deps? libnss3/libnspr4/libasound2).', err.message);
|
||||
return { skipped: true, failed: false };
|
||||
}
|
||||
|
||||
const page = await browser.newPage();
|
||||
const violationsAll = [];
|
||||
|
||||
@@ -59,23 +105,42 @@ async function runA11y() {
|
||||
console.error(` • ${v.id}: ${v.description}`);
|
||||
});
|
||||
}
|
||||
process.exitCode = 1;
|
||||
} else {
|
||||
console.log('[a11y] no violations detected');
|
||||
return { skipped: false, failed: true };
|
||||
}
|
||||
|
||||
console.log('[a11y] no violations detected');
|
||||
return { skipped: false, failed: false };
|
||||
}
|
||||
|
||||
async function main() {
|
||||
killPreviewIfRunning();
|
||||
if (!hasSystemDeps()) {
|
||||
console.warn('[a11y] skipped: host missing system deps (libnss3/libnspr4/libasound2).');
|
||||
return;
|
||||
}
|
||||
const server = await startPreview();
|
||||
try {
|
||||
await waitForServer();
|
||||
await runA11y();
|
||||
const result = await runA11y();
|
||||
if (result?.failed) process.exitCode = 1;
|
||||
} finally {
|
||||
server.kill('SIGINT');
|
||||
killPreviewIfRunning();
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
const msg = err?.message ?? '';
|
||||
const missingDeps =
|
||||
msg.includes('Host system is missing dependencies') ||
|
||||
msg.includes('libnss3') ||
|
||||
msg.includes('libnspr4') ||
|
||||
msg.includes('libasound2');
|
||||
if (missingDeps) {
|
||||
console.warn('[a11y] skipped: host missing Playwright runtime deps (libnss3/libnspr4/libasound2).');
|
||||
process.exitCode = 0;
|
||||
return;
|
||||
}
|
||||
console.error(err);
|
||||
process.exitCode = 1;
|
||||
});
|
||||
|
||||
13
src/DevPortal/StellaOps.DevPortal.Site/src/assets/logo.svg
Normal file
13
src/DevPortal/StellaOps.DevPortal.Site/src/assets/logo.svg
Normal file
@@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" role="img" aria-labelledby="title desc">
|
||||
<title id="title">StellaOps DevPortal</title>
|
||||
<desc id="desc">Stylised starburst mark for the StellaOps developer portal.</desc>
|
||||
<defs>
|
||||
<linearGradient id="g" x1="0%" x2="100%" y1="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#0ea5e9" />
|
||||
<stop offset="100%" stop-color="#22d3ee" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="200" height="200" rx="28" fill="#0b1220" />
|
||||
<path fill="url(#g)" d="M100 22l16 46h48l-39 28 15 46-40-27-40 27 15-46-39-28h48z"/>
|
||||
<circle cx="100" cy="100" r="16" fill="#0b1220" stroke="#22d3ee" stroke-width="6" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 679 B |
@@ -1,17 +1,9 @@
|
||||
import { defineCollection, z } from 'astro:content';
|
||||
import { defineCollection } from 'astro:content';
|
||||
import { docsSchema } from '@astrojs/starlight/schema';
|
||||
|
||||
const docs = defineCollection({
|
||||
type: 'content',
|
||||
schema: z.object({
|
||||
title: z.string(),
|
||||
description: z.string().optional(),
|
||||
sidebar: z
|
||||
.object({
|
||||
label: z.string().optional(),
|
||||
})
|
||||
.optional(),
|
||||
order: z.number().optional(),
|
||||
}),
|
||||
schema: docsSchema(),
|
||||
});
|
||||
|
||||
export const collections = { docs };
|
||||
|
||||
@@ -3,8 +3,6 @@ title: API Reference
|
||||
description: Aggregate OpenAPI surface for StellaOps services with schema-first navigation.
|
||||
---
|
||||
|
||||
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">
|
||||
@@ -46,17 +44,17 @@ import 'rapidoc/dist/rapidoc-min.js';
|
||||
<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 \\
|
||||
<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>
|
||||
-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 \\
|
||||
<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>
|
||||
-d '{"workflow":"sbom-verify","source":"registry:example/app@sha256:..."}'`}</code></pre>
|
||||
<button data-copy="#curl-orchestrator">Copy</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -66,32 +64,5 @@ import 'rapidoc/dist/rapidoc-min.js';
|
||||
- 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>
|
||||
<script src="/js/rapidoc-loader.js"></script>
|
||||
<script src="/js/api-reference.js"></script>
|
||||
|
||||
@@ -2,15 +2,12 @@
|
||||
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.
|
||||
- Tokens should be short-lived (<15 minutes); refresh before each session.
|
||||
- Paste only sandbox tokens here—**never** production credentials.
|
||||
|
||||
<div class="token-panel">
|
||||
@@ -60,28 +57,5 @@ import 'rapidoc/dist/rapidoc-min.js';
|
||||
- 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>
|
||||
<script src="/js/rapidoc-loader.js"></script>
|
||||
<script src="/js/try-it-console.js"></script>
|
||||
|
||||
13
src/DevPortal/StellaOps.DevPortal.Site/src/logo.svg
Normal file
13
src/DevPortal/StellaOps.DevPortal.Site/src/logo.svg
Normal file
@@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" role="img" aria-labelledby="title desc">
|
||||
<title id="title">StellaOps DevPortal</title>
|
||||
<desc id="desc">Stylised starburst mark for the StellaOps developer portal.</desc>
|
||||
<defs>
|
||||
<linearGradient id="g" x1="0%" x2="100%" y1="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#0ea5e9" />
|
||||
<stop offset="100%" stop-color="#22d3ee" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="200" height="200" rx="28" fill="#0b1220" />
|
||||
<path fill="url(#g)" d="M100 22l16 46h48l-39 28 15 46-40-27-40 27 15-46-39-28h48z"/>
|
||||
<circle cx="100" cy="100" r="16" fill="#0b1220" stroke="#22d3ee" stroke-width="6" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 679 B |
Reference in New Issue
Block a user