feat(interfaces): add structured data models and discriminated check configs; migrate tooling and package metadata

This commit is contained in:
2025-12-26 18:20:01 +00:00
parent add4a52635
commit da0bdc0564
23 changed files with 7721 additions and 3689 deletions

43
changelog.md Normal file
View File

@@ -0,0 +1,43 @@
# Changelog
## 2025-12-26 - 2.1.0 - feat(interfaces)
add structured data models and discriminated check configs; migrate tooling and package metadata
- Introduce TCheckConfig union and typed check config interfaces (IAssumptionCheckConfig, IFunctionCheckConfig, IPwaCheckConfig, IPageRankCheckConfig) and TExecutionTiming for runtimes
- Extend ICheckCollection to support a unified checks array while preserving legacy per-type arrays for backward compatibility
- Add service and status-page models (IServiceStatus, IOverallStatus, IServiceGroup, IStatusPageConfig) and richer incident types (IIncident, IIncidentUpdate) plus a legacy IIncidentLegacy shim
- Export central data index enhancements (re-exports for checks and types) and add new data files (types.ts, checks/index.ts, servicestatus.ts, statuspageconfig.ts)
- Migrate plugin and dependency namespaces (@apiglobal/... -> @api.global/..., @gitzone/* -> @git.zone/*) and update dependency versions
- Add npmextra release configuration (registries and accessLevel) and adjust tsconfig for NodeNext module resolution and verbatimModuleSyntax
## 2023-04-19 - 2.0.21 - core
Maintenance release with a series of core fixes and minor updates.
- Aggregated patch-level fixes and stability improvements applied across the 2.0.x line.
- Includes maintenance changes introduced in 2.0.4 through 2.0.21 (core updates, bug fixes, small adjustments).
- No breaking API changes.
## 2022-07-19 - 2.0.3 - core
Patch releases preparing and stabilizing the 2.0 series.
- Multiple small core updates and fixes delivered in 2.0.0 through 2.0.3.
- General maintenance and reliability improvements; no breaking changes.
## 2022-07-16 - 1.0.10 - core (BREAKING CHANGE)
Switch from CommonJS to ECMAScript Modules (ESM).
- BREAKING CHANGE: module system changed to ESM.
- Consumers must update imports/usage accordingly (CommonJS require() calls will need migration).
- Ensure build tools and runtime environments support ESM after this change.
## 2019-11-30 - 1.0.2 - interfaces
Introduce basic interface constructs for page checks.
- Implemented basic constructs for pagechecks under interfaces.
- Foundation for further interface-driven checks and validations.
## 2019-11-30 → 2021-03-08 - 1.0.31.0.9 - maintenance
Series of patch releases with minor fixes and updates.
- Multiple small fixes and maintenance updates across 1.0.3 through 1.0.9.
- General stability and housekeeping changes; no notable feature additions or breaking changes.

View File

@@ -1,5 +1,5 @@
{
"gitzone": {
"@git.zone/cli": {
"projectType": "npm",
"module": {
"githost": "gitlab.com",
@@ -9,10 +9,16 @@
"npmPackagename": "@uptime.link/interfaces",
"license": "MIT",
"projectDomain": "uptime.link"
},
"release": {
"registries": [
"https://verdaccio.lossless.digital",
"https://registry.npmjs.org"
],
"accessLevel": "public"
}
},
"npmci": {
"npmGlobalTools": [],
"npmAccessLevel": "public"
"@ship.zone/szci": {
"npmGlobalTools": []
}
}

View File

@@ -14,15 +14,14 @@
"buildDocs": "tsdoc"
},
"devDependencies": {
"@gitzone/tsbuild": "^2.1.65",
"@gitzone/tsrun": "^1.2.39",
"@gitzone/tstest": "^1.0.74",
"@pushrocks/tapbundle": "^5.0.4",
"@types/node": "^18.15.11"
"@git.zone/tsbuild": "^4.0.2",
"@git.zone/tsrun": "^2.0.1",
"@git.zone/tstest": "^3.1.3",
"@types/node": "^25.0.3"
},
"dependencies": {
"@apiglobal/typedrequest-interfaces": "^2.0.1",
"@tsclass/tsclass": "^4.0.38"
"@api.global/typedrequest-interfaces": "^3.0.19",
"@tsclass/tsclass": "^9.3.0"
},
"files": [
"ts/**/*",

10860
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
import { expect, tap } from '@pushrocks/tapbundle';
import { expect, tap } from '@git.zone/tstest/tapbundle';
import * as interfaces from '../ts/index.js';
tap.test('first test', async () => {

View File

@@ -1,8 +1,8 @@
/**
* autocreated commitinfo by @pushrocks/commitinfo
* autocreated commitinfo by @push.rocks/commitinfo
*/
export const commitinfo = {
name: '@uptime.link/interfaces',
version: '2.0.21',
version: '2.1.0',
description: 'TypeScript interface for the uptime.link API and modules'
}

View File

@@ -1,13 +1,24 @@
import * as plugins from '../ul-interfaces.plugins.js';
import * as search from './search.js';
import * as checks from './checks/index.js';
import type * as checks from './checks/index.js';
/**
* A collection of checks to run against a property/service.
*
* Two storage modes supported:
* 1. Legacy: Separate arrays for each check type (assumptionChecks, functionChecks, etc.)
* 2. Modern: Single unified array using discriminated union (checks)
*/
export interface ICheckCollection {
id: string;
name?: string;
description?: string;
intervalMs: number;
assumptionChecks?: Array<checks.IAssumptionCheck>;
functionChecks: Array<checks.IFunctionCheck>;
pwaChecks?: Array<checks.IPwaCheck>;
pageRankChecks: Array<checks.IPageRankCheck>;
// Modern: Single array with discriminated union
checks?: checks.TCheckConfig[];
// Legacy: Separate arrays by type (for backward compatibility)
assumptionChecks?: checks.IAssumptionCheck[];
functionChecks?: checks.IFunctionCheck[];
pwaChecks?: checks.IPwaCheck[];
pageRankChecks?: checks.IPageRankCheck[];
}

View File

@@ -1,6 +1,11 @@
import * as plugins from '../../ul-interfaces.plugins.js';
import { TCheckResultStatus, TExecutionTiming } from './index.js';
import type * as plugins from '../../ul-interfaces.plugins.js';
import type { TCheckResultStatus } from '../types.js';
import type { TExecutionTiming } from './index.js';
/**
* Assumption check execution data.
* Used by check runners to store input and results.
*/
export interface IAssumptionCheck {
inputData: {
domain: string;

View File

@@ -1,5 +1,10 @@
import { TCheckResultStatus, TExecutionTiming } from './index.js';
import type { TCheckResultStatus } from '../types.js';
import type { TExecutionTiming } from './index.js';
/**
* Function check execution data.
* Used by check runners to store input and results.
*/
export interface IFunctionCheck {
checkId: string;
inputData: {

View File

@@ -1,4 +1,8 @@
export type TCheckResultStatus = 'ok' | 'not ok' | 'timed out';
import type { TStatusType, TCheckResultStatus, TCheckLastResult } from '../types.js';
// ============================================
// Execution Timing (used by check runners)
// ============================================
export interface TExecutionTiming {
plannedTime: number;
@@ -7,6 +11,106 @@ export interface TExecutionTiming {
duration: number;
}
// Re-export for backward compatibility
export type { TCheckResultStatus };
// ============================================
// Check Configuration Base Interface
// ============================================
/**
* Base interface for all check configurations.
* Extended by discriminated variants.
*/
export interface ICheckBase {
id: string;
name: string;
description?: string;
enabled: boolean;
intervalMs?: number;
lastRun?: number;
lastResult?: TCheckLastResult;
}
// ============================================
// Discriminated Check Variants (Configuration)
// ============================================
/**
* Assumption check - assumes a status without active verification
*/
export interface IAssumptionCheckConfig extends ICheckBase {
checkType: 'assumption';
assumedStatus: TStatusType;
domain?: string;
title?: string;
statusCode?: string;
}
/**
* Function check - calls a URL and validates response
*/
export interface IFunctionCheckConfig extends ICheckBase {
checkType: 'function';
functionUrl: string;
domain?: string;
expectedStatusCode?: number;
timeoutMs?: number;
headers?: Record<string, string>;
}
/**
* PWA check - validates Progressive Web App criteria
*/
export interface IPwaCheckConfig extends ICheckBase {
checkType: 'pwa';
targetUrl: string;
domain?: string;
lighthouseThreshold?: number;
categories?: ('performance' | 'accessibility' | 'best-practices' | 'seo')[];
}
/**
* PageRank check - validates search engine ranking
*/
export interface IPageRankCheckConfig extends ICheckBase {
checkType: 'pagerank';
targetUrl: string;
domain?: string;
searchTerm: string;
minimumRank?: number;
checkGoogle?: boolean;
checkBing?: boolean;
googleMinRank?: number;
bingMinRank?: number;
}
// ============================================
// Union Type (for UI and generic handling)
// ============================================
/**
* Union of all check configuration types.
* Use `checkType` discriminant for type narrowing.
*
* @example
* function handleCheck(check: TCheckConfig) {
* if (check.checkType === 'function') {
* console.log(check.functionUrl); // TypeScript knows this exists
* }
* }
*/
export type TCheckConfig =
| IAssumptionCheckConfig
| IFunctionCheckConfig
| IPwaCheckConfig
| IPageRankCheckConfig;
// ============================================
// Execution Interfaces (Runtime Data)
// ============================================
// Keep existing execution interfaces for backward compatibility
export * from './assumption.check.js';
export * from './function.check.js';
export * from './pagerank.check.js';

View File

@@ -1,6 +1,11 @@
import * as search from '../search.js';
import { TCheckResultStatus, TExecutionTiming } from './index.js';
import type * as search from '../search.js';
import type { TCheckResultStatus } from '../types.js';
import type { TExecutionTiming } from './index.js';
/**
* PageRank check execution data.
* Used by check runners to store input and results.
*/
export interface IPageRankCheck {
inputData: {
subId: string;

View File

@@ -1,7 +1,13 @@
import { TCheckResultStatus } from './index.js';
import type { TCheckResultStatus } from '../types.js';
/**
* PWA check execution data.
* Used by check runners to store input and results.
*/
export interface IPwaCheck {
inputData: { domain: string };
inputData: {
domain: string;
};
executionResults: Array<{
subId: string;
timeStarted: number;

View File

@@ -1,5 +1,5 @@
import * as plugins from '../ul-interfaces.plugins.js';
import { ILinkSnapshot } from './linksnapshot.js';
import type { ILinkSnapshot } from './linksnapshot.js';
export interface IDomainSnapshot {
registration: {

View File

@@ -1,21 +1,80 @@
import * as plugins from '../ul-interfaces.plugins.js';
import type { TIncidentSeverity, TIncidentStatus } from './types.js';
// ============================================
// Incident Update
// ============================================
/**
* A single update within an incident timeline.
*/
export interface IIncidentUpdate {
id: string;
incidentId: string;
status: TIncidentStatus;
message: string;
createdAt: number;
createdBy?: string;
type?: 'comment' | 'status_change' | 'automatic';
}
// ============================================
// Incident
// ============================================
/**
* Represents an incident affecting one or more services.
*/
export interface IIncident {
id: string;
title: string;
description: string;
severity: TIncidentSeverity;
status: TIncidentStatus;
// Affected services
affectedServiceIds: string[];
// Timeline
createdAt: number;
updatedAt: number;
resolvedAt?: number;
firstResponseAt?: number;
// Updates history
updates: IIncidentUpdate[];
// Metadata
createdBy?: string;
assignedUserId?: string;
creationMode?: 'monitor' | 'manual';
// Scheduled maintenance
isScheduled?: boolean;
scheduledStartTime?: number;
scheduledEndTime?: number;
// Post-incident
postMortemLink?: string;
}
// ============================================
// Legacy Interface (for backward compatibility)
// ============================================
/**
* @deprecated Use IIncident instead
*/
export interface IIncidentLegacy {
timestamp: number;
firstResponseTimestamp?: number;
/**
* indicates
*/
status: 'discovered' | 'investigating' | 'fixing' | 'fixImplemented' | 'watching' | 'resolved';
creationMode: 'monitor' | 'manual';
assignedUserId?: string;
postMortemLink?: string;
updates: {
markdownText: string;
type: 'comment' | 'manualUpdate' | 'automaticUpdate';
}[];
justForLooks: {
isoTimestamp: string;
};

View File

@@ -1,11 +1,32 @@
// Core types
export * from './types.js';
// Check interfaces (configuration + execution)
export * from './checks/index.js';
// Collections
export * from './checkcollection.js';
export * from './domainsnapshot.js';
// Incidents
export * from './incident.js';
// Service status
export * from './servicestatus.js';
// Status page configuration
export * from './statuspageconfig.js';
// Domain and link snapshots
export * from './domainsnapshot.js';
export * from './linksnapshot.js';
// Property and search
export * from './property.js';
export * from './search.js';
// Status (90-day history)
export * from './status.js';
// Re-export checks namespace for convenience
import * as checks from './checks/index.js';
export { checks };

64
ts/data/servicestatus.ts Normal file
View File

@@ -0,0 +1,64 @@
import type { TStatusType, TStatusMode, TCheckType } from './types.js';
// ============================================
// Service Status
// ============================================
/**
* Represents the status of a monitored service.
*/
export interface IServiceStatus {
id: string;
name: string;
displayName: string;
description?: string;
// Current state
currentStatus: TStatusType;
lastChecked: number;
responseTime: number;
// Uptime metrics
uptime30d: number;
uptime90d: number;
// Organization
category?: string;
dependencies?: string[];
// Status management
statusMode: TStatusMode;
manualStatus?: TStatusType;
paused: boolean;
// Check configuration
checkType?: TCheckType;
checkCollectionId?: string;
intervalMs?: number;
}
// ============================================
// Status History
// ============================================
/**
* A point in the status history timeline.
*/
export interface IStatusHistoryPoint {
timestamp: number;
status: TStatusType;
responseTime?: number;
}
// ============================================
// Overall Status
// ============================================
/**
* Aggregate status for a group of services or entire status page.
*/
export interface IOverallStatus {
status: TStatusType;
message?: string;
lastUpdated: number;
}

View File

@@ -0,0 +1,57 @@
import type { IOverallStatus } from './servicestatus.js';
// ============================================
// Service Group
// ============================================
/**
* A group of related services displayed together.
*/
export interface IServiceGroup {
id: string;
name: string;
description?: string;
serviceIds: string[];
expanded: boolean;
order?: number;
}
// ============================================
// Status Page Configuration
// ============================================
/**
* Configuration for a public status page.
*/
export interface IStatusPageConfig {
id: string;
name: string;
slug: string;
// Branding
logoUrl?: string;
faviconUrl?: string;
primaryColor?: string;
customCss?: string;
// Content
headerTitle: string;
headerDescription?: string;
footerText?: string;
// Features
showHistoricalUptime: boolean;
showResponseTime: boolean;
showSubscribeButton: boolean;
showIncidentHistory: boolean;
// Service grouping
serviceGroups: IServiceGroup[];
// Overall status override
overallStatus?: IOverallStatus;
// Custom domain
customDomain?: string;
sslEnabled?: boolean;
}

63
ts/data/types.ts Normal file
View File

@@ -0,0 +1,63 @@
/**
* Shared type definitions for uptime.link
*/
// ============================================
// Status Types
// ============================================
/**
* Status types for monitors/services
*/
export type TStatusType =
| 'operational'
| 'degraded'
| 'partial_outage'
| 'major_outage'
| 'maintenance'
| 'initializing'
| 'error'
| 'paused';
/**
* Check types (discriminant values for TCheck union)
*/
export type TCheckType = 'assumption' | 'function' | 'pwa' | 'pagerank';
/**
* Status mode for monitors - auto follows checks, manual is user-set
*/
export type TStatusMode = 'auto' | 'manual';
// ============================================
// Incident Types
// ============================================
/**
* Incident severity levels
*/
export type TIncidentSeverity = 'critical' | 'major' | 'minor' | 'maintenance';
/**
* Incident status workflow
*/
export type TIncidentStatus =
| 'investigating'
| 'identified'
| 'monitoring'
| 'resolved'
| 'postmortem';
// ============================================
// Check Result Types (used by execution)
// ============================================
/**
* Result status for check execution
*/
export type TCheckResultStatus = 'ok' | 'not ok' | 'timed out';
/**
* Last result state for a check
*/
export type TCheckLastResult = 'success' | 'failure' | 'pending';

View File

@@ -1,4 +1,4 @@
import { ICheckCollection } from '../data/checkcollection.js';
import type { ICheckCollection } from '../data/checkcollection.js';
import * as plugins from '../ul-interfaces.plugins.js';
export interface IRequest_CheckExchange

View File

@@ -1,5 +1,5 @@
import { IDomainSnapshot } from '../data/domainsnapshot.js';
import { ILinkSnapshot } from '../data/linksnapshot.js';
import type { IDomainSnapshot } from '../data/domainsnapshot.js';
import type { ILinkSnapshot } from '../data/linksnapshot.js';
import * as plugins from '../ul-interfaces.plugins.js';
export interface IReq_PerformDomainSnapshot

View File

@@ -1,6 +1,6 @@
import * as plugins from '../ul-interfaces.plugins.js';
import * as data from '../data/index.js';
import { IStatus } from '../data/status.js';
import type { IStatus } from '../data/status.js';
export interface IRequest_Status_Get
extends plugins.typedRequestInterfaces.implementsTR<

View File

@@ -1,4 +1,4 @@
import * as typedRequestInterfaces from '@apiglobal/typedrequest-interfaces';
import * as typedRequestInterfaces from '@api.global/typedrequest-interfaces';
export { typedRequestInterfaces };

View File

@@ -1,10 +1,12 @@
{
"compilerOptions": {
"experimentalDecorators": true,
"useDefineForClassFields": false,
"target": "ES2022",
"module": "ES2022",
"moduleResolution": "nodenext",
"esModuleInterop": true
}
"module": "NodeNext",
"moduleResolution": "NodeNext",
"esModuleInterop": true,
"verbatimModuleSyntax": true
},
"exclude": [
"dist_*/**/*.d.ts"
]
}