@slopware/sloppy 0.1.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,17 @@
1
+ Sloppy is licensed under the Apache License, Version 2.0.
2
+ The full text is available in the project root LICENSE file and at
3
+ http://www.apache.org/licenses/LICENSE-2.0.
4
+
5
+ Copyright 2026 The Sloppy Authors
6
+
7
+ Licensed under the Apache License, Version 2.0 (the "License");
8
+ you may not use this file except in compliance with the License.
9
+ You may obtain a copy of the License at
10
+
11
+ http://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ Unless required by applicable law or agreed to in writing, software
14
+ distributed under the License is distributed on an "AS IS" BASIS,
15
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
16
+ implied. See the License for the specific language governing permissions
17
+ and limitations under the License.
package/README.md ADDED
@@ -0,0 +1,25 @@
1
+ # @slopware/sloppy
2
+
3
+ This package is a thin launcher for installing the Sloppy runtime. It selects an installed
4
+ platform package and forwards arguments to the packaged `sloppy` binary.
5
+
6
+ The alpha root package references supported platform packages for Windows x64,
7
+ Linux x64 GNU, and macOS. Platform packages contain the native CLI binaries,
8
+ bootstrap stdlib, built-in project templates, selected docs/examples,
9
+ manifest, and license files. The launcher sets `SLOPPY_SLOPPYC` so commands
10
+ such as `sloppy create`, `sloppy build`, and `sloppy package` work outside a
11
+ repository checkout.
12
+
13
+ The root package includes TypeScript declarations for the public starter
14
+ surface (`sloppy`, `sloppy/data`, `sloppy/fs`, `sloppy/os`, and
15
+ `sloppy/providers/sqlite`) so app workspaces can install it as a local dev
16
+ dependency for editor IntelliSense.
17
+
18
+ npm is only a distribution channel for Sloppy itself. Sloppy apps can bundle
19
+ compatible already-installed pure-JavaScript packages when their imports fit
20
+ Sloppy's resolver, module loader, and runtime boundary. Sloppy does not install
21
+ packages from a registry, solve semver, support Node native addons/N-API, or
22
+ claim full Node compatibility in this alpha track.
23
+
24
+ The package has no native install script, no `node-gyp`, and no postinstall V8 build or
25
+ download.
package/bin/sloppy.js ADDED
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ const { spawnSync } = require("node:child_process");
5
+ const path = require("node:path");
6
+ const { resolvePlatformPackage } = require("../lib/platform");
7
+
8
+ function main() {
9
+ const selected = resolvePlatformPackage(process.env, process.platform, process.arch);
10
+ if (!selected.supported) {
11
+ console.error(selected.message);
12
+ return 1;
13
+ }
14
+
15
+ let packageJsonPath;
16
+ try {
17
+ packageJsonPath = require.resolve(`${selected.packageName}/package.json`);
18
+ } catch {
19
+ console.error(
20
+ `Sloppy runtime platform package '${selected.packageName}' is not installed. ` +
21
+ "Install the matching @slopware/sloppy platform package generated from a tested release archive."
22
+ );
23
+ return 1;
24
+ }
25
+
26
+ const packageRoot = path.dirname(packageJsonPath);
27
+ const platformBin = path.join(packageRoot, "bin");
28
+ const executable = path.join(platformBin, process.platform === "win32" ? "sloppy.exe" : "sloppy");
29
+ const sloppyc = path.join(platformBin, process.platform === "win32" ? "sloppyc.exe" : "sloppyc");
30
+ const pathKey = Object.keys(process.env).find((key) => /^path$/i.test(key)) || "PATH";
31
+ const currentPath = process.env[pathKey] || "";
32
+ const childEnv = {
33
+ ...process.env,
34
+ [pathKey]: `${platformBin}${path.delimiter}${currentPath}`,
35
+ SLOPPY_SLOPPYC: process.env.SLOPPY_SLOPPYC || sloppyc
36
+ };
37
+ const result = spawnSync(executable, process.argv.slice(2), { stdio: "inherit", env: childEnv });
38
+ if (result.error) {
39
+ console.error(`Failed to run packaged Sloppy binary '${executable}': ${result.error.message}`);
40
+ return 1;
41
+ }
42
+ return typeof result.status === "number" ? result.status : 1;
43
+ }
44
+
45
+ process.exitCode = main();
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+
3
+ function effectivePlatform(env, processPlatform) {
4
+ return env.SLOPPY_RUNTIME_PLATFORM || processPlatform;
5
+ }
6
+
7
+ function effectiveArch(env, processArch) {
8
+ return env.SLOPPY_RUNTIME_ARCH || processArch;
9
+ }
10
+
11
+ function effectiveLibc(env, platform) {
12
+ if (env.SLOPPY_RUNTIME_LIBC) {
13
+ return env.SLOPPY_RUNTIME_LIBC;
14
+ }
15
+ if (platform !== "linux") {
16
+ return "";
17
+ }
18
+ if (
19
+ typeof process !== "undefined" &&
20
+ process.report &&
21
+ typeof process.report.getReport === "function"
22
+ ) {
23
+ const report = process.report.getReport();
24
+ if (report && report.header && report.header.glibcVersionRuntime) {
25
+ return "gnu";
26
+ }
27
+ }
28
+ return "musl";
29
+ }
30
+
31
+ function resolvePlatformPackage(env, processPlatform, processArch) {
32
+ const platform = effectivePlatform(env, processPlatform);
33
+ const arch = effectiveArch(env, processArch);
34
+ const libc = effectiveLibc(env, platform);
35
+
36
+ if (platform === "win32" && arch === "x64") {
37
+ return { supported: true, packageName: "@slopware/sloppy-win32-x64" };
38
+ }
39
+ if (platform === "linux" && arch === "x64" && libc === "gnu") {
40
+ return { supported: true, packageName: "@slopware/sloppy-linux-x64" };
41
+ }
42
+ if (platform === "darwin" && arch === "arm64") {
43
+ return { supported: true, packageName: "@slopware/sloppy-darwin-arm64" };
44
+ }
45
+ if (platform === "darwin" && arch === "x64") {
46
+ return { supported: true, packageName: "@slopware/sloppy-darwin-x64" };
47
+ }
48
+
49
+ return {
50
+ supported: false,
51
+ message:
52
+ `Unsupported Sloppy runtime npm platform: platform=${platform} arch=${arch} libc=${libc}. ` +
53
+ "Use a GitHub Release archive or build Sloppy from source for this platform."
54
+ };
55
+ }
56
+
57
+ module.exports = { resolvePlatformPackage };
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@slopware/sloppy",
3
+ "version": "0.1.0-alpha.0",
4
+ "description": "Sloppy runtime launcher. npm installs Sloppy itself; it does not add npm package support to Sloppy apps.",
5
+ "license": "Apache-2.0",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/RtlZeroMemory/Slop.git"
9
+ },
10
+ "bin": {
11
+ "sloppy": "bin/sloppy.js"
12
+ },
13
+ "files": [
14
+ "bin/",
15
+ "lib/",
16
+ "types/",
17
+ "LICENSE",
18
+ "README.md",
19
+ "package.json"
20
+ ],
21
+ "optionalDependencies": {
22
+ "@slopware/sloppy-win32-x64": "0.1.0-alpha.0",
23
+ "@slopware/sloppy-linux-x64": "0.1.0-alpha.0",
24
+ "@slopware/sloppy-darwin-arm64": "0.1.0-alpha.0",
25
+ "@slopware/sloppy-darwin-x64": "0.1.0-alpha.0"
26
+ },
27
+ "publishConfig": {
28
+ "tag": "alpha",
29
+ "access": "public"
30
+ },
31
+ "types": "types/index.d.ts",
32
+ "typesVersions": {
33
+ "*": {
34
+ "os": [
35
+ "types/os.d.ts"
36
+ ],
37
+ "fs": [
38
+ "types/fs.d.ts"
39
+ ],
40
+ "data": [
41
+ "types/data.d.ts"
42
+ ],
43
+ "providers/sqlite": [
44
+ "types/providers/sqlite.d.ts"
45
+ ]
46
+ }
47
+ }
48
+ }
@@ -0,0 +1,24 @@
1
+ export interface SqlFragment {
2
+ readonly __sloppySql?: true;
3
+ }
4
+
5
+ export interface MigrationOptions {
6
+ provider?: string;
7
+ path?: string;
8
+ [key: string]: unknown;
9
+ }
10
+
11
+ export const sql: {
12
+ sqlite(strings: TemplateStringsArray, ...values: unknown[]): SqlFragment;
13
+ postgres(strings: TemplateStringsArray, ...values: unknown[]): SqlFragment;
14
+ sqlserver(strings: TemplateStringsArray, ...values: unknown[]): SqlFragment;
15
+ };
16
+
17
+ export const data: Record<string, unknown>;
18
+ export const Migrations: {
19
+ apply(database: unknown, options?: MigrationOptions): Promise<unknown>;
20
+ run(options?: MigrationOptions): Promise<unknown>;
21
+ status(options?: MigrationOptions): Promise<unknown>;
22
+ };
23
+ export const ProviderHealth: Record<string, unknown>;
24
+ export function isRealDataProvider(value: unknown): boolean;
package/types/fs.d.ts ADDED
@@ -0,0 +1,23 @@
1
+ export const File: {
2
+ readText(path: string, options?: Record<string, unknown>): Promise<string>;
3
+ writeText(path: string, value: string, options?: Record<string, unknown>): Promise<void>;
4
+ readBytes(path: string, options?: Record<string, unknown>): Promise<Uint8Array>;
5
+ writeBytes(path: string, value: Uint8Array | ArrayBuffer, options?: Record<string, unknown>): Promise<void>;
6
+ exists(path: string): Promise<boolean>;
7
+ };
8
+
9
+ export const Directory: {
10
+ create(path: string, options?: Record<string, unknown>): Promise<void>;
11
+ exists(path: string): Promise<boolean>;
12
+ entries(path: string, options?: Record<string, unknown>): Promise<string[]>;
13
+ };
14
+
15
+ export const Path: {
16
+ join(...parts: string[]): string;
17
+ dirname(path: string): string;
18
+ basename(path: string): string;
19
+ extname(path: string): string;
20
+ };
21
+
22
+ export const FileHandle: Record<string, unknown>;
23
+ export const FileWatcher: Record<string, unknown>;
@@ -0,0 +1,177 @@
1
+ /// <reference path="./providers/sqlite.d.ts" />
2
+ /// <reference path="./sloppy.d.ts" />
3
+
4
+ export type Awaitable<T> = T | Promise<T>;
5
+ export type JsonPrimitive = string | number | boolean | null;
6
+ export type JsonValue = JsonPrimitive | JsonValue[] | { [key: string]: JsonValue };
7
+
8
+ export type Route<T = string> = T;
9
+ export type Query<T = string> = T;
10
+ export type Header<T = string> = T;
11
+ export type Body<T = unknown> = T;
12
+ export type Service<T = unknown> = T;
13
+
14
+ export interface SloppyRequest {
15
+ method: string;
16
+ path: string;
17
+ headers?: Record<string, string>;
18
+ query?: Record<string, string | string[]>;
19
+ body?: unknown;
20
+ }
21
+
22
+ export interface RequestBody<T = unknown> {
23
+ value?: T;
24
+ text(): Promise<string>;
25
+ json<TJson = unknown>(): Promise<TJson>;
26
+ validate<TValue>(schema: SchemaType<TValue>): Promise<TValue>;
27
+ }
28
+
29
+ export interface RequestContext {
30
+ request: SloppyRequest;
31
+ route: Record<string, string>;
32
+ routeName?: string;
33
+ requestId?: string;
34
+ services?: Record<string, unknown>;
35
+ body: RequestBody;
36
+ log?: {
37
+ debug(message: string, fields?: Record<string, unknown>): void;
38
+ info(message: string, fields?: Record<string, unknown>): void;
39
+ warn(message: string, fields?: Record<string, unknown>): void;
40
+ error(message: string, fields?: Record<string, unknown>): void;
41
+ };
42
+ }
43
+
44
+ export interface ResultDescriptor<TBody = unknown> {
45
+ readonly __sloppyResult?: true;
46
+ readonly kind?: string;
47
+ readonly status?: number;
48
+ readonly headers?: Record<string, string>;
49
+ readonly contentType?: string;
50
+ readonly body?: TBody;
51
+ }
52
+
53
+ export type Handler<T = unknown> = (ctx: RequestContext) => Awaitable<T | ResultDescriptor<T>>;
54
+ export type Middleware = (ctx: RequestContext, next: () => Awaitable<ResultDescriptor>) => Awaitable<ResultDescriptor>;
55
+
56
+ export interface RouteBuilder {
57
+ withName(name: string): RouteBuilder;
58
+ withTags(...tags: string[]): RouteBuilder;
59
+ produces(status: number, contentType?: string): RouteBuilder;
60
+ accepts(schema: SchemaType, options?: Record<string, unknown>): RouteBuilder;
61
+ returns(schema: SchemaType, options?: Record<string, unknown>): RouteBuilder;
62
+ }
63
+
64
+ export interface RouteGroup {
65
+ use(middleware: Middleware): RouteGroup;
66
+ get(path: string, handler: Handler): RouteBuilder;
67
+ post(path: string, handler: Handler): RouteBuilder;
68
+ put(path: string, handler: Handler): RouteBuilder;
69
+ patch(path: string, handler: Handler): RouteBuilder;
70
+ delete(path: string, handler: Handler): RouteBuilder;
71
+ group(prefix: string): RouteGroup;
72
+ }
73
+
74
+ export interface SloppyApp extends RouteGroup {
75
+ useCors(options?: Record<string, unknown>): SloppyApp;
76
+ useErrors(options?: Record<string, unknown>): SloppyApp;
77
+ useStaticFiles(options: Record<string, unknown>): SloppyApp;
78
+ useModule(module: (app: SloppyApp) => void): SloppyApp;
79
+ provider<T = unknown>(name: string): T;
80
+ mapController(prefix: string, controller: new (...args: any[]) => unknown, configure: (mapper: any) => void): SloppyApp;
81
+ }
82
+
83
+ export interface ServiceBuilder {
84
+ addSingleton<T>(name: string, factory: () => T): ServiceBuilder;
85
+ addScoped<T>(name: string, factory: () => T): ServiceBuilder;
86
+ addTransient<T>(name: string, factory: () => T): ServiceBuilder;
87
+ }
88
+
89
+ export interface SloppyBuilder {
90
+ services: ServiceBuilder;
91
+ build(): SloppyApp;
92
+ }
93
+
94
+ export const Sloppy: {
95
+ create(options?: Record<string, unknown>): SloppyApp;
96
+ createBuilder(options?: Record<string, unknown>): SloppyBuilder;
97
+ };
98
+
99
+ export const Router: {
100
+ group(prefix: string): RouteGroup;
101
+ };
102
+
103
+ export const Results: {
104
+ ok<T = unknown>(value?: T, options?: Record<string, unknown>): ResultDescriptor<T>;
105
+ json<T = unknown>(value: T, options?: Record<string, unknown>): ResultDescriptor<T>;
106
+ text(value: string, options?: Record<string, unknown>): ResultDescriptor<string>;
107
+ html(value: string, options?: Record<string, unknown>): ResultDescriptor<string>;
108
+ bytes(value: Uint8Array | ArrayBuffer, options?: Record<string, unknown>): ResultDescriptor<Uint8Array | ArrayBuffer>;
109
+ created<T = unknown>(location: string, value?: T, options?: Record<string, unknown>): ResultDescriptor<T>;
110
+ created<T = unknown>(value?: T, options?: Record<string, unknown>): ResultDescriptor<T>;
111
+ accepted<T = unknown>(value?: T, options?: Record<string, unknown>): ResultDescriptor<T>;
112
+ noContent(options?: Record<string, unknown>): ResultDescriptor<void>;
113
+ notFound<T = unknown>(value?: T, options?: Record<string, unknown>): ResultDescriptor<T>;
114
+ badRequest<T = unknown>(value?: T, options?: Record<string, unknown>): ResultDescriptor<T>;
115
+ unauthorized<T = unknown>(value?: T, options?: Record<string, unknown>): ResultDescriptor<T>;
116
+ status<T = unknown>(statusCode: number, value?: T, options?: Record<string, unknown>): ResultDescriptor<T>;
117
+ problem(problemOrMessage: string | Record<string, unknown>, options?: Record<string, unknown>): ResultDescriptor<Record<string, unknown>>;
118
+ };
119
+
120
+ export interface SchemaValidation<T> {
121
+ ok: boolean;
122
+ value?: T;
123
+ issues?: Array<{ path: Array<string | number>; code: string; message: string }>;
124
+ }
125
+
126
+ export interface SchemaType<T = unknown> {
127
+ readonly kind: string;
128
+ readonly metadata: Record<string, unknown>;
129
+ validate(value: unknown): SchemaValidation<T>;
130
+ optional(): SchemaType<T | undefined>;
131
+ nullable(): SchemaType<T | null>;
132
+ default(value: T): SchemaType<T>;
133
+ min(value: number): SchemaType<T>;
134
+ max(value: number): SchemaType<T>;
135
+ email(): SchemaType<T>;
136
+ }
137
+
138
+ export const Schema: {
139
+ string(): SchemaType<string>;
140
+ number(): SchemaType<number>;
141
+ int(): SchemaType<number>;
142
+ integer(): SchemaType<number>;
143
+ boolean(): SchemaType<boolean>;
144
+ bool(): SchemaType<boolean>;
145
+ array<T>(item: SchemaType<T>): SchemaType<T[]>;
146
+ enum<T extends string | number | boolean | null>(values: readonly T[]): SchemaType<T>;
147
+ literal<T extends string | number | boolean | null>(value: T): SchemaType<T>;
148
+ object<T extends Record<string, SchemaType>>(shape: T): SchemaType<{ [K in keyof T]: T[K] extends SchemaType<infer V> ? V : never }>;
149
+ validate<T>(value: unknown, schema: SchemaType<T>): T;
150
+ isSchema(value: unknown): value is SchemaType;
151
+ };
152
+
153
+ export const schema: typeof Schema;
154
+
155
+ export const RequestId: {
156
+ defaults(options?: Record<string, unknown>): Middleware;
157
+ };
158
+
159
+ export const RequestLogging: {
160
+ defaults(options?: Record<string, unknown>): Middleware;
161
+ };
162
+
163
+ export const ProblemDetails: {
164
+ defaults(options?: Record<string, unknown>): Middleware;
165
+ };
166
+ export const Auth: Record<string, unknown>;
167
+ export const Config: Record<string, unknown>;
168
+ export const Health: Record<string, unknown>;
169
+ export const Metrics: Record<string, unknown>;
170
+ export const RateLimit: Record<string, unknown>;
171
+ export const Realtime: Record<string, unknown>;
172
+ export const Webhooks: Record<string, unknown>;
173
+ export const Testing: Record<string, unknown>;
174
+
175
+ export * from "./data";
176
+ export * from "./fs";
177
+ export * from "./os";
package/types/os.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ export const Environment: {
2
+ get(name: string, fallback?: string): string | undefined;
3
+ require(name: string): string;
4
+ };
5
+
6
+ export const System: {
7
+ platform(): string;
8
+ arch(): string;
9
+ cwd(): string;
10
+ };
11
+
12
+ export const Process: Record<string, unknown>;
13
+ export const Signals: Record<string, unknown>;
14
+ export class OsError extends Error {}
@@ -0,0 +1,8 @@
1
+ export interface SqliteProviderOptions {
2
+ database?: string;
3
+ readonly?: boolean;
4
+ migrations?: string;
5
+ [key: string]: unknown;
6
+ }
7
+
8
+ export function sqlite(name: string, options?: SqliteProviderOptions): any;
@@ -0,0 +1,244 @@
1
+ declare module "sloppy" {
2
+ export type Awaitable<T> = T | Promise<T>;
3
+ export type JsonPrimitive = string | number | boolean | null;
4
+ export type JsonValue = JsonPrimitive | JsonValue[] | { [key: string]: JsonValue };
5
+
6
+ export type Route<T = string> = T;
7
+ export type Query<T = string> = T;
8
+ export type Header<T = string> = T;
9
+ export type Body<T = unknown> = T;
10
+ export type Service<T = unknown> = T;
11
+
12
+ export interface SloppyRequest {
13
+ method: string;
14
+ path: string;
15
+ headers?: Record<string, string>;
16
+ query?: Record<string, string | string[]>;
17
+ body?: unknown;
18
+ }
19
+
20
+ export interface SchemaValidation<T> {
21
+ ok: boolean;
22
+ value?: T;
23
+ issues?: Array<{ path: Array<string | number>; code: string; message: string }>;
24
+ }
25
+
26
+ export interface SchemaType<T = unknown> {
27
+ readonly kind: string;
28
+ readonly metadata: Record<string, unknown>;
29
+ validate(value: unknown): SchemaValidation<T>;
30
+ optional(): SchemaType<T | undefined>;
31
+ nullable(): SchemaType<T | null>;
32
+ default(value: T): SchemaType<T>;
33
+ min(value: number): SchemaType<T>;
34
+ max(value: number): SchemaType<T>;
35
+ email(): SchemaType<T>;
36
+ }
37
+
38
+ export interface RequestBody<T = unknown> {
39
+ value?: T;
40
+ text(): Promise<string>;
41
+ json<TJson = unknown>(): Promise<TJson>;
42
+ validate<TValue>(schema: SchemaType<TValue>): Promise<TValue>;
43
+ }
44
+
45
+ export interface RequestContext {
46
+ request: SloppyRequest;
47
+ route: Record<string, string>;
48
+ routeName?: string;
49
+ requestId?: string;
50
+ services?: Record<string, unknown>;
51
+ body: RequestBody;
52
+ log?: {
53
+ debug(message: string, fields?: Record<string, unknown>): void;
54
+ info(message: string, fields?: Record<string, unknown>): void;
55
+ warn(message: string, fields?: Record<string, unknown>): void;
56
+ error(message: string, fields?: Record<string, unknown>): void;
57
+ };
58
+ }
59
+
60
+ export interface ResultDescriptor<TBody = unknown> {
61
+ readonly __sloppyResult?: true;
62
+ readonly kind?: string;
63
+ readonly status?: number;
64
+ readonly headers?: Record<string, string>;
65
+ readonly contentType?: string;
66
+ readonly body?: TBody;
67
+ }
68
+
69
+ export type Handler<T = unknown> = (ctx: RequestContext) => Awaitable<T | ResultDescriptor<T>>;
70
+ export type Middleware = (ctx: RequestContext, next: () => Awaitable<ResultDescriptor>) => Awaitable<ResultDescriptor>;
71
+
72
+ export interface RouteBuilder {
73
+ withName(name: string): RouteBuilder;
74
+ withTags(...tags: string[]): RouteBuilder;
75
+ produces(status: number, contentType?: string): RouteBuilder;
76
+ accepts(schema: SchemaType, options?: Record<string, unknown>): RouteBuilder;
77
+ returns(schema: SchemaType, options?: Record<string, unknown>): RouteBuilder;
78
+ }
79
+
80
+ export interface RouteGroup {
81
+ use(middleware: Middleware): RouteGroup;
82
+ get(path: string, handler: Handler): RouteBuilder;
83
+ post(path: string, handler: Handler): RouteBuilder;
84
+ put(path: string, handler: Handler): RouteBuilder;
85
+ patch(path: string, handler: Handler): RouteBuilder;
86
+ delete(path: string, handler: Handler): RouteBuilder;
87
+ group(prefix: string): RouteGroup;
88
+ }
89
+
90
+ export interface SloppyApp extends RouteGroup {
91
+ useCors(options?: Record<string, unknown>): SloppyApp;
92
+ useErrors(options?: Record<string, unknown>): SloppyApp;
93
+ useStaticFiles(options: Record<string, unknown>): SloppyApp;
94
+ useModule(module: (app: SloppyApp) => void): SloppyApp;
95
+ provider<T = unknown>(name: string): T;
96
+ mapController(prefix: string, controller: new (...args: any[]) => unknown, configure: (mapper: any) => void): SloppyApp;
97
+ }
98
+
99
+ export interface ServiceBuilder {
100
+ addSingleton<T>(name: string, factory: () => T): ServiceBuilder;
101
+ addScoped<T>(name: string, factory: () => T): ServiceBuilder;
102
+ addTransient<T>(name: string, factory: () => T): ServiceBuilder;
103
+ }
104
+
105
+ export interface SloppyBuilder {
106
+ services: ServiceBuilder;
107
+ build(): SloppyApp;
108
+ }
109
+
110
+ export const Sloppy: {
111
+ create(options?: Record<string, unknown>): SloppyApp;
112
+ createBuilder(options?: Record<string, unknown>): SloppyBuilder;
113
+ };
114
+
115
+ export const Router: {
116
+ group(prefix: string): RouteGroup;
117
+ };
118
+
119
+ export const Results: {
120
+ ok<T = unknown>(value?: T, options?: Record<string, unknown>): ResultDescriptor<T>;
121
+ json<T = unknown>(value: T, options?: Record<string, unknown>): ResultDescriptor<T>;
122
+ text(value: string, options?: Record<string, unknown>): ResultDescriptor<string>;
123
+ html(value: string, options?: Record<string, unknown>): ResultDescriptor<string>;
124
+ bytes(value: Uint8Array | ArrayBuffer, options?: Record<string, unknown>): ResultDescriptor<Uint8Array | ArrayBuffer>;
125
+ created<T = unknown>(location: string, value?: T, options?: Record<string, unknown>): ResultDescriptor<T>;
126
+ created<T = unknown>(value?: T, options?: Record<string, unknown>): ResultDescriptor<T>;
127
+ accepted<T = unknown>(value?: T, options?: Record<string, unknown>): ResultDescriptor<T>;
128
+ noContent(options?: Record<string, unknown>): ResultDescriptor<void>;
129
+ notFound<T = unknown>(value?: T, options?: Record<string, unknown>): ResultDescriptor<T>;
130
+ badRequest<T = unknown>(value?: T, options?: Record<string, unknown>): ResultDescriptor<T>;
131
+ unauthorized<T = unknown>(value?: T, options?: Record<string, unknown>): ResultDescriptor<T>;
132
+ status<T = unknown>(statusCode: number, value?: T, options?: Record<string, unknown>): ResultDescriptor<T>;
133
+ problem(problemOrMessage: string | Record<string, unknown>, options?: Record<string, unknown>): ResultDescriptor<Record<string, unknown>>;
134
+ };
135
+
136
+ export const Schema: {
137
+ string(): SchemaType<string>;
138
+ number(): SchemaType<number>;
139
+ int(): SchemaType<number>;
140
+ integer(): SchemaType<number>;
141
+ boolean(): SchemaType<boolean>;
142
+ bool(): SchemaType<boolean>;
143
+ array<T>(item: SchemaType<T>): SchemaType<T[]>;
144
+ enum<T extends string | number | boolean | null>(values: readonly T[]): SchemaType<T>;
145
+ literal<T extends string | number | boolean | null>(value: T): SchemaType<T>;
146
+ object<T extends Record<string, SchemaType>>(shape: T): SchemaType<{ [K in keyof T]: T[K] extends SchemaType<infer V> ? V : never }>;
147
+ validate<T>(value: unknown, schema: SchemaType<T>): T;
148
+ isSchema(value: unknown): value is SchemaType;
149
+ };
150
+
151
+ export const schema: typeof Schema;
152
+ export const RequestId: { defaults(options?: Record<string, unknown>): Middleware };
153
+ export const RequestLogging: { defaults(options?: Record<string, unknown>): Middleware };
154
+ export const ProblemDetails: { defaults(options?: Record<string, unknown>): Middleware };
155
+ export const Auth: Record<string, unknown>;
156
+ export const Config: Record<string, unknown>;
157
+ export const Health: Record<string, unknown>;
158
+ export const Metrics: Record<string, unknown>;
159
+ export const RateLimit: Record<string, unknown>;
160
+ export const Realtime: Record<string, unknown>;
161
+ export const Webhooks: Record<string, unknown>;
162
+ export const Testing: Record<string, unknown>;
163
+ }
164
+
165
+ declare module "sloppy/data" {
166
+ export interface SqlFragment {
167
+ readonly __sloppySql?: true;
168
+ }
169
+
170
+ export interface MigrationOptions {
171
+ provider?: string;
172
+ path?: string;
173
+ [key: string]: unknown;
174
+ }
175
+
176
+ export const sql: {
177
+ sqlite(strings: TemplateStringsArray, ...values: unknown[]): SqlFragment;
178
+ postgres(strings: TemplateStringsArray, ...values: unknown[]): SqlFragment;
179
+ sqlserver(strings: TemplateStringsArray, ...values: unknown[]): SqlFragment;
180
+ };
181
+
182
+ export const data: Record<string, unknown>;
183
+ export const Migrations: {
184
+ apply(database: unknown, options?: MigrationOptions): Promise<unknown>;
185
+ run(options?: MigrationOptions): Promise<unknown>;
186
+ status(options?: MigrationOptions): Promise<unknown>;
187
+ };
188
+ export const ProviderHealth: Record<string, unknown>;
189
+ export function isRealDataProvider(value: unknown): boolean;
190
+ }
191
+
192
+ declare module "sloppy/fs" {
193
+ export const File: {
194
+ readText(path: string, options?: Record<string, unknown>): Promise<string>;
195
+ writeText(path: string, value: string, options?: Record<string, unknown>): Promise<void>;
196
+ readBytes(path: string, options?: Record<string, unknown>): Promise<Uint8Array>;
197
+ writeBytes(path: string, value: Uint8Array | ArrayBuffer, options?: Record<string, unknown>): Promise<void>;
198
+ exists(path: string): Promise<boolean>;
199
+ };
200
+
201
+ export const Directory: {
202
+ create(path: string, options?: Record<string, unknown>): Promise<void>;
203
+ exists(path: string): Promise<boolean>;
204
+ entries(path: string, options?: Record<string, unknown>): Promise<string[]>;
205
+ };
206
+
207
+ export const Path: {
208
+ join(...parts: string[]): string;
209
+ dirname(path: string): string;
210
+ basename(path: string): string;
211
+ extname(path: string): string;
212
+ };
213
+
214
+ export const FileHandle: Record<string, unknown>;
215
+ export const FileWatcher: Record<string, unknown>;
216
+ }
217
+
218
+ declare module "sloppy/os" {
219
+ export const Environment: {
220
+ get(name: string, fallback?: string): string | undefined;
221
+ require(name: string): string;
222
+ };
223
+
224
+ export const System: {
225
+ platform(): string;
226
+ arch(): string;
227
+ cwd(): string;
228
+ };
229
+
230
+ export const Process: Record<string, unknown>;
231
+ export const Signals: Record<string, unknown>;
232
+ export class OsError extends Error {}
233
+ }
234
+
235
+ declare module "sloppy/providers/sqlite" {
236
+ export interface SqliteProviderOptions {
237
+ database?: string;
238
+ readonly?: boolean;
239
+ migrations?: string;
240
+ [key: string]: unknown;
241
+ }
242
+
243
+ export function sqlite(name: string, options?: SqliteProviderOptions): any;
244
+ }