alepha 0.20.3 → 0.20.4
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/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/files/index.d.ts.map +1 -1
- package/dist/api/jobs/index.d.ts +14 -14
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/keys/index.d.ts +4 -4
- package/dist/api/organizations/index.d.ts.map +1 -1
- package/dist/api/parameters/index.d.ts +8 -3
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/parameters/index.js +20 -4
- package/dist/api/parameters/index.js.map +1 -1
- package/dist/api/payments/index.d.ts.map +1 -1
- package/dist/api/users/index.browser.js +6 -0
- package/dist/api/users/index.browser.js.map +1 -1
- package/dist/api/users/index.d.ts +5037 -139
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +58 -10
- package/dist/api/users/index.js.map +1 -1
- package/dist/bucket/index.d.ts +77 -107
- package/dist/bucket/index.d.ts.map +1 -1
- package/dist/bucket/index.js +148 -4
- package/dist/bucket/index.js.map +1 -1
- package/dist/bucket/index.workerd.js +7 -1
- package/dist/bucket/index.workerd.js.map +1 -1
- package/dist/cache/core/index.d.ts +26 -0
- package/dist/cache/core/index.d.ts.map +1 -1
- package/dist/cache/core/index.js +11 -1
- package/dist/cache/core/index.js.map +1 -1
- package/dist/cache/core/index.workerd.js +11 -1
- package/dist/cache/core/index.workerd.js.map +1 -1
- package/dist/cli/config/index.d.ts +7 -5
- package/dist/cli/config/index.d.ts.map +1 -1
- package/dist/cli/config/index.js +2 -3
- package/dist/cli/config/index.js.map +1 -1
- package/dist/cli/core/index.d.ts +420 -13
- package/dist/cli/core/index.d.ts.map +1 -1
- package/dist/cli/core/index.js +22 -511
- package/dist/cli/core/index.js.map +1 -1
- package/dist/cli/devtools/index.d.ts +4 -8
- package/dist/cli/devtools/index.d.ts.map +1 -1
- package/dist/cli/devtools/index.js +13 -15
- package/dist/cli/devtools/index.js.map +1 -1
- package/dist/cli/platform/index.d.ts +10 -13
- package/dist/cli/platform/index.d.ts.map +1 -1
- package/dist/cli/platform/index.js +18 -15
- package/dist/cli/platform/index.js.map +1 -1
- package/dist/cli/vendor/index.d.ts +10 -13
- package/dist/cli/vendor/index.d.ts.map +1 -1
- package/dist/cli/vendor/index.js +16 -13
- package/dist/cli/vendor/index.js.map +1 -1
- package/dist/core/index.browser.js +27 -3
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +6 -3
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +27 -3
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +27 -3
- package/dist/core/index.native.js.map +1 -1
- package/dist/core/index.workerd.js +27 -3
- package/dist/core/index.workerd.js.map +1 -1
- package/dist/datetime/index.d.ts +69 -10
- package/dist/datetime/index.d.ts.map +1 -1
- package/dist/datetime/index.js +135 -13
- package/dist/datetime/index.js.map +1 -1
- package/dist/email/smtp/index.js +10636 -2
- package/dist/email/smtp/index.js.map +1 -1
- package/dist/fake/index.d.ts +8085 -4
- package/dist/fake/index.d.ts.map +1 -1
- package/dist/fake/index.js +33554 -3
- package/dist/fake/index.js.map +1 -1
- package/dist/lock/core/index.d.ts +30 -2
- package/dist/lock/core/index.d.ts.map +1 -1
- package/dist/lock/core/index.js +35 -12
- package/dist/lock/core/index.js.map +1 -1
- package/dist/mcp/index.d.ts +238 -31
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +198 -71
- package/dist/mcp/index.js.map +1 -1
- package/dist/orm/core/index.browser.js +1 -1
- package/dist/orm/core/index.browser.js.map +1 -1
- package/dist/orm/core/index.bun.js +4 -3
- package/dist/orm/core/index.bun.js.map +1 -1
- package/dist/orm/core/index.d.ts +4877 -9
- package/dist/orm/core/index.d.ts.map +1 -1
- package/dist/orm/core/index.js +4 -3
- package/dist/orm/core/index.js.map +1 -1
- package/dist/orm/postgres/index.d.ts +608 -1
- package/dist/orm/postgres/index.d.ts.map +1 -1
- package/dist/react/core/index.d.ts +102 -1
- package/dist/react/core/index.d.ts.map +1 -1
- package/dist/react/core/index.js +65 -1
- package/dist/react/core/index.js.map +1 -1
- package/dist/react/form/index.d.ts +6 -0
- package/dist/react/form/index.d.ts.map +1 -1
- package/dist/react/form/index.js +7 -7
- package/dist/react/form/index.js.map +1 -1
- package/dist/react/i18n/index.d.ts +7 -1
- package/dist/react/i18n/index.d.ts.map +1 -1
- package/dist/react/i18n/index.js +6 -0
- package/dist/react/i18n/index.js.map +1 -1
- package/dist/react/router/index.browser.js +20 -2
- package/dist/react/router/index.browser.js.map +1 -1
- package/dist/react/router/index.d.ts +36 -4
- package/dist/react/router/index.d.ts.map +1 -1
- package/dist/react/router/index.js +20 -2
- package/dist/react/router/index.js.map +1 -1
- package/dist/react/testing/chunk-6Ep1yQYe.js +16 -0
- package/dist/react/testing/index.d.ts +411 -1
- package/dist/react/testing/index.d.ts.map +1 -1
- package/dist/react/testing/index.js +12293 -13
- package/dist/react/testing/index.js.map +1 -1
- package/dist/react/ui/index.d.ts +195 -1
- package/dist/react/ui/index.d.ts.map +1 -1
- package/dist/react/ui/index.js +61 -1
- package/dist/react/ui/index.js.map +1 -1
- package/dist/scheduler/index.d.ts +84 -3
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/scheduler/index.js +390 -1
- package/dist/scheduler/index.js.map +1 -1
- package/dist/scheduler/index.workerd.js +390 -1
- package/dist/scheduler/index.workerd.js.map +1 -1
- package/dist/security/index.d.ts +325 -2
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +1361 -2
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +1054 -1
- package/dist/server/auth/index.d.ts.map +1 -1
- package/dist/server/auth/index.js +1223 -1
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/core/index.browser.js +10 -3
- package/dist/server/core/index.browser.js.map +1 -1
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +28 -5
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/metrics/index.d.ts +514 -1
- package/dist/server/metrics/index.d.ts.map +1 -1
- package/dist/server/metrics/index.js +4374 -4
- package/dist/server/metrics/index.js.map +1 -1
- package/dist/server/swagger/index.d.ts.map +1 -1
- package/dist/server/swagger/index.js +3 -4
- package/dist/server/swagger/index.js.map +1 -1
- package/dist/websocket/index.browser.js +11 -5
- package/dist/websocket/index.browser.js.map +1 -1
- package/dist/websocket/index.d.ts +3 -1
- package/dist/websocket/index.d.ts.map +1 -1
- package/dist/websocket/index.js +21 -6
- package/dist/websocket/index.js.map +1 -1
- package/package.json +671 -263
- package/src/api/parameters/services/ParameterProvider.ts +21 -4
- package/src/api/users/__tests__/SessionService.spec.ts +99 -0
- package/src/api/users/__tests__/UserJobs.spec.ts +67 -0
- package/src/api/users/atoms/realmAuthSettingsAtom.ts +15 -0
- package/src/api/users/entities/sessions.ts +6 -0
- package/src/api/users/jobs/UserJobs.ts +44 -17
- package/src/api/users/providers/RealmProvider.ts +4 -0
- package/src/api/users/services/SessionService.ts +27 -0
- package/src/bucket/__tests__/NodeS3BucketProvider.spec.ts +74 -0
- package/src/bucket/index.ts +19 -2
- package/src/bucket/primitives/$bucket.ts +9 -1
- package/src/bucket/providers/CloudflareR2Provider.ts +2 -137
- package/src/bucket/providers/NodeS3BucketProvider.ts +218 -0
- package/src/cache/core/index.ts +29 -0
- package/src/cache/core/primitives/$cache.ts +14 -1
- package/src/cli/config/defineConfig.ts +13 -15
- package/src/cli/core/__tests__/init.spec.ts +6 -7
- package/src/cli/core/services/ProjectScaffolder.ts +18 -14
- package/src/cli/core/tasks/BuildCloudflareTask.ts +5 -0
- package/src/cli/core/templates/agentMd.ts +2 -10
- package/src/cli/core/templates/saasAdminLayoutTsx.ts +3 -3
- package/src/cli/devtools/index.ts +12 -26
- package/src/cli/platform/index.ts +15 -24
- package/src/cli/vendor/atoms/vendorOptions.ts +1 -1
- package/src/cli/vendor/index.ts +14 -23
- package/src/core/Alepha.ts +11 -1
- package/src/core/helpers/ref.ts +18 -0
- package/src/core/index.shared.ts +1 -0
- package/src/core/providers/SchemaValidator.ts +9 -1
- package/src/core/providers/TypeProvider.ts +1 -2
- package/src/datetime/REFACTORING.md +118 -0
- package/src/datetime/providers/DateTimeProvider.ts +203 -24
- package/src/lock/core/index.ts +31 -0
- package/src/lock/core/primitives/$lock.ts +14 -1
- package/src/mcp/__tests__/jsonrpc.spec.ts +1 -1
- package/src/mcp/helpers/jsonrpc.ts +26 -1
- package/src/mcp/index.ts +10 -5
- package/src/mcp/interfaces/McpTypes.ts +83 -6
- package/src/mcp/primitives/$prompt.ts +18 -1
- package/src/mcp/primitives/$resource.ts +18 -1
- package/src/mcp/primitives/$tool.ts +83 -7
- package/src/mcp/providers/McpServerProvider.ts +74 -16
- package/src/mcp/transports/StreamableHttpMcpTransport.ts +226 -0
- package/src/orm/REFACTORING.md +330 -0
- package/src/orm/core/primitives/$transactional.ts +11 -0
- package/src/orm/core/schemas/updateSchema.ts +1 -1
- package/src/orm/core/services/PgRelationManager.ts +4 -2
- package/src/react/core/__tests__/useQuery.browser.spec.tsx +86 -0
- package/src/react/core/hooks/useQuery.ts +153 -0
- package/src/react/core/index.ts +1 -0
- package/src/react/form/services/FormModel.ts +15 -6
- package/src/react/form/services/parseField.ts +8 -0
- package/src/react/i18n/providers/I18nProvider.ts +8 -2
- package/src/react/router/__tests__/$page.spec.tsx +0 -16
- package/src/react/router/__tests__/ssr.spec.tsx +339 -0
- package/src/react/router/primitives/$page.ts +28 -4
- package/src/react/router/providers/ReactPageProvider.ts +27 -9
- package/src/react/ui/atoms/uiThemeListAtom.ts +36 -0
- package/src/react/ui/index.ts +6 -0
- package/src/react/ui/services/SchemaControl.ts +209 -0
- package/src/security/primitives/$issuer.ts +6 -3
- package/src/server/core/__tests__/ServerRouterProvider-serializationError.spec.ts +75 -0
- package/src/server/core/__tests__/ServerRouterProvider-validationError.spec.ts +306 -0
- package/src/server/core/errors/ValidationError.ts +13 -1
- package/src/server/core/primitives/$action.ts +16 -5
- package/src/server/core/providers/ServerRouterProvider.ts +26 -4
- package/src/server/swagger/providers/ServerSwaggerProvider.ts +5 -7
- package/src/websocket/providers/NodeWebSocketServerProvider.ts +10 -4
- package/src/websocket/services/WebSocketClient.ts +11 -5
- package/src/mcp/transports/SseMcpTransport.ts +0 -182
|
@@ -9,24 +9,189 @@ import { $hook, $inject, Alepha } from "alepha";
|
|
|
9
9
|
import DayjsApi, {
|
|
10
10
|
type Dayjs,
|
|
11
11
|
type ManipulateType,
|
|
12
|
+
type OpUnitType,
|
|
12
13
|
type PluginFunc,
|
|
14
|
+
type QUnitType,
|
|
13
15
|
} from "dayjs";
|
|
14
|
-
import dayjsDuration from "dayjs/plugin/duration.js";
|
|
16
|
+
import dayjsDuration, { type DurationUnitType } from "dayjs/plugin/duration.js";
|
|
15
17
|
import dayjsLocalizedFormat from "dayjs/plugin/localizedFormat.js";
|
|
16
18
|
import dayjsRelativeTime from "dayjs/plugin/relativeTime.js";
|
|
17
19
|
import dayjsTimezone from "dayjs/plugin/timezone.js";
|
|
18
20
|
import dayjsUtc from "dayjs/plugin/utc.js";
|
|
19
21
|
|
|
20
|
-
export type
|
|
21
|
-
|
|
22
|
-
export type
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
export type { DurationUnitType, ManipulateType, OpUnitType, QUnitType };
|
|
23
|
+
|
|
24
|
+
export type DateTimeInput = string | number | Date | DateTime | Dayjs;
|
|
25
|
+
|
|
26
|
+
export type DurationLike = number | Duration | [number, ManipulateType];
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Immutable wrapper around the underlying date-time engine.
|
|
30
|
+
*
|
|
31
|
+
* Designed to isolate consumers from the engine in use (currently dayjs).
|
|
32
|
+
* Methods that produce a new value return a new `DateTime` instance.
|
|
33
|
+
*/
|
|
34
|
+
export class DateTime {
|
|
35
|
+
protected readonly inner: Dayjs;
|
|
36
|
+
|
|
37
|
+
constructor(inner: Dayjs) {
|
|
38
|
+
this.inner = inner;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Add a duration to this date-time.
|
|
43
|
+
*/
|
|
44
|
+
add(amount: number, unit?: ManipulateType): DateTime;
|
|
45
|
+
add(duration: Duration): DateTime;
|
|
46
|
+
add(amount: number | Duration, unit?: ManipulateType): DateTime {
|
|
47
|
+
if (amount instanceof Duration) {
|
|
48
|
+
return new DateTime(this.inner.add(amount.toDayjs()));
|
|
49
|
+
}
|
|
50
|
+
return new DateTime(this.inner.add(amount, unit));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Subtract a duration from this date-time.
|
|
55
|
+
*/
|
|
56
|
+
subtract(amount: number, unit?: ManipulateType): DateTime;
|
|
57
|
+
subtract(duration: Duration): DateTime;
|
|
58
|
+
subtract(amount: number | Duration, unit?: ManipulateType): DateTime {
|
|
59
|
+
if (amount instanceof Duration) {
|
|
60
|
+
return new DateTime(this.inner.subtract(amount.toDayjs()));
|
|
61
|
+
}
|
|
62
|
+
return new DateTime(this.inner.subtract(amount, unit));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
startOf(unit: OpUnitType): DateTime {
|
|
66
|
+
return new DateTime(this.inner.startOf(unit));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
endOf(unit: OpUnitType): DateTime {
|
|
70
|
+
return new DateTime(this.inner.endOf(unit));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
isAfter(other: DateTimeInput): boolean {
|
|
74
|
+
return this.inner.isAfter(toDayjs(other));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
isBefore(other: DateTimeInput): boolean {
|
|
78
|
+
return this.inner.isBefore(toDayjs(other));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
isSame(other: DateTimeInput, unit?: OpUnitType): boolean {
|
|
82
|
+
return this.inner.isSame(toDayjs(other), unit);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
diff(other: DateTimeInput, unit?: QUnitType | OpUnitType): number {
|
|
86
|
+
return this.inner.diff(toDayjs(other), unit);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
tz(timezone: string): DateTime {
|
|
90
|
+
return new DateTime(this.inner.tz(timezone));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
locale(lang: string): DateTime {
|
|
94
|
+
return new DateTime(this.inner.locale(lang));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
format(template?: string): string {
|
|
98
|
+
return this.inner.format(template);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
fromNow(withoutSuffix?: boolean): string {
|
|
102
|
+
return this.inner.fromNow(withoutSuffix);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
toISOString(): string {
|
|
106
|
+
return this.inner.toISOString();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
toDate(): Date {
|
|
110
|
+
return this.inner.toDate();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
valueOf(): number {
|
|
114
|
+
return this.inner.valueOf();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
unix(): number {
|
|
118
|
+
return this.inner.unix();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
toJSON(): string {
|
|
122
|
+
return this.inner.toISOString();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
toString(): string {
|
|
126
|
+
return this.inner.toISOString();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Escape hatch for the underlying dayjs instance.
|
|
131
|
+
*
|
|
132
|
+
* Use sparingly — anything calling this becomes coupled to dayjs and
|
|
133
|
+
* will need to migrate when the engine is replaced.
|
|
134
|
+
*/
|
|
135
|
+
toDayjs(): Dayjs {
|
|
136
|
+
return this.inner;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Immutable wrapper around the underlying duration engine.
|
|
142
|
+
*/
|
|
143
|
+
export class Duration {
|
|
144
|
+
protected readonly inner: dayjsDuration.Duration;
|
|
145
|
+
|
|
146
|
+
constructor(inner: dayjsDuration.Duration) {
|
|
147
|
+
this.inner = inner;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
asMilliseconds(): number {
|
|
151
|
+
return this.inner.asMilliseconds();
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
asSeconds(): number {
|
|
155
|
+
return this.inner.asSeconds();
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
asMinutes(): number {
|
|
159
|
+
return this.inner.asMinutes();
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
asHours(): number {
|
|
163
|
+
return this.inner.asHours();
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
asDays(): number {
|
|
167
|
+
return this.inner.asDays();
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
as(unit: DurationUnitType): number {
|
|
171
|
+
return this.inner.as(unit);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
toISOString(): string {
|
|
175
|
+
return this.inner.toISOString();
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Escape hatch for the underlying dayjs duration.
|
|
180
|
+
*/
|
|
181
|
+
toDayjs(): dayjsDuration.Duration {
|
|
182
|
+
return this.inner;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
26
185
|
|
|
27
|
-
export const dayjs = DayjsApi;
|
|
28
186
|
export const isDateTime = (value: unknown): value is DateTime => {
|
|
29
|
-
return
|
|
187
|
+
return value instanceof DateTime;
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
const toDayjs = (value: DateTimeInput): Dayjs => {
|
|
191
|
+
if (value instanceof DateTime) {
|
|
192
|
+
return value.toDayjs();
|
|
193
|
+
}
|
|
194
|
+
return DayjsApi(value as any);
|
|
30
195
|
};
|
|
31
196
|
|
|
32
197
|
export class DateTimeProvider {
|
|
@@ -45,7 +210,7 @@ export class DateTimeProvider {
|
|
|
45
210
|
|
|
46
211
|
constructor() {
|
|
47
212
|
for (const plugin of DateTimeProvider.PLUGINS) {
|
|
48
|
-
|
|
213
|
+
DayjsApi.extend(plugin);
|
|
49
214
|
}
|
|
50
215
|
}
|
|
51
216
|
|
|
@@ -81,33 +246,34 @@ export class DateTimeProvider {
|
|
|
81
246
|
});
|
|
82
247
|
|
|
83
248
|
public setLocale(locale: string): void {
|
|
84
|
-
|
|
249
|
+
DayjsApi.locale(locale);
|
|
85
250
|
}
|
|
86
251
|
|
|
87
252
|
public isDateTime(value: unknown): value is DateTime {
|
|
88
|
-
return
|
|
253
|
+
return value instanceof DateTime;
|
|
89
254
|
}
|
|
90
255
|
|
|
91
256
|
/**
|
|
92
257
|
* Create a new UTC DateTime instance.
|
|
93
258
|
*/
|
|
94
|
-
public utc(
|
|
95
|
-
|
|
96
|
-
): DateTime {
|
|
97
|
-
return dayjs.utc(date);
|
|
259
|
+
public utc(date: DateTimeInput | null | undefined): DateTime {
|
|
260
|
+
return new DateTime(DayjsApi.utc(unwrap(date)));
|
|
98
261
|
}
|
|
99
262
|
|
|
100
263
|
/**
|
|
101
264
|
* Create a new DateTime instance.
|
|
102
265
|
*/
|
|
103
|
-
public of(date:
|
|
104
|
-
|
|
266
|
+
public of(date: DateTimeInput | null | undefined): DateTime {
|
|
267
|
+
if (date instanceof DateTime) {
|
|
268
|
+
return date;
|
|
269
|
+
}
|
|
270
|
+
return new DateTime(DayjsApi(date as any));
|
|
105
271
|
}
|
|
106
272
|
|
|
107
273
|
/**
|
|
108
274
|
* Get the current date as a string.
|
|
109
275
|
*/
|
|
110
|
-
public toISOString(date:
|
|
276
|
+
public toISOString(date: DateTimeInput = this.now()): string {
|
|
111
277
|
return this.of(date).toISOString();
|
|
112
278
|
}
|
|
113
279
|
|
|
@@ -152,7 +318,7 @@ export class DateTimeProvider {
|
|
|
152
318
|
return this.ref;
|
|
153
319
|
}
|
|
154
320
|
|
|
155
|
-
return
|
|
321
|
+
return new DateTime(DayjsApi());
|
|
156
322
|
}
|
|
157
323
|
|
|
158
324
|
/**
|
|
@@ -162,12 +328,16 @@ export class DateTimeProvider {
|
|
|
162
328
|
duration: DurationLike,
|
|
163
329
|
unit?: ManipulateType,
|
|
164
330
|
): Duration => {
|
|
331
|
+
if (duration instanceof Duration) {
|
|
332
|
+
return duration;
|
|
333
|
+
}
|
|
334
|
+
|
|
165
335
|
if (Array.isArray(duration)) {
|
|
166
|
-
return
|
|
336
|
+
return new Duration(DayjsApi.duration(duration[0], duration[1]));
|
|
167
337
|
}
|
|
168
338
|
|
|
169
339
|
if (typeof duration === "number") {
|
|
170
|
-
return
|
|
340
|
+
return new Duration(DayjsApi.duration(duration, unit || "milliseconds"));
|
|
171
341
|
}
|
|
172
342
|
|
|
173
343
|
return duration;
|
|
@@ -175,7 +345,9 @@ export class DateTimeProvider {
|
|
|
175
345
|
|
|
176
346
|
public isDurationLike(value: unknown): value is DurationLike {
|
|
177
347
|
try {
|
|
178
|
-
return
|
|
348
|
+
return DayjsApi.isDuration(
|
|
349
|
+
this.duration(value as DurationLike).toDayjs(),
|
|
350
|
+
);
|
|
179
351
|
} catch {
|
|
180
352
|
return false;
|
|
181
353
|
}
|
|
@@ -261,7 +433,7 @@ export class DateTimeProvider {
|
|
|
261
433
|
): Timeout {
|
|
262
434
|
if (this.ref && now) {
|
|
263
435
|
const next = this.of(now).add(this.duration(duration));
|
|
264
|
-
if (next < this.now()) {
|
|
436
|
+
if (next.valueOf() < this.now().valueOf()) {
|
|
265
437
|
callback();
|
|
266
438
|
}
|
|
267
439
|
return {
|
|
@@ -403,6 +575,13 @@ export class DateTimeProvider {
|
|
|
403
575
|
}
|
|
404
576
|
}
|
|
405
577
|
|
|
578
|
+
const unwrap = (value: DateTimeInput | null | undefined): any => {
|
|
579
|
+
if (value instanceof DateTime) {
|
|
580
|
+
return value.toDayjs();
|
|
581
|
+
}
|
|
582
|
+
return value;
|
|
583
|
+
};
|
|
584
|
+
|
|
406
585
|
export interface Interval {
|
|
407
586
|
timer?: any;
|
|
408
587
|
duration: number;
|
package/src/lock/core/index.ts
CHANGED
|
@@ -13,6 +13,37 @@ export * from "./providers/MemoryLockProvider.ts";
|
|
|
13
13
|
|
|
14
14
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
15
15
|
|
|
16
|
+
declare module "alepha" {
|
|
17
|
+
interface Hooks {
|
|
18
|
+
/**
|
|
19
|
+
* Fires when a lock is successfully acquired.
|
|
20
|
+
*/
|
|
21
|
+
"lock:acquired": {
|
|
22
|
+
name: string;
|
|
23
|
+
id: string;
|
|
24
|
+
maxDurationMs: number;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Fires when a lock is released (handler completed or threw).
|
|
28
|
+
*/
|
|
29
|
+
"lock:released": {
|
|
30
|
+
name: string;
|
|
31
|
+
id: string;
|
|
32
|
+
heldMs: number;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Fires when a lock acquisition contends with another holder.
|
|
36
|
+
* Emitted whether the caller eventually acquires (`wait: true`) or fails.
|
|
37
|
+
*/
|
|
38
|
+
"lock:contended": {
|
|
39
|
+
name: string;
|
|
40
|
+
id: string;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ---------------------------------------------------------------------------------------------------------------------
|
|
46
|
+
|
|
16
47
|
/**
|
|
17
48
|
* Resource locking for distributed systems.
|
|
18
49
|
*
|
|
@@ -43,7 +43,7 @@ export const $lock = (options: LockMiddlewareOptions): Middleware => {
|
|
|
43
43
|
return createMiddleware({
|
|
44
44
|
name: "$lock",
|
|
45
45
|
options: options as unknown as Record<string, unknown>,
|
|
46
|
-
handler: ({ next }) => {
|
|
46
|
+
handler: ({ alepha, next }) => {
|
|
47
47
|
const id = crypto.randomUUID();
|
|
48
48
|
const maxDurationMs = dateTimeProvider
|
|
49
49
|
.duration(options.maxDuration ?? [5, "minutes"])
|
|
@@ -71,11 +71,13 @@ export const $lock = (options: LockMiddlewareOptions): Middleware => {
|
|
|
71
71
|
|
|
72
72
|
// Lock already ended (grace period active)
|
|
73
73
|
if (endedAtStr) {
|
|
74
|
+
await alepha.events.emit("lock:contended", { name, id });
|
|
74
75
|
throw new LockAcquireError(name);
|
|
75
76
|
}
|
|
76
77
|
|
|
77
78
|
// Lock held by someone else
|
|
78
79
|
if (lockId !== id) {
|
|
80
|
+
await alepha.events.emit("lock:contended", { name, id });
|
|
79
81
|
if (options.wait) {
|
|
80
82
|
// Poll until lock is released
|
|
81
83
|
const start = dateTimeProvider.nowMillis();
|
|
@@ -109,10 +111,21 @@ export const $lock = (options: LockMiddlewareOptions): Middleware => {
|
|
|
109
111
|
}
|
|
110
112
|
|
|
111
113
|
// We hold the lock — execute handler
|
|
114
|
+
const acquiredAt = dateTimeProvider.nowMillis();
|
|
115
|
+
await alepha.events.emit("lock:acquired", {
|
|
116
|
+
name,
|
|
117
|
+
id,
|
|
118
|
+
maxDurationMs,
|
|
119
|
+
});
|
|
112
120
|
try {
|
|
113
121
|
return await next(...args);
|
|
114
122
|
} finally {
|
|
115
123
|
await lockProvider.del(name);
|
|
124
|
+
await alepha.events.emit("lock:released", {
|
|
125
|
+
name,
|
|
126
|
+
id,
|
|
127
|
+
heldMs: dateTimeProvider.nowMillis() - acquiredAt,
|
|
128
|
+
});
|
|
116
129
|
}
|
|
117
130
|
};
|
|
118
131
|
},
|
|
@@ -25,7 +25,7 @@ describe("jsonrpc constants", () => {
|
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
test("MCP_PROTOCOL_VERSION should be defined", () => {
|
|
28
|
-
expect(MCP_PROTOCOL_VERSION).toBe("
|
|
28
|
+
expect(MCP_PROTOCOL_VERSION).toBe("2025-11-25");
|
|
29
29
|
});
|
|
30
30
|
|
|
31
31
|
test("JsonRpcErrorCodes should have correct values", () => {
|
|
@@ -12,7 +12,32 @@ import type {
|
|
|
12
12
|
|
|
13
13
|
export const JSONRPC_VERSION = "2.0" as const;
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
/**
|
|
16
|
+
* The latest MCP protocol revision Alepha targets.
|
|
17
|
+
* See {@link SUPPORTED_PROTOCOL_VERSIONS} for the full negotiation list.
|
|
18
|
+
*/
|
|
19
|
+
export const MCP_PROTOCOL_VERSION = "2025-11-25" as const;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Protocol versions Alepha will accept during `initialize` negotiation,
|
|
23
|
+
* highest preference first. The server echoes back whichever version the
|
|
24
|
+
* client requested if it appears here, otherwise picks the first entry.
|
|
25
|
+
*/
|
|
26
|
+
export const SUPPORTED_PROTOCOL_VERSIONS = [
|
|
27
|
+
"2025-11-25",
|
|
28
|
+
"2025-06-18",
|
|
29
|
+
"2025-03-26",
|
|
30
|
+
"2024-11-05",
|
|
31
|
+
] as const;
|
|
32
|
+
|
|
33
|
+
export type SupportedProtocolVersion =
|
|
34
|
+
(typeof SUPPORTED_PROTOCOL_VERSIONS)[number];
|
|
35
|
+
|
|
36
|
+
export const isSupportedProtocolVersion = (
|
|
37
|
+
v: unknown,
|
|
38
|
+
): v is SupportedProtocolVersion =>
|
|
39
|
+
typeof v === "string" &&
|
|
40
|
+
(SUPPORTED_PROTOCOL_VERSIONS as readonly string[]).includes(v);
|
|
16
41
|
|
|
17
42
|
export const JsonRpcErrorCodes = {
|
|
18
43
|
PARSE_ERROR: -32700,
|
package/src/mcp/index.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { $prompt } from "./primitives/$prompt.ts";
|
|
|
3
3
|
import { $resource } from "./primitives/$resource.ts";
|
|
4
4
|
import { $tool } from "./primitives/$tool.ts";
|
|
5
5
|
import { McpServerProvider } from "./providers/McpServerProvider.ts";
|
|
6
|
-
import {
|
|
6
|
+
import { StreamableHttpMcpTransport } from "./transports/StreamableHttpMcpTransport.ts";
|
|
7
7
|
|
|
8
8
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
9
9
|
|
|
@@ -28,12 +28,15 @@ export {
|
|
|
28
28
|
createParseError,
|
|
29
29
|
createResponse,
|
|
30
30
|
isNotification,
|
|
31
|
+
isSupportedProtocolVersion,
|
|
31
32
|
isValidJsonRpcRequest,
|
|
32
33
|
JSONRPC_VERSION,
|
|
33
34
|
JsonRpcErrorCodes,
|
|
34
35
|
JsonRpcParseError,
|
|
35
36
|
MCP_PROTOCOL_VERSION,
|
|
36
37
|
parseMessage,
|
|
38
|
+
SUPPORTED_PROTOCOL_VERSIONS,
|
|
39
|
+
type SupportedProtocolVersion,
|
|
37
40
|
} from "./helpers/jsonrpc.ts";
|
|
38
41
|
export type {
|
|
39
42
|
JsonRpcError,
|
|
@@ -88,8 +91,10 @@ export { $tool, ToolPrimitive } from "./primitives/$tool.ts";
|
|
|
88
91
|
export { McpServerProvider } from "./providers/McpServerProvider.ts";
|
|
89
92
|
export {
|
|
90
93
|
mcpSseOptions,
|
|
94
|
+
mcpStreamableHttpOptions,
|
|
91
95
|
SseMcpTransport,
|
|
92
|
-
|
|
96
|
+
StreamableHttpMcpTransport,
|
|
97
|
+
} from "./transports/StreamableHttpMcpTransport.ts";
|
|
93
98
|
|
|
94
99
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
95
100
|
|
|
@@ -101,7 +106,7 @@ export {
|
|
|
101
106
|
* - MCP tool definitions
|
|
102
107
|
* - MCP prompt definitions
|
|
103
108
|
* - JSON-RPC protocol
|
|
104
|
-
* -
|
|
109
|
+
* - Streamable HTTP transport (spec 2025-03-26+)
|
|
105
110
|
*
|
|
106
111
|
* @module alepha.mcp
|
|
107
112
|
*/
|
|
@@ -109,6 +114,6 @@ export const AlephaMcp = $module({
|
|
|
109
114
|
name: "alepha.mcp",
|
|
110
115
|
primitives: [$tool, $resource, $prompt],
|
|
111
116
|
services: [McpServerProvider],
|
|
112
|
-
// Transports are opt-in — user wires the one(s) they need via alepha.with(
|
|
113
|
-
variants: [
|
|
117
|
+
// Transports are opt-in — user wires the one(s) they need via alepha.with(StreamableHttpMcpTransport).
|
|
118
|
+
variants: [StreamableHttpMcpTransport],
|
|
114
119
|
});
|
|
@@ -40,14 +40,48 @@ export interface McpCapabilities {
|
|
|
40
40
|
prompts?: Record<string, never>;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Spec 2025-11-25: optional `description` aligns with the MCP registry's
|
|
45
|
+
* `server.json` format and provides human-readable context during init.
|
|
46
|
+
*/
|
|
43
47
|
export interface McpServerInfo {
|
|
44
48
|
name: string;
|
|
45
49
|
version: string;
|
|
50
|
+
description?: string;
|
|
46
51
|
}
|
|
47
52
|
|
|
48
53
|
export interface McpClientInfo {
|
|
49
54
|
name: string;
|
|
50
55
|
version: string;
|
|
56
|
+
description?: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Icon descriptor (spec 2025-11-25 / SEP-973). Mirrors web app manifest
|
|
61
|
+
* icon shape — clients render these in tool palettes / picker UIs.
|
|
62
|
+
*/
|
|
63
|
+
export interface McpIcon {
|
|
64
|
+
src: string;
|
|
65
|
+
mimeType?: string;
|
|
66
|
+
sizes?: string;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Tool annotations (spec 2025-03-26+). Hints to the client about how to
|
|
71
|
+
* present and gate the tool. None are guarantees — the client uses these
|
|
72
|
+
* heuristically (e.g. to show a confirmation prompt for destructive tools).
|
|
73
|
+
*/
|
|
74
|
+
export interface McpToolAnnotations {
|
|
75
|
+
/** Human-friendly display title (distinct from `name`, the programmatic id). */
|
|
76
|
+
title?: string;
|
|
77
|
+
/** Tool reads only; safe to auto-approve. */
|
|
78
|
+
readOnlyHint?: boolean;
|
|
79
|
+
/** Tool may delete or overwrite data; client should require confirmation. */
|
|
80
|
+
destructiveHint?: boolean;
|
|
81
|
+
/** Calling the tool with the same args twice yields the same end state. */
|
|
82
|
+
idempotentHint?: boolean;
|
|
83
|
+
/** Tool interacts with the open world (network, etc.) vs. a closed system. */
|
|
84
|
+
openWorldHint?: boolean;
|
|
51
85
|
}
|
|
52
86
|
|
|
53
87
|
export interface McpInitializeParams {
|
|
@@ -68,14 +102,27 @@ export interface McpInitializeResult {
|
|
|
68
102
|
|
|
69
103
|
export interface McpToolDescriptor {
|
|
70
104
|
name: string;
|
|
105
|
+
/** Human-friendly display label (spec 2025-11-25). Distinct from `name`. */
|
|
106
|
+
title?: string;
|
|
71
107
|
description: string;
|
|
72
108
|
inputSchema: McpJsonSchema;
|
|
109
|
+
/** Output schema enabling `structuredContent` on call results (spec 2025-06-18). */
|
|
110
|
+
outputSchema?: McpJsonSchema;
|
|
111
|
+
/** Behavior hints (spec 2025-03-26+). */
|
|
112
|
+
annotations?: McpToolAnnotations;
|
|
113
|
+
/** Optional icons (spec 2025-11-25 / SEP-973). */
|
|
114
|
+
icons?: McpIcon[];
|
|
115
|
+
/** Arbitrary metadata passthrough (spec 2025-06-18+). */
|
|
116
|
+
_meta?: Record<string, unknown>;
|
|
73
117
|
}
|
|
74
118
|
|
|
75
119
|
export interface McpJsonSchema {
|
|
76
120
|
type: string;
|
|
77
121
|
properties?: Record<string, unknown>;
|
|
78
122
|
required?: string[];
|
|
123
|
+
/** JSON Schema dialect (spec 2025-11-25 / SEP-1613 — defaults to 2020-12). */
|
|
124
|
+
$schema?: string;
|
|
125
|
+
[key: string]: unknown;
|
|
79
126
|
}
|
|
80
127
|
|
|
81
128
|
export interface McpToolCallParams {
|
|
@@ -85,15 +132,33 @@ export interface McpToolCallParams {
|
|
|
85
132
|
|
|
86
133
|
export interface McpToolCallResult {
|
|
87
134
|
content: McpContent[];
|
|
135
|
+
/**
|
|
136
|
+
* Structured tool output (spec 2025-06-18). When the tool declares an
|
|
137
|
+
* `outputSchema`, the server MUST populate `structuredContent`; the
|
|
138
|
+
* `content` array carrying a JSON-stringified text block is kept as
|
|
139
|
+
* a back-compat fallback for older clients.
|
|
140
|
+
*/
|
|
141
|
+
structuredContent?: unknown;
|
|
88
142
|
isError?: boolean;
|
|
143
|
+
_meta?: Record<string, unknown>;
|
|
89
144
|
}
|
|
90
145
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
146
|
+
/**
|
|
147
|
+
* Discriminated content union covering text, image, audio (added 2025-03-26),
|
|
148
|
+
* inlined resources, and resource links (added 2025-06-18).
|
|
149
|
+
*/
|
|
150
|
+
export type McpContent =
|
|
151
|
+
| { type: "text"; text: string }
|
|
152
|
+
| { type: "image"; data: string; mimeType: string }
|
|
153
|
+
| { type: "audio"; data: string; mimeType: string }
|
|
154
|
+
| { type: "resource"; resource: McpResourceContent }
|
|
155
|
+
| {
|
|
156
|
+
type: "resource_link";
|
|
157
|
+
uri: string;
|
|
158
|
+
name: string;
|
|
159
|
+
description?: string;
|
|
160
|
+
mimeType?: string;
|
|
161
|
+
};
|
|
97
162
|
|
|
98
163
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
99
164
|
// Resource Types
|
|
@@ -102,8 +167,14 @@ export interface McpContent {
|
|
|
102
167
|
export interface McpResourceDescriptor {
|
|
103
168
|
uri: string;
|
|
104
169
|
name: string;
|
|
170
|
+
/** Human-friendly display label (spec 2025-11-25). Distinct from `name`. */
|
|
171
|
+
title?: string;
|
|
105
172
|
description?: string;
|
|
106
173
|
mimeType?: string;
|
|
174
|
+
/** Optional icons (spec 2025-11-25 / SEP-973). */
|
|
175
|
+
icons?: McpIcon[];
|
|
176
|
+
/** Arbitrary metadata passthrough (spec 2025-06-18+). */
|
|
177
|
+
_meta?: Record<string, unknown>;
|
|
107
178
|
}
|
|
108
179
|
|
|
109
180
|
export interface McpResourceReadParams {
|
|
@@ -127,8 +198,14 @@ export interface McpResourceContent {
|
|
|
127
198
|
|
|
128
199
|
export interface McpPromptDescriptor {
|
|
129
200
|
name: string;
|
|
201
|
+
/** Human-friendly display label (spec 2025-11-25). Distinct from `name`. */
|
|
202
|
+
title?: string;
|
|
130
203
|
description?: string;
|
|
131
204
|
arguments?: McpPromptArgument[];
|
|
205
|
+
/** Optional icons (spec 2025-11-25 / SEP-973). */
|
|
206
|
+
icons?: McpIcon[];
|
|
207
|
+
/** Arbitrary metadata passthrough (spec 2025-06-18+). */
|
|
208
|
+
_meta?: Record<string, unknown>;
|
|
132
209
|
}
|
|
133
210
|
|
|
134
211
|
export interface McpPromptArgument {
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
} from "alepha";
|
|
11
11
|
import type {
|
|
12
12
|
McpContext,
|
|
13
|
+
McpIcon,
|
|
13
14
|
McpPromptArgument,
|
|
14
15
|
McpPromptDescriptor,
|
|
15
16
|
PromptHandlerArgs,
|
|
@@ -80,6 +81,12 @@ export interface PromptPrimitiveOptions<T extends TObject> {
|
|
|
80
81
|
*/
|
|
81
82
|
name?: string;
|
|
82
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Human-friendly display title (spec 2025-11-25). Distinct from `name`,
|
|
86
|
+
* which remains the programmatic identifier.
|
|
87
|
+
*/
|
|
88
|
+
title?: string;
|
|
89
|
+
|
|
83
90
|
/**
|
|
84
91
|
* Description of what this prompt does.
|
|
85
92
|
*
|
|
@@ -89,6 +96,11 @@ export interface PromptPrimitiveOptions<T extends TObject> {
|
|
|
89
96
|
*/
|
|
90
97
|
description?: string;
|
|
91
98
|
|
|
99
|
+
/**
|
|
100
|
+
* Optional icons surfaced in client UIs (spec 2025-11-25 / SEP-973).
|
|
101
|
+
*/
|
|
102
|
+
icons?: McpIcon[];
|
|
103
|
+
|
|
92
104
|
/**
|
|
93
105
|
* TypeBox schema defining the prompt arguments.
|
|
94
106
|
*
|
|
@@ -157,13 +169,18 @@ export class PromptPrimitive<T extends TObject> extends Primitive<
|
|
|
157
169
|
* Convert the prompt to an MCP prompt descriptor for protocol messages.
|
|
158
170
|
*/
|
|
159
171
|
public toDescriptor(): McpPromptDescriptor {
|
|
160
|
-
|
|
172
|
+
const descriptor: McpPromptDescriptor = {
|
|
161
173
|
name: this.name,
|
|
162
174
|
description: this.description,
|
|
163
175
|
arguments: this.options.args
|
|
164
176
|
? this.schemaToArguments(this.options.args)
|
|
165
177
|
: [],
|
|
166
178
|
};
|
|
179
|
+
if (this.options.title) descriptor.title = this.options.title;
|
|
180
|
+
if (this.options.icons && this.options.icons.length > 0) {
|
|
181
|
+
descriptor.icons = this.options.icons;
|
|
182
|
+
}
|
|
183
|
+
return descriptor;
|
|
167
184
|
}
|
|
168
185
|
|
|
169
186
|
/**
|