feat: add link creation and lookup
All checks were successful
Build and push Docker image / build (push) Successful in 2m50s
Release new version / release (push) Successful in 26s
Update changelog / changelog (push) Successful in 25s

finally has the bare minimum functionality to say that it works!
This commit is contained in:
2026-01-03 10:51:59 +01:00
parent c19a098b1c
commit d7f4006698
8 changed files with 477 additions and 34 deletions

View File

@@ -62,3 +62,84 @@ export type LinkResponseDTO = {
subdomain?: string | null; // null when server does not support generating subdomains
};
// POST /api/v1/link/short
/**
* @openapi
* components:
* schemas:
* CreateLinkRequestDTO:
* type: object
* required:
* - uri
* - remoteUrl
* properties:
* uri:
* type: string
* default: short uri
* remoteUrl:
* type: string
* default: source url
* subdomain:
* type: string
* default: optional subdomain
* privacy:
* type: boolean
* default: true # privacy by default
* expiryDate:
* type: number
* default: 1767413102824 # UNIX timestamp in ms, Date.now()
*/
const createLinkRequestSchemaBody = z.object({
uri: z.string({
error: (e) =>
e.input === undefined ? 'Uri is required' : '/, ?, &, = and & are not allowed'
}).min( 3, 'Shortened Uri must be at least 3 characters long')
.max(128, 'Shortened Uri cannot be longer than 128 characters')
.regex(/^[^\/?&=#]*$/),
remoteUrl: z.url({
error: (e) =>
e.input === undefined ? 'RemoteUrl is required' : 'RemoteUrl is not a valid URL'
}),
privacy: z.boolean({ error: 'Privacy must be a boolean (true by default)' })
.optional(),
subdomain: z.string('Subdomain must be a string of length between 1 and 32')
.min( 1, 'Subdomain should be at least 1 character long')
.max(32, 'Subdomain should not be longer than 32 characters')
.regex(/^[a-zA-Z0-9]*$/)
.optional(),
expiryDate: z.number('Expiry date must be a number (UNIX timestamp with milliseconds)')
.min(Date.now(), 'Expiry date is a UNIX timestamp with milliseconds')
.optional()
});
export const createLinkRequestSchema = z.object({
body: createLinkRequestSchemaBody
});
export type CreateLinkRequestDTO = z.TypeOf<typeof createLinkRequestSchema>;
/**
* @swagger
* components:
* schemas:
* CreateLinkResponseDTO:
* type: object
* required:
* - status
* - uri
* - subdomain
* properties:
* status:
* type: string
* default: ok on success, otherwise ErrorDTO with error
* uri:
* type: string
* default: full public, shortened url
* id:
* type: number
*/
export type CreateLinkResponseDTO = {
status: 'ok';
uri: string;
id: number;
};

View File

@@ -1,3 +1,4 @@
import * as z from 'zod';
/**
* @openapi
@@ -24,3 +25,8 @@ export type ErrorDTO = {
error: string;
code?: string | undefined;
};
// Used to check against reserved names.
export const disallowedUriSchema = z
.string()
.regex(/^(about|assets|kttydocs|panel)/);