api_ianmenethil_comswaggerService.ts9 matches
5/**
6* Service for generating Swagger UI HTML documentation
7* Handles the generation of interactive Swagger UI that consumes OpenAPI specifications
8*/
9export class SwaggerUIService {
10/**
11* Generate Swagger UI HTML page
12* Creates a complete HTML page with Swagger UI embedded that fetches the OpenAPI spec
13*
14* @param specUrl - URL to the OpenAPI JSON specification
15* @returns HTML string for Swagger UI documentation page
16*/
17generateSwaggerHTML(specUrl: string = "/v1/openapi.json"): string {
18return `<!DOCTYPE html>
19<html>
20<head>
21<title>API Documentation</title>
22<link rel="stylesheet" type="text/css" href="https://unpkg.com/swagger-ui-dist@5.11.0/swagger-ui.css" />
23</head>
29url: '${specUrl}',
30dom_id: '#swagger-ui',
31presets: [SwaggerUIBundle.presets.apis, SwaggerUIBundle.presets.standalone]
32});
33</script>
53/**
54* Validate that the spec URL is accessible
55* Basic validation to ensure the OpenAPI spec URL is valid
56*
57* @param specUrl - URL to validate
65return {
66valid: false,
67error: "Invalid OpenAPI specification URL",
68};
69}
104export function getSwaggerUI(c: Context<{ Variables: Variables }>): Response {
105try {
106const html = swaggerUIService.generateSwaggerHTML("/v1/openapi.json");
107return c.html(html);
108} catch (error) {
api_ianmenethil_comredoclyService.ts9 matches
5/**
6* Service for generating Redoc HTML documentation
7* Handles the generation of Redoc interface that consumes OpenAPI specifications
8*/
9export class RedoclyService {
10/**
11* Generate Redoc HTML page
12* Creates a complete HTML page with Redoc embedded that fetches the OpenAPI spec
13*
14* @param specUrl - URL to the OpenAPI JSON specification
15* @returns HTML string for Redoc documentation page
16*/
17generateRedocHTML(specUrl: string = "/v1/openapi.json"): string {
18return `<!DOCTYPE html>
19<html>
20<head>
21<title>API Documentation - Redoc</title>
22<meta charset="utf-8"/>
23<meta name="viewport" content="width=device-width, initial-scale=1">
24<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
25<style>body{margin:0;padding:0;}</style>
26</head>
49/**
50* Validate that the spec URL is accessible
51* Basic validation to ensure the OpenAPI spec URL is valid
52*
53* @param specUrl - URL to validate
61return {
62valid: false,
63error: "Invalid OpenAPI specification URL",
64};
65}
77export function getRedoc(c: Context<{ Variables: Variables }>): Response {
78try {
79const html = redoclyService.generateRedocHTML("/v1/openapi.json");
80return c.html(html);
81} catch (error) {
1// F:\zApps\valtown.servers\APIServer\src\handlers\proxy.service.ts
2import { getCurrentDateInSydney } from "@/utils/dateUtils.ts";
3import { Context } from "hono";
api_ianmenethil_comopenapiService.ts38 matches
1/**
2* openapi.service.ts - Serves the OpenAPI specification.
3* Uses OpenAPILoader to get the fully resolved specification.
4*/
56import { stringify } from "yaml";
7import { loadOpenAPISpec } from "@/openapi/loader.ts";
8import { getCurrentDateInSydney } from "@/utils/dateUtils.ts";
9import { Context } from "hono";
30}
3132interface OpenAPIDocument {
33openapi: string;
34info: any;
35servers: any[];
37components: any;
38// Adding an index signature to make it compatible with yaml.stringify
39// and to acknowledge that OpenAPI documents can have various other top-level extension fields.
40[key: string]: any;
41}
4243export class OpenapiSpecService {
44private openapiSpecPromise: Promise<OpenAPIDocument> | null = null;
45private readonly rootPath: string;
4647constructor(rootPath: string) {
48this.rootPath = rootPath;
49this.openapiSpecPromise = loadOpenAPISpec(this.rootPath) as Promise<OpenAPIDocument>;
50}
5152private async getSpec(): Promise<OpenAPIDocument> {
53if (!this.openapiSpecPromise) {
54console.warn(
55"OpenapiSpecService: Spec promise not initialized or failed, attempting to load now.",
56);
57this.openapiSpecPromise = loadOpenAPISpec(this.rootPath) as Promise<OpenAPIDocument>;
58}
59try {
60const spec = await this.openapiSpecPromise;
61if (!spec) { // Check if the loaded spec is null or undefined
62throw new Error("Loaded OpenAPI specification is null or undefined.");
63}
64return spec;
65} catch (error: unknown) {
66const message = getErrorMessage(error);
67console.error("OpenapiSpecService: Failed to load/get OpenAPI spec:", error); // Log the original error too
68this.openapiSpecPromise = null; // Clear the promise so it can be retried
69throw new Error(`Failed to load OpenAPI specification: ${message}`);
70}
71}
7273async getOpenAPIJSONObject(): Promise<OpenAPIDocument> {
74return await this.getSpec();
75}
7677async getOpenAPIYAMLString(): Promise<string> {
78try {
79const jsonSpec = await this.getSpec();
80// The OpenAPIDocument with an index signature [key: string]: any;
81// should now be compatible with stringify.
82return stringify(jsonSpec);
83} catch (error: unknown) {
84const message = getErrorMessage(error);
85console.error("OpenapiSpecService: Failed to generate OpenAPI YAML:", error);
86throw new Error(`Failed to generate OpenAPI YAML specification: ${message}`);
87}
88}
93error: errorMessage,
94format,
95service: "openapi-spec-service",
96timestamp: getCurrentDateInSydney(),
97};
106return {
107valid: false,
108error: `OpenAPI spec validation failed: ${message}`,
109};
110}
112}
113114export const openapiSpecService = new OpenapiSpecService("src/openapi/spec");
115116/**
117* OpenAPI JSON handler function for use in service router
118* @param c - Hono context with Variables
119* @returns Response with OpenAPI JSON specification
120*/
121export async function getOpenAPIJSON(c: Context<{ Variables: Variables }>): Promise<Response> {
122try {
123const spec = await openapiSpecService.getOpenAPIJSONObject();
124return c.json(spec);
125} catch (error) {
126const msg = getErrorMessage(error);
127console.error(`Error in getOpenAPIJSON: ${msg}`, error);
128return c.json(openapiSpecService.createErrorResponse(msg, "json"), 500);
129}
130}
131132/**
133* OpenAPI YAML handler function for use in service router
134* @param c - Hono context with Variables
135* @returns Response with OpenAPI YAML specification
136*/
137export async function getOpenAPIYAML(c: Context<{ Variables: Variables }>): Promise<Response> {
138try {
139const yamlString = await openapiSpecService.getOpenAPIYAMLString();
140c.res.headers.set("Content-Type", "application/yaml; charset=utf-8");
141return c.text(yamlString);
142} catch (error) {
143const msg = getErrorMessage(error);
144console.error(`Error in getOpenAPIYAML: ${msg}`, error);
145return c.json(openapiSpecService.createErrorResponse(msg, "yaml"), 500);
146}
147}
1/**
2* spotify.auth.service.ts — Spotify OAuth authentication service handlers.
3* Implements OpenAPI operations using existing middleware and services.
4*/
5292async function fetchSpotifyUserInfo(accessToken: string) {
293try {
294const userRequest = await fetch("https://api.spotify.com/v1/me", {
295headers: {
296"Authorization": `Bearer ${accessToken}`,
api_ianmenethil_comindex.ts1 match
1// F:\zApps\valtown.servers\APIServer\src\handlers\oauth\index.ts
23export { getGoogleOAuthURL, handleGoogleCallback } from "./googleAuthService.ts";
1// F:\zApps\valtown.servers\APIServer\src\handlers\oauth\google.auth.service.ts
2/**
3* auth.service.ts — OAuth authentication service handlers.
4* Implements OpenAPI operations using existing middleware and services.
5*/
6
1// F:\zApps\valtown.servers\APIServer\src\handlers\oauth\github.auth.service.ts
2/**
3* github.auth.service.ts — GitHub OAuth authentication service handlers.
4* Implements OpenAPI operations using existing middleware and services.
5*/
6296"Authorization": `Bearer ${accessToken}`,
297"Accept": "application/vnd.github.v3+json",
298"User-Agent": "Val.town-API-Server/2.0",
299},
300});
348async function fetchGitHubUserEmail(accessToken: string) {
349try {
350const emailRequest = await fetch("https://api.github.com/user/emails", {
351headers: {
352"Authorization": `Bearer ${accessToken}`,
353"Accept": "application/vnd.github.v3+json",
354"User-Agent": "Val.town-API-Server/2.0",
355},
356});
api_ianmenethil_cominfoService.ts19 matches
45// You can store these in environment variables or a config file
6const API_VERSION = Deno.env.get("API_VERSION") || "1.0.0";
7const API_BUILD = Deno.env.get("API_BUILD") || "unknown";
8const API_ENV = Deno.env.get("API_ENV") || "development";
910/**
11* Service for providing API information and version details
12*/
13export class InfoService {
14/**
15* Get basic API information
16* @returns API info object with status and basic metadata
17*/
18getApiInfo() {
19return {
20success: true,
21name: "ValTown API Server",
22version: API_VERSION,
23status: "operational",
24environment: API_ENV,
25timestamp: getCurrentDateInSydney(),
26uptime: null, // Note: Deno doesn't have process.uptime()
29swagger: "/v1/docs",
30redoc: "/v1/redoc",
31openapi: "/v1/openapi.json",
32},
33external: {
47success: true,
48version: {
49api: API_VERSION,
50build: API_BUILD,
51environment: API_ENV,
52node: Deno.version.deno,
53v8: Deno.version.v8,
8586/**
87* API info handler function for use in service router
88* @param c - Hono context with Variables
89* @returns Response with API information
90*/
91export function getApiInfo(c: Context<{ Variables: Variables }>): Response {
92try {
93const info = infoService.getApiInfo();
94return c.json(info);
95} catch (error) {
96const errorResponse = infoService.createErrorResponse(
97error instanceof Error ? error.message : "Failed to retrieve API information",
98);
99return c.json(errorResponse, 500);
api_ianmenethil_comhashService.ts20 matches
31*/
32export const ZenithHashRequestSchema = z.object({
33apiKey: z.string().min(1, "API key cannot be empty"),
34username: z.string().min(1, "Username cannot be empty"),
35password: z.string().min(1, "Password cannot be empty"),
6061export const AuthenticatedZenithHashRequestSchema = z.object({
62apiKey: z.string().min(1, "API key cannot be empty"),
63username: z.string().optional(),
64password: z.string().optional(),
128*
129* This endpoint helps clients generate the required fingerprint
130* for Zenith Payments API integration without exposing credentials.
131*
132* The generated hash should be used as the 'fingerprint' field
456457// Create hash string according to Zenith format
458const { apiKey, mode, paymentAmount, merchantUniquePaymentId, timestamp } = validatedData;
459const hashString =
460`${apiKey}|${username}|${password}|${mode}|${paymentAmount}|${merchantUniquePaymentId}|${timestamp}`;
461462// Get algorithm
530531/**
532* Generate hash using Web Crypto API
533*/
534async function generateHash(data: string, algorithm: string): Promise<string> {
547break;
548case "SHA3-512":
549// SHA3-512 is not natively supported in Web Crypto API
550// Try it first, fallback to SHA-512
551try {
626suggestion =
627'Payment amount must be in cents/pence as whole numbers only. For $12.34, use "1234". For $100.00, use "10000".';
628} else if (field === "apiKey") {
629suggestion = "API key should be provided by Zenith Payments";
630}
631672673return await c.json({
674purpose: "Generate fingerprint hash for Zenith Payments API",
675endpoint: "/v1/hash",
676current_time: currentTime,
699description: "SHA-1 hash of concatenated fields",
700algorithm: "SHA-1",
701use_case: "Zenith API v3 integration",
702warning: "SHA-1 is deprecated for security reasons, use v5",
703example_request: {
704apiKey: "test_api_key",
705username: "merchant_user",
706password: "merchant_pass",
715description: "SHA-512 hash of concatenated fields",
716algorithm: "SHA-512",
717use_case: "Zenith API v4 integration (recommended by Zenith)",
718example_request: {
719apiKey: "test_api_key",
720username: "merchant_user",
721password: "merchant_pass",
732use_case: "Most secure option for future compatibility",
733example_request: {
734apiKey: "test_api_key",
735username: "merchant_user",
736password: "merchant_pass",
745v3_v4_v5_format: {
746description: "Concatenated string format for hashing",
747format: "apiKey|username|password|mode|paymentAmount|merchantUniquePaymentId|timestamp",
748example: "test_api_key|merchant_user|merchant_pass|0|10050|INV-2025-001|2025-06-15T19:42:13Z",
749},
750required_fields: {
755v3_v4_v5: {
756public_access: [
757"apiKey",
758"username",
759"password",
764],
765authenticated_access: [
766"apiKey",
767"username (optional)",
768"password (optional)",
786},
787authenticated_access: {
788description: "Requires API key or session authentication",
789benefit: "Username and password can use environment defaults if not provided in request",
790},