@zylaris/server 1.0.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.
@@ -0,0 +1,22 @@
1
+ import type { ZodType } from 'zod';
2
+ import type { ActionConfig, ActionContext, ActionResult, Middleware, RateLimitConfig, ActionHandler } from './types.js';
3
+ export declare class ActionBuilder<I, O> {
4
+ private config;
5
+ constructor(config?: ActionConfig<I, O>);
6
+ input<T extends ZodType>(schema: T): ActionBuilder<ReturnType<T['parse']>, O>;
7
+ output<T extends ZodType>(schema: T): ActionBuilder<I, ReturnType<T['parse']>>;
8
+ use(middleware: Middleware): this;
9
+ rateLimit(config: RateLimitConfig): this;
10
+ run(handler: ActionHandler<I, O>): Action<I, O>;
11
+ }
12
+ export declare class Action<I, O> {
13
+ private config;
14
+ private handler;
15
+ id: string;
16
+ constructor(config: ActionConfig<I, O>, handler: ActionHandler<I, O>);
17
+ execute(input: unknown, ctx: ActionContext): Promise<ActionResult<O>>;
18
+ }
19
+ export declare function action(): ActionBuilder<unknown, unknown>;
20
+ export declare function requireAuth(): Middleware;
21
+ export declare function requireRole(_roles: string[]): Middleware;
22
+ //# sourceMappingURL=action.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../src/action.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AACnC,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,YAAY,EAEZ,UAAU,EACV,eAAe,EACf,aAAa,EACd,MAAM,YAAY,CAAC;AAKpB,qBAAa,aAAa,CAAC,CAAC,EAAE,CAAC;IAC7B,OAAO,CAAC,MAAM,CAAqB;gBAEvB,MAAM,GAAE,YAAY,CAAC,CAAC,EAAE,CAAC,CAAM;IAI3C,KAAK,CAAC,CAAC,SAAS,OAAO,EAAE,MAAM,EAAE,CAAC,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAI7E,MAAM,CAAC,CAAC,SAAS,OAAO,EAAE,MAAM,EAAE,CAAC,GAAG,aAAa,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAI9E,GAAG,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI;IAKjC,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI;IAKxC,GAAG,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC;CAGhD;AAED,qBAAa,MAAM,CAAC,CAAC,EAAE,CAAC;IAIpB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,OAAO;IAJjB,EAAE,EAAE,MAAM,CAAC;gBAGD,MAAM,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,OAAO,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC;IAKhC,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;CAmE5E;AAmDD,wBAAgB,MAAM,IAAI,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,CAExD;AAGD,wBAAgB,WAAW,IAAI,UAAU,CAUxC;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAWxD"}
package/dist/action.js ADDED
@@ -0,0 +1,165 @@
1
+ // Rate limiting store (in production, use Redis)
2
+ const rateLimitStore = new Map();
3
+ export class ActionBuilder {
4
+ config;
5
+ constructor(config = {}) {
6
+ this.config = config;
7
+ }
8
+ input(schema) {
9
+ return new ActionBuilder({ ...this.config, input: schema });
10
+ }
11
+ output(schema) {
12
+ return new ActionBuilder({ ...this.config, output: schema });
13
+ }
14
+ use(middleware) {
15
+ this.config.middleware = [...(this.config.middleware || []), middleware];
16
+ return this;
17
+ }
18
+ rateLimit(config) {
19
+ this.config.rateLimit = config;
20
+ return this;
21
+ }
22
+ run(handler) {
23
+ return new Action(this.config, handler);
24
+ }
25
+ }
26
+ export class Action {
27
+ config;
28
+ handler;
29
+ id;
30
+ constructor(config, handler) {
31
+ this.config = config;
32
+ this.handler = handler;
33
+ this.id = generateActionId();
34
+ }
35
+ async execute(input, ctx) {
36
+ try {
37
+ // Check rate limit
38
+ if (this.config.rateLimit) {
39
+ const rateLimitError = await checkRateLimit(this.config.rateLimit, ctx);
40
+ if (rateLimitError) {
41
+ return { success: false, error: rateLimitError };
42
+ }
43
+ }
44
+ // Run middleware
45
+ if (this.config.middleware) {
46
+ for (const middleware of this.config.middleware) {
47
+ const result = await middleware(ctx);
48
+ if (result) {
49
+ return { success: false, error: result };
50
+ }
51
+ }
52
+ }
53
+ // Validate input
54
+ let validatedInput;
55
+ if (this.config.input) {
56
+ const result = this.config.input.safeParse(input);
57
+ if (!result.success) {
58
+ return {
59
+ success: false,
60
+ error: {
61
+ code: 'VALIDATION_ERROR',
62
+ message: 'Input validation failed',
63
+ fieldErrors: result.error.flatten().fieldErrors,
64
+ },
65
+ };
66
+ }
67
+ validatedInput = result.data;
68
+ }
69
+ else {
70
+ validatedInput = input;
71
+ }
72
+ // Execute handler
73
+ const output = await this.handler(validatedInput, ctx);
74
+ // Validate output
75
+ if (this.config.output) {
76
+ const result = this.config.output.safeParse(output);
77
+ if (!result.success) {
78
+ return {
79
+ success: false,
80
+ error: {
81
+ code: 'OUTPUT_VALIDATION_ERROR',
82
+ message: 'Output validation failed',
83
+ },
84
+ };
85
+ }
86
+ }
87
+ return { success: true, data: output };
88
+ }
89
+ catch (error) {
90
+ return {
91
+ success: false,
92
+ error: {
93
+ code: 'INTERNAL_ERROR',
94
+ message: error instanceof Error ? error.message : 'Unknown error',
95
+ },
96
+ };
97
+ }
98
+ }
99
+ }
100
+ function generateActionId() {
101
+ return `action_${Math.random().toString(36).substring(2, 11)}`;
102
+ }
103
+ async function checkRateLimit(config, ctx) {
104
+ const key = config.key ? config.key(ctx) : ctx.ip;
105
+ const windowMs = parseTimeWindow(config.window);
106
+ const now = Date.now();
107
+ const record = rateLimitStore.get(key);
108
+ if (!record || now > record.resetAt) {
109
+ rateLimitStore.set(key, {
110
+ count: 1,
111
+ resetAt: now + windowMs,
112
+ });
113
+ return null;
114
+ }
115
+ if (record.count >= config.max) {
116
+ return {
117
+ code: 'RATE_LIMIT_EXCEEDED',
118
+ message: `Rate limit exceeded. Try again in ${Math.ceil((record.resetAt - now) / 1000)}s`,
119
+ };
120
+ }
121
+ record.count++;
122
+ return null;
123
+ }
124
+ function parseTimeWindow(window) {
125
+ const match = window.match(/^(\d+)([smhd])$/);
126
+ if (!match)
127
+ return 60000; // Default 1 minute
128
+ const [, num, unit] = match;
129
+ const multiplier = {
130
+ s: 1000,
131
+ m: 60000,
132
+ h: 3600000,
133
+ d: 86400000,
134
+ }[unit] || 60000;
135
+ return parseInt(num) * multiplier;
136
+ }
137
+ // Factory function
138
+ export function action() {
139
+ return new ActionBuilder();
140
+ }
141
+ // Built-in middleware
142
+ export function requireAuth() {
143
+ return (ctx) => {
144
+ if (!ctx.user) {
145
+ return {
146
+ code: 'UNAUTHORIZED',
147
+ message: 'Authentication required',
148
+ };
149
+ }
150
+ return null;
151
+ };
152
+ }
153
+ export function requireRole(_roles) {
154
+ return (ctx) => {
155
+ if (!ctx.user) {
156
+ return {
157
+ code: 'UNAUTHORIZED',
158
+ message: 'Authentication required',
159
+ };
160
+ }
161
+ // In real implementation, check user roles
162
+ return null;
163
+ };
164
+ }
165
+ //# sourceMappingURL=action.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action.js","sourceRoot":"","sources":["../src/action.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=action.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action.test.d.ts","sourceRoot":"","sources":["../src/action.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,87 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { action, ActionBuilder, Action, requireAuth, requireRole } from './action.js';
3
+ describe('ActionBuilder', () => {
4
+ it('should create action builder', () => {
5
+ const builder = action();
6
+ expect(builder).toBeInstanceOf(ActionBuilder);
7
+ });
8
+ it('should build action with run', async () => {
9
+ const myAction = action().run(async (input) => {
10
+ const { name } = input;
11
+ return { message: `Hello ${name}` };
12
+ });
13
+ expect(myAction).toBeInstanceOf(Action);
14
+ });
15
+ });
16
+ describe('Action', () => {
17
+ it('should execute action successfully', async () => {
18
+ const myAction = action().run(async (input) => {
19
+ const { value } = input;
20
+ return { result: value * 2 };
21
+ });
22
+ const result = await myAction.execute({ value: 5 }, {
23
+ request: new Request('http://localhost'),
24
+ headers: new Headers(),
25
+ cookies: new Map(),
26
+ ip: '127.0.0.1',
27
+ userAgent: 'test'
28
+ });
29
+ expect(result.success).toBe(true);
30
+ expect(result.data).toEqual({ result: 10 });
31
+ });
32
+ it('should execute with null input', async () => {
33
+ const myAction = action().run(async () => {
34
+ return { success: true };
35
+ });
36
+ const result = await myAction.execute(null, {
37
+ request: new Request('http://localhost'),
38
+ headers: new Headers(),
39
+ cookies: new Map(),
40
+ ip: '127.0.0.1',
41
+ userAgent: 'test'
42
+ });
43
+ // Action without input validation should succeed
44
+ expect(result.success).toBe(true);
45
+ });
46
+ });
47
+ describe('requireAuth', () => {
48
+ it('should return error when no user', async () => {
49
+ const middleware = requireAuth();
50
+ const result = await middleware({
51
+ request: new Request('http://localhost'),
52
+ headers: new Headers(),
53
+ cookies: new Map(),
54
+ ip: '127.0.0.1',
55
+ userAgent: 'test'
56
+ });
57
+ expect(result).not.toBeNull();
58
+ expect(result && result.code).toBe('UNAUTHORIZED');
59
+ });
60
+ it('should return null when user exists', async () => {
61
+ const middleware = requireAuth();
62
+ const result = await middleware({
63
+ request: new Request('http://localhost'),
64
+ headers: new Headers(),
65
+ cookies: new Map(),
66
+ ip: '127.0.0.1',
67
+ userAgent: 'test',
68
+ user: { id: '1', email: 'test@test.com' }
69
+ });
70
+ expect(result).toBeNull();
71
+ });
72
+ });
73
+ describe('requireRole', () => {
74
+ it('should return error when no user', async () => {
75
+ const middleware = requireRole(['admin']);
76
+ const result = await middleware({
77
+ request: new Request('http://localhost'),
78
+ headers: new Headers(),
79
+ cookies: new Map(),
80
+ ip: '127.0.0.1',
81
+ userAgent: 'test'
82
+ });
83
+ expect(result).not.toBeNull();
84
+ expect(result && result.code).toBe('UNAUTHORIZED');
85
+ });
86
+ });
87
+ //# sourceMappingURL=action.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action.test.js","sourceRoot":"","sources":["../src/action.test.ts"],"names":[],"mappings":"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"}
package/dist/api.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ import type { ZodType } from 'zod';
2
+ import type { APIConfig, APIHandler, Middleware } from './types.js';
3
+ export declare class APIBuilder<I, O> {
4
+ private config;
5
+ constructor(config?: APIConfig<I, O>);
6
+ query<T extends ZodType>(schema: T): APIBuilder<ReturnType<T['parse']>, O>;
7
+ body<T extends ZodType>(schema: T): APIBuilder<ReturnType<T['parse']>, O>;
8
+ output<T extends ZodType>(schema: T): APIBuilder<I, ReturnType<T['parse']>>;
9
+ use(middleware: Middleware): this;
10
+ handler(fn: APIHandler<I, O>): (request: Request) => Promise<Response>;
11
+ }
12
+ export declare function api(): APIBuilder<unknown, unknown>;
13
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AACnC,OAAO,KAAK,EACV,SAAS,EACT,UAAU,EAEV,UAAU,EACX,MAAM,YAAY,CAAC;AAEpB,qBAAa,UAAU,CAAC,CAAC,EAAE,CAAC;IAC1B,OAAO,CAAC,MAAM,CAAkB;gBAEpB,MAAM,GAAE,SAAS,CAAC,CAAC,EAAE,CAAC,CAAM;IAIxC,KAAK,CAAC,CAAC,SAAS,OAAO,EAAE,MAAM,EAAE,CAAC,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAI1E,IAAI,CAAC,CAAC,SAAS,OAAO,EAAE,MAAM,EAAE,CAAC,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAIzE,MAAM,CAAC,CAAC,SAAS,OAAO,EAAE,MAAM,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAI3E,GAAG,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI;IAKjC,OAAO,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC;CA8EvE;AA8BD,wBAAgB,GAAG,IAAI,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAElD"}
package/dist/api.js ADDED
@@ -0,0 +1,109 @@
1
+ export class APIBuilder {
2
+ config;
3
+ constructor(config = {}) {
4
+ this.config = config;
5
+ }
6
+ query(schema) {
7
+ return new APIBuilder({ ...this.config, query: schema });
8
+ }
9
+ body(schema) {
10
+ return new APIBuilder({ ...this.config, body: schema });
11
+ }
12
+ output(schema) {
13
+ return new APIBuilder({ ...this.config, output: schema });
14
+ }
15
+ use(middleware) {
16
+ this.config.middleware = [...(this.config.middleware || []), middleware];
17
+ return this;
18
+ }
19
+ handler(fn) {
20
+ return async (request) => {
21
+ try {
22
+ const ctx = await createContext(request);
23
+ // Run middleware
24
+ if (this.config.middleware) {
25
+ for (const middleware of this.config.middleware) {
26
+ const result = await middleware(ctx);
27
+ if (result) {
28
+ return Response.json({ success: false, error: result }, { status: 400 });
29
+ }
30
+ }
31
+ }
32
+ // Parse input
33
+ let input = {};
34
+ if (this.config.query) {
35
+ const url = new URL(request.url);
36
+ const query = Object.fromEntries(url.searchParams);
37
+ const result = this.config.query.safeParse(query);
38
+ if (!result.success) {
39
+ return Response.json({
40
+ success: false,
41
+ error: {
42
+ code: 'VALIDATION_ERROR',
43
+ message: 'Query validation failed',
44
+ fieldErrors: result.error.flatten().fieldErrors,
45
+ },
46
+ }, { status: 400 });
47
+ }
48
+ input = { ...input, ...result.data };
49
+ }
50
+ if (this.config.body && request.body) {
51
+ const body = await request.json();
52
+ const result = this.config.body.safeParse(body);
53
+ if (!result.success) {
54
+ return Response.json({
55
+ success: false,
56
+ error: {
57
+ code: 'VALIDATION_ERROR',
58
+ message: 'Body validation failed',
59
+ fieldErrors: result.error.flatten().fieldErrors,
60
+ },
61
+ }, { status: 400 });
62
+ }
63
+ input = { ...input, ...result.data };
64
+ }
65
+ // Execute handler
66
+ const response = await fn(input, ctx);
67
+ return response;
68
+ }
69
+ catch (error) {
70
+ console.error('API Error:', error);
71
+ return Response.json({
72
+ success: false,
73
+ error: {
74
+ code: 'INTERNAL_ERROR',
75
+ message: error instanceof Error ? error.message : 'Unknown error',
76
+ },
77
+ }, { status: 500 });
78
+ }
79
+ };
80
+ }
81
+ }
82
+ async function createContext(request) {
83
+ const headers = request.headers;
84
+ const cookies = parseCookies(headers.get('cookie') || '');
85
+ return {
86
+ request,
87
+ headers,
88
+ cookies,
89
+ ip: headers.get('x-forwarded-for') || 'unknown',
90
+ userAgent: headers.get('user-agent') || 'unknown',
91
+ };
92
+ }
93
+ function parseCookies(cookieHeader) {
94
+ const cookies = new Map();
95
+ if (!cookieHeader)
96
+ return cookies;
97
+ cookieHeader.split(';').forEach((cookie) => {
98
+ const [name, value] = cookie.trim().split('=');
99
+ if (name && value) {
100
+ cookies.set(name, decodeURIComponent(value));
101
+ }
102
+ });
103
+ return cookies;
104
+ }
105
+ // Factory function
106
+ export function api() {
107
+ return new APIBuilder();
108
+ }
109
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { Action, ActionBuilder, action, requireAuth, requireRole } from './action.js';
2
+ export { APIBuilder, api } from './api.js';
3
+ export type { ActionContext, User, Session, ActionConfig, ActionResult, ActionError, Middleware, RateLimitConfig, ActionHandler, APIConfig, APIHandler, } from './types.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtF,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE3C,YAAY,EACV,aAAa,EACb,IAAI,EACJ,OAAO,EACP,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,UAAU,EACV,eAAe,EACf,aAAa,EACb,SAAS,EACT,UAAU,GACX,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ // Zylaris Server - Server-side utilities
2
+ export { Action, ActionBuilder, action, requireAuth, requireRole } from './action.js';
3
+ export { APIBuilder, api } from './api.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yCAAyC;AAEzC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtF,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,53 @@
1
+ import type { ZodType } from 'zod';
2
+ export interface ActionContext {
3
+ request: Request;
4
+ headers: Headers;
5
+ cookies: Map<string, string>;
6
+ user?: User;
7
+ session?: Session;
8
+ ip: string;
9
+ userAgent: string;
10
+ }
11
+ export interface User {
12
+ id: string;
13
+ email: string;
14
+ name?: string;
15
+ [key: string]: unknown;
16
+ }
17
+ export interface Session {
18
+ id: string;
19
+ userId: string;
20
+ expiresAt: Date;
21
+ [key: string]: unknown;
22
+ }
23
+ export interface ActionConfig<I, O> {
24
+ input?: ZodType<I>;
25
+ output?: ZodType<O>;
26
+ middleware?: Middleware[];
27
+ rateLimit?: RateLimitConfig;
28
+ }
29
+ export interface ActionResult<O> {
30
+ success: boolean;
31
+ data?: O;
32
+ error?: ActionError;
33
+ }
34
+ export interface ActionError {
35
+ code: string;
36
+ message: string;
37
+ fieldErrors?: Record<string, string[]>;
38
+ }
39
+ export type Middleware = (ctx: ActionContext) => Promise<ActionError | null | undefined> | ActionError | null | undefined;
40
+ export interface RateLimitConfig {
41
+ max: number;
42
+ window: string;
43
+ key?: (ctx: ActionContext) => string;
44
+ }
45
+ export type ActionHandler<I, O> = (input: I, ctx: ActionContext) => Promise<O> | O;
46
+ export interface APIConfig<I, O> {
47
+ query?: ZodType<I>;
48
+ body?: ZodType<I>;
49
+ output?: ZodType<O>;
50
+ middleware?: Middleware[];
51
+ }
52
+ export type APIHandler<_I, _O> = (input: _I, ctx: ActionContext) => Promise<Response> | Response;
53
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAEnC,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;IAChB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,EAAE,CAAC;IAChC,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACpB,UAAU,CAAC,EAAE,UAAU,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,eAAe,CAAC;CAC7B;AAED,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACxC;AAED,MAAM,MAAM,UAAU,GAAG,CACvB,GAAG,EAAE,aAAa,KACf,OAAO,CAAC,WAAW,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,WAAW,GAAG,IAAI,GAAG,SAAS,CAAC;AAE9E,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,MAAM,CAAC;CACtC;AAED,MAAM,MAAM,aAAa,CAAC,CAAC,EAAE,CAAC,IAAI,CAChC,KAAK,EAAE,CAAC,EACR,GAAG,EAAE,aAAa,KACf,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AAGpB,MAAM,WAAW,SAAS,CAAC,CAAC,EAAE,CAAC;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACpB,UAAU,CAAC,EAAE,UAAU,EAAE,CAAC;CAC3B;AAED,MAAM,MAAM,UAAU,CAAC,EAAE,EAAE,EAAE,IAAI,CAC/B,KAAK,EAAE,EAAE,EACT,GAAG,EAAE,aAAa,KACf,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@zylaris/server",
3
+ "version": "1.0.0",
4
+ "description": "Server-side utilities for Zylaris",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsc",
20
+ "dev": "tsc --watch",
21
+ "test": "vitest run --passWithNoTests",
22
+ "typecheck": "tsc --noEmit",
23
+ "clean": "rm -rf dist"
24
+ },
25
+ "dependencies": {
26
+ "@zylaris/reactivity": "workspace:*",
27
+ "zod": "^3.22.4"
28
+ },
29
+ "devDependencies": {
30
+ "@types/node": "^20.0.0",
31
+ "typescript": "^5.3.3",
32
+ "vitest": "^1.2.0"
33
+ },
34
+ "keywords": [
35
+ "server",
36
+ "actions",
37
+ "api",
38
+ "zylaris"
39
+ ],
40
+ "license": "MIT"
41
+ }