@tuturuuu/utils 0.31.0 → 0.33.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/CHANGELOG.md +29 -0
- package/package.json +2 -2
- package/src/commercial-comparison.ts +14 -0
- package/src/devbox-control.ts +23 -0
- package/src/email/__tests__/client.test.ts +11 -0
- package/src/email/client.ts +6 -0
- package/src/platform-release.test.ts +1 -1
- package/src/platform-release.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.33.0](https://github.com/tutur3u/platform/compare/utils-v0.32.0...utils-v0.33.0) (2026-09-29)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **auth:** enforce required account MFA lifecycle ([#5448](https://github.com/tutur3u/platform/issues/5448)) ([d7a5ed4](https://github.com/tutur3u/platform/commit/d7a5ed453963e619bd1dc3bd8c8a18c5e027317c))
|
|
9
|
+
* **cron:** gate immediate recovery on Cloudflare ([546f389](https://github.com/tutur3u/platform/commit/546f3899143c09d52dfa198698b1c4310b860db2)) ([#5615](https://github.com/tutur3u/platform/issues/5615)) ([8eac476](https://github.com/tutur3u/platform/commit/8eac47606da1e1295cb3e6c80c96e5b4d3750068))
|
|
10
|
+
* **devboxes:** route agent control through Cloudflare ([98d4580](https://github.com/tutur3u/platform/commit/98d4580b39308fdd835e1762ebad102fe6ca3f02)) ([#5614](https://github.com/tutur3u/platform/issues/5614)) ([cbd18fa](https://github.com/tutur3u/platform/commit/cbd18fa70ee2d88c8b7e607ab56631c581b723c9))
|
|
11
|
+
* **parley:** add private multiplayer training and shared AI Hub billing ([#5505](https://github.com/tutur3u/platform/issues/5505)) ([038e05c](https://github.com/tutur3u/platform/commit/038e05c69a0e4a080f62d6441ae4dd2b15721dba))
|
|
12
|
+
* **parley:** share Meet runtime and integrate private training with AI Hub billing ([66d40e2](https://github.com/tutur3u/platform/commit/66d40e23a8110bd43be652e1181205cf50e506ab))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* **devboxes:** load Durable Object base and register internal app ([50a4ed0](https://github.com/tutur3u/platform/commit/50a4ed0dd5f639c44f513e6d7e2ca663452b76bb))
|
|
18
|
+
|
|
19
|
+
## [0.32.0](https://github.com/tutur3u/platform/compare/utils-v0.31.0...utils-v0.32.0) (2026-09-29)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Features
|
|
23
|
+
|
|
24
|
+
* **cron:** gate immediate recovery on Cloudflare ([546f389](https://github.com/tutur3u/platform/commit/546f3899143c09d52dfa198698b1c4310b860db2)) ([#5615](https://github.com/tutur3u/platform/issues/5615)) ([8eac476](https://github.com/tutur3u/platform/commit/8eac47606da1e1295cb3e6c80c96e5b4d3750068))
|
|
25
|
+
* **devboxes:** route agent control through Cloudflare ([98d4580](https://github.com/tutur3u/platform/commit/98d4580b39308fdd835e1762ebad102fe6ca3f02)) ([#5614](https://github.com/tutur3u/platform/issues/5614)) ([cbd18fa](https://github.com/tutur3u/platform/commit/cbd18fa70ee2d88c8b7e607ab56631c581b723c9))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Bug Fixes
|
|
29
|
+
|
|
30
|
+
* **devboxes:** load Durable Object base and register internal app ([50a4ed0](https://github.com/tutur3u/platform/commit/50a4ed0dd5f639c44f513e6d7e2ca663452b76bb))
|
|
31
|
+
|
|
3
32
|
## [0.31.0](https://github.com/tutur3u/platform/compare/utils-v0.30.0...utils-v0.31.0) (2026-09-25)
|
|
4
33
|
|
|
5
34
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tuturuuu/utils",
|
|
3
3
|
"license": "MIT",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.33.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/tutur3u/platform",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"@tiptap/react": "3.31.3",
|
|
25
25
|
"@tuturuuu/google": "0.1.1",
|
|
26
26
|
"@tuturuuu/icons": "0.1.1",
|
|
27
|
-
"@tuturuuu/internal-api": "0.
|
|
27
|
+
"@tuturuuu/internal-api": "0.47.0",
|
|
28
28
|
"@tuturuuu/supabase": "0.5.2",
|
|
29
29
|
"@upstash/ratelimit": "^2.0.8",
|
|
30
30
|
"@upstash/redis": "^1.38.4",
|
|
@@ -9,6 +9,20 @@ import { features2 } from './commercial-comparison-2';
|
|
|
9
9
|
|
|
10
10
|
const gateOrder = ['FREE', 'PLUS', 'PRO', 'ENTERPRISE'];
|
|
11
11
|
const advanced: ComparisonFeature[] = [
|
|
12
|
+
{
|
|
13
|
+
id: 'cronControl',
|
|
14
|
+
app: 'cron-control',
|
|
15
|
+
category: 'internal',
|
|
16
|
+
detail: 'standard',
|
|
17
|
+
values: ['internal', 'internal', 'internal', 'internal'],
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: 'devboxControl',
|
|
21
|
+
app: 'devbox-control',
|
|
22
|
+
category: 'internal',
|
|
23
|
+
detail: 'standard',
|
|
24
|
+
values: ['internal', 'internal', 'internal', 'internal'],
|
|
25
|
+
},
|
|
12
26
|
{
|
|
13
27
|
id: 'parley_0',
|
|
14
28
|
app: 'parley',
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Best-effort wake signal. The runner also polls, so enqueue never depends on it. */
|
|
2
|
+
export async function notifyDevboxRun(runId: string) {
|
|
3
|
+
const origin = process.env.TUTURUUU_DEVBOX_CONTROL_URL?.trim();
|
|
4
|
+
const token = process.env.TUTURUUU_DEVBOX_CONTROL_TOKEN?.trim();
|
|
5
|
+
if (!origin || !token) return;
|
|
6
|
+
try {
|
|
7
|
+
const url = new URL('/v1/notify', origin);
|
|
8
|
+
if (url.protocol !== 'https:') throw new Error('Invalid control URL');
|
|
9
|
+
const response = await fetch(url, {
|
|
10
|
+
method: 'POST',
|
|
11
|
+
headers: {
|
|
12
|
+
Authorization: `Bearer ${token}`,
|
|
13
|
+
'Content-Type': 'application/json',
|
|
14
|
+
},
|
|
15
|
+
body: JSON.stringify({ runId }),
|
|
16
|
+
signal: AbortSignal.timeout(2000),
|
|
17
|
+
});
|
|
18
|
+
if (!response.ok)
|
|
19
|
+
console.warn('Devbox wake signal rejected', response.status);
|
|
20
|
+
} catch {
|
|
21
|
+
console.warn('Devbox wake signal unavailable');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
isEmail,
|
|
6
6
|
isExactTuturuuuDotComEmail,
|
|
7
7
|
isIncompleteEmail,
|
|
8
|
+
isTuturuuuReviewEmail,
|
|
8
9
|
isValidTuturuuuEmail,
|
|
9
10
|
suggestEmails,
|
|
10
11
|
} from '../client';
|
|
@@ -90,6 +91,16 @@ describe('isExactTuturuuuDotComEmail', () => {
|
|
|
90
91
|
});
|
|
91
92
|
});
|
|
92
93
|
|
|
94
|
+
describe('isTuturuuuReviewEmail', () => {
|
|
95
|
+
it('accepts only the routed non-staff review domain', () => {
|
|
96
|
+
expect(isTuturuuuReviewEmail('APP-REVIEW@TUTUR3U.COM')).toBe(true);
|
|
97
|
+
expect(isTuturuuuReviewEmail('review@tuturuuu.com')).toBe(false);
|
|
98
|
+
expect(isTuturuuuReviewEmail('review@xwf.tuturuuu.com')).toBe(false);
|
|
99
|
+
expect(isTuturuuuReviewEmail('review@sub.tutur3u.com')).toBe(false);
|
|
100
|
+
expect(isTuturuuuReviewEmail('review@tutur3u.com.evil.test')).toBe(false);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
93
104
|
describe('isEmail', () => {
|
|
94
105
|
it('validates complex email formats', () => {
|
|
95
106
|
expect(isEmail('user.name+alias@example.co.uk')).toBe(true);
|
package/src/email/client.ts
CHANGED
|
@@ -31,6 +31,12 @@ export const isExactTuturuuuDotComEmail = (email?: string | null): boolean => {
|
|
|
31
31
|
return /^[^\s@]+@tuturuuu\.com$/i.test(email.trim());
|
|
32
32
|
};
|
|
33
33
|
|
|
34
|
+
/** Routed QA domain. It is deliberately outside all staff-email allowlists. */
|
|
35
|
+
export const isTuturuuuReviewEmail = (email?: string | null): boolean => {
|
|
36
|
+
if (!email) return false;
|
|
37
|
+
return /^[^\s@]+@tutur3u\.com$/i.test(email.trim());
|
|
38
|
+
};
|
|
39
|
+
|
|
34
40
|
export const isEmail = (text: string): boolean => {
|
|
35
41
|
const emailRegex =
|
|
36
42
|
/^(?:[^<>()[\]\\.,;:\s@"]+(?:\.[^<>()[\]\\.,;:\s@"]+)*|".+")@(?:\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}]|(?:[a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,})$/;
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
|
|
8
8
|
describe('platform release metadata', () => {
|
|
9
9
|
it('uses the centralized shared browser app version', () => {
|
|
10
|
-
expect(TUTURUUU_PLATFORM_VERSION).toBe('0.
|
|
10
|
+
expect(TUTURUUU_PLATFORM_VERSION).toBe('0.62.0'); // x-release-please-version
|
|
11
11
|
});
|
|
12
12
|
|
|
13
13
|
it('preserves the source timestamp in builtAt and derives a short hash', () => {
|
package/src/platform-release.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PLATFORM_BUILD_METADATA } from './generated/platform-build-metadata';
|
|
2
2
|
|
|
3
|
-
export const TUTURUUU_PLATFORM_VERSION = '0.
|
|
3
|
+
export const TUTURUUU_PLATFORM_VERSION = '0.62.0'; // x-release-please-version
|
|
4
4
|
|
|
5
5
|
export type PlatformBuildMetadataInput = {
|
|
6
6
|
/** ISO timestamp of the source commit used for the build, not deployment time. */
|