signalk-server
Version:
An implementation of a [Signal K](http://signalk.org) server for boats.
191 lines • 9.65 kB
JavaScript
"use strict";
/*
* Copyright 2026 Signal K contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.PluginDetailPayloadSchema = exports.AppStoreEntryExtensionSchema = exports.DependencyReferenceSchema = exports.SignalKPackageMetadataSchema = exports.PluginCiSchema = exports.PluginCiJobSchema = exports.PluginCiConclusionSchema = exports.PluginCiPlatformSchema = exports.IndicatorResultSchema = exports.IndicatorRawMetricsSchema = exports.IndicatorCheckSchema = exports.IndicatorStatusSchema = void 0;
const typebox_1 = require("@sinclair/typebox");
exports.IndicatorStatusSchema = typebox_1.Type.Union([typebox_1.Type.Literal('ok'), typebox_1.Type.Literal('warn'), typebox_1.Type.Literal('fail')], { $id: 'AppStoreIndicatorStatus' });
exports.IndicatorCheckSchema = typebox_1.Type.Object({
id: typebox_1.Type.String(),
status: exports.IndicatorStatusSchema,
title: typebox_1.Type.String(),
subtitle: typebox_1.Type.String(),
// True when no signal was available to evaluate the check. The UI
// renders these neutrally (not as a green pass) and the scoring
// layer excludes them from the weighted average so missing signals
// don't inflate the composite.
unknown: typebox_1.Type.Optional(typebox_1.Type.Boolean())
}, {
$id: 'AppStoreIndicatorCheck',
description: 'One heuristic check contributing to the App Store indicator score.'
});
exports.IndicatorRawMetricsSchema = typebox_1.Type.Object({
stars: typebox_1.Type.Optional(typebox_1.Type.Number()),
downloadsPerWeek: typebox_1.Type.Optional(typebox_1.Type.Number()),
openIssues: typebox_1.Type.Optional(typebox_1.Type.Number()),
contributors: typebox_1.Type.Optional(typebox_1.Type.Number()),
lastReleaseDate: typebox_1.Type.Optional(typebox_1.Type.String())
}, {
$id: 'AppStoreIndicatorRawMetrics',
description: 'Raw informational metrics shown on the Indicators tab.'
});
exports.IndicatorResultSchema = typebox_1.Type.Object({
score: typebox_1.Type.Number({ minimum: 0, maximum: 100 }),
checks: typebox_1.Type.Array(exports.IndicatorCheckSchema),
rawMetrics: exports.IndicatorRawMetricsSchema
}, {
$id: 'AppStoreIndicatorResult',
description: 'Aggregate heuristic indicator result. Weights are not exposed.'
});
// plugin-ci matrix: per-platform pass/fail of the upstream
// SignalK/signalk-server/.github/workflows/plugin-ci.yml against the
// commit (npm gitHead) the published version was built from. Fetched
// once per nightly by the signalk-plugin-registry CI under the
// authenticated GITHUB_TOKEN; surfaced on the App Store Indicators tab.
// Discriminated union by `status` so the UI never has to disambiguate
// "not yet fetched" from "fetched, nothing found".
exports.PluginCiPlatformSchema = typebox_1.Type.Union([
typebox_1.Type.Literal('linux-x64'),
typebox_1.Type.Literal('linux-arm64'),
typebox_1.Type.Literal('macos'),
typebox_1.Type.Literal('windows'),
typebox_1.Type.Literal('armv7-cerbo'),
typebox_1.Type.Literal('integration'),
// Future-proof: registry may emit new platforms before the admin UI
// ships a label for them.
typebox_1.Type.String()
]);
exports.PluginCiConclusionSchema = typebox_1.Type.Union([
typebox_1.Type.Literal('success'),
typebox_1.Type.Literal('failure'),
typebox_1.Type.Literal('skipped'),
typebox_1.Type.Literal('cancelled'),
typebox_1.Type.Literal('in_progress'),
typebox_1.Type.Null()
]);
exports.PluginCiJobSchema = typebox_1.Type.Object({
platform: exports.PluginCiPlatformSchema,
node: typebox_1.Type.Number(),
conclusion: exports.PluginCiConclusionSchema,
server_version: typebox_1.Type.Optional(typebox_1.Type.String()),
job_url: typebox_1.Type.Optional(typebox_1.Type.String())
});
exports.PluginCiSchema = typebox_1.Type.Union([
typebox_1.Type.Object({
status: typebox_1.Type.Literal('no-githead')
}),
typebox_1.Type.Object({
status: typebox_1.Type.Literal('no-run'),
head_sha: typebox_1.Type.String(),
commit_url: typebox_1.Type.String()
}),
typebox_1.Type.Object({
status: typebox_1.Type.Literal('no-plugin-ci'),
head_sha: typebox_1.Type.String(),
workflow_run_url: typebox_1.Type.String()
}),
typebox_1.Type.Object({
status: typebox_1.Type.Literal('in-progress'),
head_sha: typebox_1.Type.String(),
workflow_run_url: typebox_1.Type.String(),
tested_at: typebox_1.Type.Optional(typebox_1.Type.String())
}),
typebox_1.Type.Object({
status: typebox_1.Type.Literal('ok'),
head_sha: typebox_1.Type.String(),
commit_url: typebox_1.Type.String(),
workflow_run_url: typebox_1.Type.String(),
tested_at: typebox_1.Type.String(),
workflow_ref: typebox_1.Type.String(),
jobs: typebox_1.Type.Array(exports.PluginCiJobSchema)
})
]);
exports.SignalKPackageMetadataSchema = typebox_1.Type.Object({
displayName: typebox_1.Type.Optional(typebox_1.Type.String()),
appIcon: typebox_1.Type.Optional(typebox_1.Type.String()),
screenshots: typebox_1.Type.Optional(typebox_1.Type.Array(typebox_1.Type.String())),
deprecated: typebox_1.Type.Optional(typebox_1.Type.Boolean()),
requires: typebox_1.Type.Optional(typebox_1.Type.Array(typebox_1.Type.String())),
recommends: typebox_1.Type.Optional(typebox_1.Type.Array(typebox_1.Type.String()))
}, {
$id: 'SignalKPackageMetadata',
description: 'Metadata authors declare under the signalk key in package.json.',
additionalProperties: true
});
exports.DependencyReferenceSchema = typebox_1.Type.Object({
name: typebox_1.Type.String(),
displayName: typebox_1.Type.Optional(typebox_1.Type.String()),
appIcon: typebox_1.Type.Optional(typebox_1.Type.String()),
installed: typebox_1.Type.Boolean()
}, {
$id: 'AppStoreDependencyReference',
description: 'A hydrated reference to another App Store plugin that this plugin ' +
'requires or recommends.'
});
exports.AppStoreEntryExtensionSchema = typebox_1.Type.Object({
displayName: typebox_1.Type.Optional(typebox_1.Type.String()),
appIcon: typebox_1.Type.Optional(typebox_1.Type.String()),
installedIconUrl: typebox_1.Type.Optional(typebox_1.Type.String()),
screenshots: typebox_1.Type.Optional(typebox_1.Type.Array(typebox_1.Type.String())),
installedScreenshotUrls: typebox_1.Type.Optional(typebox_1.Type.Array(typebox_1.Type.String())),
official: typebox_1.Type.Boolean(),
deprecated: typebox_1.Type.Boolean(),
readmeUrl: typebox_1.Type.String(),
changelogUrl: typebox_1.Type.Optional(typebox_1.Type.String()),
githubUrl: typebox_1.Type.Optional(typebox_1.Type.String()),
issuesUrl: typebox_1.Type.Optional(typebox_1.Type.String()),
requires: typebox_1.Type.Optional(typebox_1.Type.Array(typebox_1.Type.String())),
recommends: typebox_1.Type.Optional(typebox_1.Type.Array(typebox_1.Type.String())),
indicators: typebox_1.Type.Optional(exports.IndicatorResultSchema),
pluginCi: typebox_1.Type.Optional(exports.PluginCiSchema)
}, {
$id: 'AppStoreEntryExtension',
description: 'Extra fields enriched onto each App Store list entry.'
});
exports.PluginDetailPayloadSchema = typebox_1.Type.Object({
name: typebox_1.Type.String(),
version: typebox_1.Type.String(),
displayName: typebox_1.Type.Optional(typebox_1.Type.String()),
appIcon: typebox_1.Type.Optional(typebox_1.Type.String()),
installedIconUrl: typebox_1.Type.Optional(typebox_1.Type.String()),
screenshots: typebox_1.Type.Array(typebox_1.Type.String()),
installedScreenshotUrls: typebox_1.Type.Optional(typebox_1.Type.Array(typebox_1.Type.String())),
official: typebox_1.Type.Boolean(),
deprecated: typebox_1.Type.Boolean(),
// Header-display fields. These exist on list entries too, but the
// detail page must not depend on the list having been hydrated to
// render its header (a hard refresh of /apps/store/plugin/:name
// hits this endpoint without a list response in scope).
description: typebox_1.Type.Optional(typebox_1.Type.String()),
author: typebox_1.Type.Optional(typebox_1.Type.String()),
categories: typebox_1.Type.Optional(typebox_1.Type.Array(typebox_1.Type.String())),
githubUrl: typebox_1.Type.Optional(typebox_1.Type.String()),
npmUrl: typebox_1.Type.Optional(typebox_1.Type.String()),
isPlugin: typebox_1.Type.Optional(typebox_1.Type.Boolean()),
isWebapp: typebox_1.Type.Optional(typebox_1.Type.Boolean()),
readme: typebox_1.Type.String(),
changelog: typebox_1.Type.String(),
indicators: typebox_1.Type.Optional(exports.IndicatorResultSchema),
pluginCi: typebox_1.Type.Optional(exports.PluginCiSchema),
requires: typebox_1.Type.Array(exports.DependencyReferenceSchema),
recommends: typebox_1.Type.Array(exports.DependencyReferenceSchema),
recent: typebox_1.Type.Optional(typebox_1.Type.Boolean()),
readmeFormat: typebox_1.Type.Literal('markdown'),
changelogFormat: typebox_1.Type.Union([
typebox_1.Type.Literal('markdown'),
typebox_1.Type.Literal('synthesized')
]),
fetchedAt: typebox_1.Type.Number(),
fromCache: typebox_1.Type.Boolean()
}, {
$id: 'AppStorePluginDetailPayload',
description: 'Response body of GET /appstore/plugin/:name.'
});
//# sourceMappingURL=schemas.js.map