@h-ai/cli 0.1.0-alpha.20 → 0.1.0-alpha.21
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/README.md +10 -7
- package/dist/{chunk-GSMXGUYF.js → chunk-5IGMJVV5.js} +56 -38
- package/dist/chunk-5IGMJVV5.js.map +1 -0
- package/dist/{chunk-3BBXDQ4Y.js → chunk-CFCXOKGV.js} +24 -2
- package/dist/chunk-CFCXOKGV.js.map +1 -0
- package/dist/cli-config-templates-5J5VKWWD.js +5 -0
- package/dist/{cli-config-templates-IGGO7P45.js.map → cli-config-templates-5J5VKWWD.js.map} +1 -1
- package/dist/cli-skill-templates-JMSV2SVW.js +5 -0
- package/dist/{cli-skill-templates-IMYZPQRG.js.map → cli-skill-templates-JMSV2SVW.js.map} +1 -1
- package/dist/index.js +567 -75
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
- package/templates/README.md +40 -29
- package/templates/apps/api/apps/{{projectName}}-contract/README.md.hbs +16 -0
- package/templates/apps/api/apps/{{projectName}}-contract/package.json.hbs +38 -0
- package/templates/apps/api/apps/{{projectName}}-contract/src/app-contract.ts.hbs +27 -0
- package/templates/apps/api/apps/{{projectName}}-contract/src/app-schemas.ts.hbs +33 -0
- package/templates/apps/api/apps/{{projectName}}-contract/src/index.ts.hbs +3 -0
- package/templates/apps/api/apps/{{projectName}}-contract/src/{{projectName}}-contract.ts.hbs +12 -0
- package/templates/apps/api/apps/{{projectName}}-contract/tests/contract.test.ts.hbs +18 -0
- package/templates/apps/api/apps/{{projectName}}-contract/tsconfig.json.hbs +12 -0
- package/templates/apps/api/apps/{{projectName}}-contract/tsup.config.ts.hbs +11 -0
- package/templates/apps/api/apps/{{projectName}}-contract/vitest.config.ts.hbs +9 -0
- package/templates/apps/api/apps/{{projectName}}-service/README.md.hbs +17 -0
- package/templates/apps/api/apps/{{projectName}}-service/config/_core.yml.hbs +19 -0
- package/templates/apps/api/apps/{{projectName}}-service/config/_serv.yml.hbs +26 -0
- package/templates/apps/api/apps/{{projectName}}-service/package.json.hbs +55 -0
- package/templates/apps/api/apps/{{projectName}}-service/src/app.ts.hbs +98 -0
- package/templates/apps/api/apps/{{projectName}}-service/src/index.ts.hbs +21 -0
- package/templates/apps/api/apps/{{projectName}}-service/src/lib/server/init.ts.hbs +184 -0
- package/templates/apps/api/apps/{{projectName}}-service/src/server/procedures/app-procedures.ts.hbs +49 -0
- package/templates/apps/api/apps/{{projectName}}-service/src/server/procedures/index.ts.hbs +18 -0
- package/templates/apps/api/apps/{{projectName}}-service/tests/service.test.ts.hbs +168 -0
- package/templates/apps/api/apps/{{projectName}}-service/tsconfig.json.hbs +16 -0
- package/templates/apps/api/apps/{{projectName}}-service/tsup.config.ts.hbs +11 -0
- package/templates/apps/api/apps/{{projectName}}-service/vitest.config.ts.hbs +9 -0
- package/templates/apps/api/e2e/api-service.spec.ts.hbs +18 -0
- package/templates/apps/api/eslint.config.js +32 -0
- package/templates/apps/api/package.json.hbs +29 -0
- package/templates/apps/api/playwright.config.ts.hbs +58 -0
- package/templates/apps/api/pnpm-workspace.yaml.hbs +14 -0
- package/templates/apps/api/tsconfig.base.json +15 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/.env.example.hbs +10 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/README.md.hbs +24 -7
- package/templates/apps/fullstack/apps/{{projectName}}-app/capacitor.config.ts.hbs +18 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/eslint.config.js.hbs +1 -1
- package/templates/apps/fullstack/apps/{{projectName}}-app/index.html.hbs +16 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/messages/en-US.json.hbs +6 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/messages/zh-CN.json.hbs +6 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/package.json.hbs +51 -29
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/App.svelte.hbs +186 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/app.css.hbs +2 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/app.d.ts.hbs +0 -1
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/lib/capacitor.ts.hbs +18 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/main.ts.hbs +14 -0
- package/templates/apps/fullstack/apps/{{projectName}}-app/svelte.config.js.hbs +1 -5
- package/templates/apps/fullstack/apps/{{projectName}}-app/tsconfig.json.hbs +10 -4
- package/templates/apps/fullstack/apps/{{projectName}}-app/vite.config.ts.hbs +4 -3
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/.env.example.hbs +6 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/README.md.hbs +20 -6
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/eslint.config.js.hbs +1 -1
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/index.html.hbs +15 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/package.json.hbs +33 -30
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/App.svelte.hbs +152 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/app.d.ts.hbs +1 -2
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/main.ts.hbs +13 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/Cargo.toml.hbs +22 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/build.rs.hbs +6 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/capabilities/default.json.hbs +12 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/icons/128x128.png +0 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/icons/128x128@2x.png +0 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/icons/32x32.png +0 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/icons/icon.icns +0 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/icons/icon.ico +0 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/src/lib.rs.hbs +16 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/src/main.rs.hbs +8 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src-tauri/tauri.conf.json.hbs +41 -0
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/svelte.config.js.hbs +2 -8
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/tsconfig.json.hbs +9 -4
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/vite.config.ts.hbs +44 -21
- package/templates/apps/fullstack/apps/{{projectName}}-web/README.md.hbs +15 -6
- package/templates/apps/fullstack/apps/{{projectName}}-web/eslint.config.js.hbs +1 -1
- package/templates/apps/fullstack/apps/{{projectName}}-web/index.html.hbs +15 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/package.json.hbs +25 -27
- package/templates/apps/fullstack/apps/{{projectName}}-web/src/App.svelte.hbs +153 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/src/app.d.ts.hbs +0 -1
- package/templates/apps/fullstack/apps/{{projectName}}-web/src/main.ts.hbs +14 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/svelte.config.js.hbs +1 -5
- package/templates/apps/fullstack/apps/{{projectName}}-web/tsconfig.json.hbs +10 -4
- package/templates/apps/fullstack/apps/{{projectName}}-web/vite.config.ts.hbs +3 -2
- package/templates/apps/fullstack/e2e/fullstack.spec.ts.hbs +2 -1
- package/templates/apps/fullstack/eslint.config.js +0 -1
- package/templates/apps/fullstack/package.json.hbs +18 -17
- package/templates/apps/fullstack/packages/{{projectName}}-contract/package.json.hbs +3 -3
- package/templates/apps/fullstack/packages/{{projectName}}-serv/README.md.hbs +2 -2
- package/templates/apps/fullstack/packages/{{projectName}}-serv/package.json.hbs +2 -2
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/index.ts.hbs +1 -1
- package/templates/apps/fullstack/packages/{{projectName}}-serv/tests/{server-app.test.ts.hbs → app-server.test.ts.hbs} +1 -1
- package/templates/apps/fullstack/packages/{{projectName}}-shared/package.json.hbs +9 -8
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/index.ts.hbs +1 -1
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/api/api-client.ts.hbs +5 -1
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/ThemeSwitcher.svelte.hbs +1 -1
- package/templates/apps/fullstack/packages/{{projectName}}-shared/tsconfig.json.hbs +1 -1
- package/templates/apps/fullstack/playwright.config.ts.hbs +41 -4
- package/templates/apps/fullstack/pnpm-workspace.yaml.hbs +15 -0
- package/templates/apps/mobile-app/.env.hbs +3 -0
- package/templates/apps/{android-app → mobile-app}/capacitor.config.ts.hbs +2 -2
- package/templates/apps/mobile-app/index.html.hbs +13 -0
- package/templates/apps/mobile-app/messages/en-US.json +36 -0
- package/templates/apps/mobile-app/messages/zh-CN.json +36 -0
- package/templates/apps/mobile-app/src/App.svelte.hbs +162 -0
- package/templates/apps/mobile-app/src/lib/api.ts.hbs +54 -0
- package/templates/apps/{android-app → mobile-app}/src/lib/capacitor.ts +5 -6
- package/templates/apps/mobile-app/src/main.ts.hbs +11 -0
- package/templates/base/.gitignore.hbs +16 -0
- package/templates/base/{eslint.config.js → eslint.config.js.hbs} +4 -1
- package/templates/base/package.json.hbs +52 -33
- package/templates/base/playwright.config.ts +30 -3
- package/templates/base/pnpm-workspace.yaml.hbs +14 -0
- package/templates/base/src/app.d.ts.hbs +3 -0
- package/templates/base/src/app.html.hbs +3 -0
- package/templates/base/svelte.config.js.hbs +43 -3
- package/templates/base/tests/scaffold.test.ts.hbs +7 -0
- package/templates/base/tsconfig.json.hbs +50 -0
- package/templates/base/vite.config.ts.hbs +10 -0
- package/templates/skills/AGENTS.md +57 -24
- package/templates/skills/CLAUDE.md +18 -7
- package/templates/skills/bridges/admin/AGENTS.md +66 -0
- package/templates/skills/bridges/admin/CLAUDE.md +19 -0
- package/templates/skills/bridges/admin/copilot-instructions.md +46 -0
- package/templates/skills/bridges/api/AGENTS.md +65 -0
- package/templates/skills/bridges/api/CLAUDE.md +19 -0
- package/templates/skills/bridges/api/copilot-instructions.md +46 -0
- package/templates/skills/bridges/fullstack/AGENTS.md +84 -0
- package/templates/skills/bridges/fullstack/CLAUDE.md +19 -0
- package/templates/skills/bridges/fullstack/copilot-instructions.md +54 -0
- package/templates/skills/bridges/h5/AGENTS.md +65 -0
- package/templates/skills/bridges/h5/CLAUDE.md +19 -0
- package/templates/skills/bridges/h5/copilot-instructions.md +44 -0
- package/templates/skills/bridges/mobile-app/AGENTS.md +77 -0
- package/templates/skills/bridges/mobile-app/CLAUDE.md +19 -0
- package/templates/skills/bridges/mobile-app/copilot-instructions.md +45 -0
- package/templates/skills/bridges/website/AGENTS.md +65 -0
- package/templates/skills/bridges/website/CLAUDE.md +19 -0
- package/templates/skills/bridges/website/copilot-instructions.md +44 -0
- package/templates/skills/copilot-instructions.md +27 -64
- package/templates/skills/hai-app-create/SKILL.md +1 -0
- package/templates/skills/hai-app-review/SKILL.md +1 -1
- package/templates/skills/hai-app-tests/SKILL.md +28 -3
- package/templates/skills/hai-capacitor/SKILL.md +14 -22
- package/templates/skills/opencode.json +1 -6
- package/dist/chunk-3BBXDQ4Y.js.map +0 -1
- package/dist/chunk-GSMXGUYF.js.map +0 -1
- package/dist/cli-config-templates-IGGO7P45.js +0 -5
- package/dist/cli-skill-templates-IMYZPQRG.js +0 -5
- package/templates/apps/android-app/.env.hbs +0 -3
- package/templates/apps/android-app/messages/en-US.json +0 -24
- package/templates/apps/android-app/messages/zh-CN.json +0 -24
- package/templates/apps/android-app/src/lib/api.ts.hbs +0 -32
- package/templates/apps/android-app/src/routes/+layout.svelte.hbs +0 -43
- package/templates/apps/android-app/src/routes/+layout.ts +0 -7
- package/templates/apps/android-app/src/routes/+page.svelte.hbs +0 -38
- package/templates/apps/api/src/routes/+layout.svelte +0 -14
- package/templates/apps/api/src/routes/+page.svelte +0 -11
- package/templates/apps/api/src/routes/api/v1/health/+server.ts +0 -14
- package/templates/apps/api/src/routes/api/v1/items/+server.ts +0 -37
- package/templates/apps/api/src/routes/api/v1/items/[id]/+server.ts +0 -30
- package/templates/apps/api/tests/health.test.ts.hbs +0 -26
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/app.html.hbs +0 -14
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/routes/+layout.svelte.hbs +0 -18
- package/templates/apps/fullstack/apps/{{projectName}}-app/src/routes/+page.svelte.hbs +0 -162
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/app.html.hbs +0 -14
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/routes/+layout.svelte.hbs +0 -18
- package/templates/apps/fullstack/apps/{{projectName}}-desktop/src/routes/+page.svelte.hbs +0 -162
- package/templates/apps/fullstack/apps/{{projectName}}-web/src/app.html.hbs +0 -14
- package/templates/apps/fullstack/apps/{{projectName}}-web/src/routes/+layout.svelte.hbs +0 -18
- package/templates/apps/fullstack/apps/{{projectName}}-web/src/routes/+page.svelte.hbs +0 -162
- package/templates/apps/fullstack/pnpm-workspace.yaml +0 -7
- package/templates/base/tsconfig.json +0 -20
- /package/templates/apps/fullstack/packages/{{projectName}}-serv/src/{server-app.ts.hbs → app-server.ts.hbs} +0 -0
- /package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/stores/{theme.svelte.ts.hbs → theme-store.svelte.ts.hbs} +0 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://inlang.com/schema/inlang-message-format",
|
|
3
|
+
"app_title": "移动工作台",
|
|
4
|
+
"app_description": "基于 hai Agent Framework + Capacitor + Svelte 5 构建的移动应用",
|
|
5
|
+
"boot_failed_title": "启动失败",
|
|
6
|
+
"common_retry": "重试",
|
|
7
|
+
"common_refresh": "刷新",
|
|
8
|
+
"common_enabled": "已启用",
|
|
9
|
+
"common_disabled": "未启用",
|
|
10
|
+
"nav_home": "工作台",
|
|
11
|
+
"nav_tasks": "任务",
|
|
12
|
+
"nav_profile": "我的",
|
|
13
|
+
"hero_eyebrow": "Mobile Workspace",
|
|
14
|
+
"hero_title": "真正可用的移动端起点",
|
|
15
|
+
"hero_subtitle": "Capacitor 原生能力、安全 Token 存储、统一 API Client 与 @h-ai/ui 移动组件已经接好。",
|
|
16
|
+
"feature_native_title": "原生能力",
|
|
17
|
+
"feature_native_desc": "状态栏、安全区与设备信息就绪,可继续接入推送、相机等插件。",
|
|
18
|
+
"feature_api_title": "统一 API",
|
|
19
|
+
"feature_api_desc": "通过 PUBLIC_API_BASE 连接服务端,Token 在原生端走安全存储。",
|
|
20
|
+
"status_title": "运行状态",
|
|
21
|
+
"status_api_label": "API 地址",
|
|
22
|
+
"status_runtime_label": "运行环境",
|
|
23
|
+
"status_runtime_native": "原生 App",
|
|
24
|
+
"status_runtime_web": "浏览器预览",
|
|
25
|
+
"status_token_label": "Token 存储",
|
|
26
|
+
"status_token_native": "安全存储",
|
|
27
|
+
"status_token_memory": "内存存储",
|
|
28
|
+
"tasks_title": "今日任务",
|
|
29
|
+
"tasks_sync": "同步后端接口",
|
|
30
|
+
"tasks_polish": "打磨移动端体验",
|
|
31
|
+
"tasks_release": "准备原生打包",
|
|
32
|
+
"profile_title": "应用设置",
|
|
33
|
+
"profile_language": "语言跟随 Paraglide",
|
|
34
|
+
"profile_theme": "主题跟随 @h-ai/ui",
|
|
35
|
+
"profile_secure": "敏感 Token 不落 localStorage"
|
|
36
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
<script lang='ts'>
|
|
2
|
+
import { applyTheme, getSavedTheme, setGlobalLocale } from '@h-ai/ui'
|
|
3
|
+
import { onMount } from 'svelte'
|
|
4
|
+
import { closeApi, initApi, resolveApiBase, usesNativeTokenStorage } from './lib/api.js'
|
|
5
|
+
import { initCapacitor, isNativeApp } from './lib/capacitor.js'
|
|
6
|
+
import * as m from './lib/paraglide/messages.js'
|
|
7
|
+
import { getLocale } from './lib/paraglide/runtime.js'
|
|
8
|
+
|
|
9
|
+
type TabId = 'home' | 'tasks' | 'profile'
|
|
10
|
+
|
|
11
|
+
let booting = $state(true)
|
|
12
|
+
let bootError = $state<string | null>(null)
|
|
13
|
+
let activeTab = $state<TabId>('home')
|
|
14
|
+
let nativeRuntime = $state(false)
|
|
15
|
+
let nativeTokenStorage = $state(false)
|
|
16
|
+
|
|
17
|
+
const navItems = $derived([
|
|
18
|
+
{ id: 'home', label: m.nav_home(), iconClass: 'icon-[tabler--layout-dashboard]' },
|
|
19
|
+
{ id: 'tasks', label: m.nav_tasks(), iconClass: 'icon-[tabler--checkbox]' },
|
|
20
|
+
{ id: 'profile', label: m.nav_profile(), iconClass: 'icon-[tabler--user-circle]' },
|
|
21
|
+
])
|
|
22
|
+
|
|
23
|
+
async function bootstrap(): Promise<void> {
|
|
24
|
+
try {
|
|
25
|
+
applyTheme(getSavedTheme(), false)
|
|
26
|
+
setGlobalLocale(getLocale())
|
|
27
|
+
await initCapacitor()
|
|
28
|
+
await initApi()
|
|
29
|
+
nativeRuntime = await isNativeApp()
|
|
30
|
+
nativeTokenStorage = await usesNativeTokenStorage()
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
bootError = error instanceof Error ? error.message : String(error)
|
|
34
|
+
}
|
|
35
|
+
finally {
|
|
36
|
+
booting = false
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function handleTabChange(id: string): void {
|
|
41
|
+
if (id === 'home' || id === 'tasks' || id === 'profile')
|
|
42
|
+
activeTab = id
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
onMount(() => {
|
|
46
|
+
void bootstrap()
|
|
47
|
+
|
|
48
|
+
return () => {
|
|
49
|
+
void closeApi()
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
</script>
|
|
53
|
+
|
|
54
|
+
{#if booting}
|
|
55
|
+
<div class='hai-mobile-viewport'>
|
|
56
|
+
<div class='hai-mobile-shell max-w-lg'>
|
|
57
|
+
<div class='flex min-h-screen items-center justify-center'>
|
|
58
|
+
<span class='loading loading-spinner loading-lg'></span>
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
{:else if bootError}
|
|
63
|
+
<div class='hai-mobile-viewport'>
|
|
64
|
+
<div class='hai-mobile-shell max-w-lg'>
|
|
65
|
+
<div class='flex min-h-screen flex-col items-center justify-center gap-3 p-6 text-center'>
|
|
66
|
+
<span class='icon-[tabler--alert-triangle] text-error text-4xl'></span>
|
|
67
|
+
<h1 class='text-lg font-bold'>{m.boot_failed_title()}</h1>
|
|
68
|
+
<p class='text-base-content/60 text-sm'>{bootError}</p>
|
|
69
|
+
<Button variant='primary' size='sm' onclick={() => location.reload()}>{m.common_retry()}</Button>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
{:else}
|
|
74
|
+
<div class='hai-mobile-viewport'>
|
|
75
|
+
<div class='hai-mobile-shell max-w-lg'>
|
|
76
|
+
<AppBar title={m.app_title()} safeArea fixed={false} class='bg-base-100/95 backdrop-blur border-base-content/8' />
|
|
77
|
+
|
|
78
|
+
<main class='hai-mobile-main'>
|
|
79
|
+
{#if activeTab === 'home'}
|
|
80
|
+
<section class='space-y-4 p-4 pb-6'>
|
|
81
|
+
<div class='bg-primary text-primary-content rounded-2xl p-5 shadow-sm'>
|
|
82
|
+
<p class='text-sm opacity-75'>{m.hero_eyebrow()}</p>
|
|
83
|
+
<h1 class='mt-1 text-2xl font-bold'>{m.hero_title()}</h1>
|
|
84
|
+
<p class='mt-2 text-sm opacity-80'>{m.hero_subtitle()}</p>
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
<div class='grid grid-cols-2 gap-3'>
|
|
88
|
+
<Card padding='sm' shadow='sm'>
|
|
89
|
+
<div class='flex flex-col gap-2'>
|
|
90
|
+
<span class='icon-[tabler--device-mobile-code] text-primary text-2xl'></span>
|
|
91
|
+
<span class='text-sm font-medium'>{m.feature_native_title()}</span>
|
|
92
|
+
<span class='text-base-content/60 text-xs'>{m.feature_native_desc()}</span>
|
|
93
|
+
</div>
|
|
94
|
+
</Card>
|
|
95
|
+
<Card padding='sm' shadow='sm'>
|
|
96
|
+
<div class='flex flex-col gap-2'>
|
|
97
|
+
<span class='icon-[tabler--api-app] text-primary text-2xl'></span>
|
|
98
|
+
<span class='text-sm font-medium'>{m.feature_api_title()}</span>
|
|
99
|
+
<span class='text-base-content/60 text-xs'>{m.feature_api_desc()}</span>
|
|
100
|
+
</div>
|
|
101
|
+
</Card>
|
|
102
|
+
</div>
|
|
103
|
+
|
|
104
|
+
<Card title={m.status_title()} shadow='sm'>
|
|
105
|
+
<div class='grid grid-cols-2 gap-3 text-sm'>
|
|
106
|
+
<div>
|
|
107
|
+
<p class='text-base-content/50'>{m.status_api_label()}</p>
|
|
108
|
+
<p class='font-medium break-all'>{resolveApiBase()}</p>
|
|
109
|
+
</div>
|
|
110
|
+
<div>
|
|
111
|
+
<p class='text-base-content/50'>{m.status_runtime_label()}</p>
|
|
112
|
+
<Badge variant={nativeRuntime ? 'success' : 'warning'} size='sm'>
|
|
113
|
+
{nativeRuntime ? m.status_runtime_native() : m.status_runtime_web()}
|
|
114
|
+
</Badge>
|
|
115
|
+
</div>
|
|
116
|
+
<div class='col-span-2'>
|
|
117
|
+
<p class='text-base-content/50'>{m.status_token_label()}</p>
|
|
118
|
+
<p class='font-medium'>{nativeTokenStorage ? m.status_token_native() : m.status_token_memory()}</p>
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
</Card>
|
|
122
|
+
</section>
|
|
123
|
+
{:else if activeTab === 'tasks'}
|
|
124
|
+
<section class='space-y-4 p-4 pb-6'>
|
|
125
|
+
<Card title={m.tasks_title()} shadow='sm'>
|
|
126
|
+
<div class='space-y-3'>
|
|
127
|
+
{#each [m.tasks_sync(), m.tasks_polish(), m.tasks_release()] as task (task)}
|
|
128
|
+
<div class='bg-base-200 rounded-xl flex items-center gap-3 p-3'>
|
|
129
|
+
<span class='icon-[tabler--circle-check] text-success text-xl'></span>
|
|
130
|
+
<span class='text-sm font-medium'>{task}</span>
|
|
131
|
+
</div>
|
|
132
|
+
{/each}
|
|
133
|
+
</div>
|
|
134
|
+
</Card>
|
|
135
|
+
</section>
|
|
136
|
+
{:else}
|
|
137
|
+
<section class='space-y-4 p-4 pb-6'>
|
|
138
|
+
<Card title={m.profile_title()} shadow='sm'>
|
|
139
|
+
<div class='space-y-3 text-sm'>
|
|
140
|
+
<div class='bg-base-200 rounded-xl p-3'>{m.profile_language()}</div>
|
|
141
|
+
<div class='bg-base-200 rounded-xl p-3'>{m.profile_theme()}</div>
|
|
142
|
+
<div class='bg-base-200 rounded-xl p-3'>{m.profile_secure()}</div>
|
|
143
|
+
</div>
|
|
144
|
+
</Card>
|
|
145
|
+
</section>
|
|
146
|
+
{/if}
|
|
147
|
+
</main>
|
|
148
|
+
|
|
149
|
+
<BottomNav
|
|
150
|
+
items={navItems}
|
|
151
|
+
active={activeTab}
|
|
152
|
+
onchange={handleTabChange}
|
|
153
|
+
safeArea
|
|
154
|
+
centered
|
|
155
|
+
maxWidth='lg'
|
|
156
|
+
class='border-base-content/8 shadow-[0_-12px_32px_rgba(15,23,42,0.08)]'
|
|
157
|
+
/>
|
|
158
|
+
</div>
|
|
159
|
+
</div>
|
|
160
|
+
{/if}
|
|
161
|
+
|
|
162
|
+
<ToastContainer />
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* {{projectName}} — API 客户端初始化。
|
|
3
|
+
* Web 预览仅使用内存 TokenStore;原生端使用 Capacitor 安全存储。
|
|
4
|
+
*/
|
|
5
|
+
import { apiClient } from '@h-ai/api-client'
|
|
6
|
+
import { createCapacitorTokenStorage } from '@h-ai/capacitor'
|
|
7
|
+
|
|
8
|
+
const DEFAULT_API_BASE = 'http://localhost:3000/api/v1'
|
|
9
|
+
|
|
10
|
+
let initialized = false
|
|
11
|
+
|
|
12
|
+
export function resolveApiBase(): string {
|
|
13
|
+
return import.meta.env.PUBLIC_API_BASE ?? DEFAULT_API_BASE
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export async function usesNativeTokenStorage(): Promise<boolean> {
|
|
17
|
+
const { Capacitor } = await import('@capacitor/core')
|
|
18
|
+
return Capacitor.isNativePlatform()
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function createTokenStorage() {
|
|
22
|
+
if (await usesNativeTokenStorage())
|
|
23
|
+
return createCapacitorTokenStorage()
|
|
24
|
+
|
|
25
|
+
return apiClient.tokenStorage.memory()
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export async function initApi(): Promise<void> {
|
|
29
|
+
if (initialized)
|
|
30
|
+
return
|
|
31
|
+
|
|
32
|
+
const initResult = await apiClient.init({
|
|
33
|
+
baseUrl: resolveApiBase(),
|
|
34
|
+
auth: {
|
|
35
|
+
storage: await createTokenStorage(),
|
|
36
|
+
refreshPath: '/auth/refresh',
|
|
37
|
+
},
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
if (!initResult.success)
|
|
41
|
+
throw new Error(initResult.error.message)
|
|
42
|
+
|
|
43
|
+
initialized = true
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export async function closeApi(): Promise<void> {
|
|
47
|
+
if (!initialized)
|
|
48
|
+
return
|
|
49
|
+
|
|
50
|
+
await apiClient.close()
|
|
51
|
+
initialized = false
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { apiClient }
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Capacitor
|
|
3
|
-
*
|
|
4
|
-
* 在应用启动时调用,配置状态栏等原生能力。
|
|
2
|
+
* Capacitor 初始化。
|
|
5
3
|
*/
|
|
6
4
|
import { capacitor } from '@h-ai/capacitor'
|
|
7
5
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
export async function isNativeApp(): Promise<boolean> {
|
|
7
|
+
return capacitor.isNative()
|
|
8
|
+
}
|
|
9
|
+
|
|
11
10
|
export async function initCapacitor(): Promise<void> {
|
|
12
11
|
await capacitor.init()
|
|
13
12
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { mount } from 'svelte'
|
|
2
|
+
import App from './App.svelte'
|
|
3
|
+
import './app.css'
|
|
4
|
+
|
|
5
|
+
const target = document.getElementById('app')
|
|
6
|
+
if (!target)
|
|
7
|
+
throw new Error('Root element #app not found')
|
|
8
|
+
|
|
9
|
+
const app = mount(App, { target })
|
|
10
|
+
|
|
11
|
+
export default app
|
|
@@ -9,8 +9,11 @@ import antfu from '@antfu/eslint-config'
|
|
|
9
9
|
export default antfu({
|
|
10
10
|
formatters: true,
|
|
11
11
|
ignores: [
|
|
12
|
+
{{#unless isSvelteOnlyApp}}
|
|
12
13
|
'**/.svelte-kit/**',
|
|
14
|
+
{{/unless}}
|
|
13
15
|
'**/build/**',
|
|
16
|
+
'**/dist/**',
|
|
14
17
|
'**/*.d.ts',
|
|
15
18
|
'**/project.inlang/**',
|
|
16
19
|
'**/paraglide/**',
|
|
@@ -29,4 +32,4 @@ export default antfu({
|
|
|
29
32
|
'no-console': 'error',
|
|
30
33
|
'ts/no-explicit-any': 'error',
|
|
31
34
|
},
|
|
32
|
-
})
|
|
35
|
+
})
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "{{projectName}}",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.21",
|
|
4
4
|
"private": true,
|
|
5
|
-
"description": "{{#if_eq appType 'admin'}}Enterprise management system built with hai Agent Framework{{/if_eq}}{{#if_eq appType 'website'}}Enterprise website built with hai Agent Framework{{/if_eq}}{{#if_eq appType 'h5'}}Mobile H5 app built with hai Agent Framework{{/if_eq}}{{#if_eq appType 'api'}}REST API service built with hai Agent Framework{{/if_eq}}{{#if_eq appType '
|
|
6
|
-
"keywords": ["hai", "sveltekit", "svelte5", "{{appType}}"],
|
|
5
|
+
"description": "{{#if_eq appType 'admin'}}Enterprise management system built with hai Agent Framework{{/if_eq}}{{#if_eq appType 'website'}}Enterprise website built with hai Agent Framework{{/if_eq}}{{#if_eq appType 'h5'}}Mobile H5 app built with hai Agent Framework{{/if_eq}}{{#if_eq appType 'api'}}REST API service built with hai Agent Framework{{/if_eq}}{{#if_eq appType 'mobile-app'}}Mobile app built with hai Agent Framework{{/if_eq}}",
|
|
6
|
+
"keywords": ["hai", {{#unless isSvelteOnlyApp}}"sveltekit", {{/unless}}"svelte5", "{{appType}}"],
|
|
7
7
|
"license": "Apache-2.0",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"scripts": {
|
|
@@ -11,54 +11,72 @@
|
|
|
11
11
|
"paraglide:compile": "paraglide-js compile --project ./project.inlang --outdir ./src/lib/paraglide",
|
|
12
12
|
{{/if}}
|
|
13
13
|
"dev": "vite dev",
|
|
14
|
-
"build": "vite build",
|
|
14
|
+
"build": "{{#if hasI18n}}pnpm paraglide:compile && {{/if}}vite build",
|
|
15
15
|
"preview": "vite preview",
|
|
16
|
-
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
17
|
-
"typecheck": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
16
|
+
"check": "{{#if hasI18n}}pnpm paraglide:compile && {{/if}}{{#if isSvelteOnlyApp}}svelte-check --tsconfig ./tsconfig.json{{else}}svelte-kit sync && svelte-check --tsconfig ./tsconfig.json{{/if}}",
|
|
17
|
+
"typecheck": "{{#if hasI18n}}pnpm paraglide:compile && {{/if}}{{#if isSvelteOnlyApp}}svelte-check --tsconfig ./tsconfig.json{{else}}svelte-kit sync && svelte-check --tsconfig ./tsconfig.json{{/if}}",
|
|
18
18
|
"lint": "eslint .",
|
|
19
|
-
"test": "vitest run",
|
|
19
|
+
"test": "{{#if hasI18n}}pnpm paraglide:compile && {{/if}}vitest run",
|
|
20
20
|
"test:watch": "vitest",
|
|
21
21
|
"test:e2e": "playwright test",
|
|
22
|
-
"clean": "rimraf .svelte-kit build .turbo"
|
|
22
|
+
"clean": "{{#if isSvelteOnlyApp}}rimraf dist build android ios .turbo src/lib/paraglide{{else}}rimraf .svelte-kit build .turbo{{/if}}"{{#if isCapacitorApp}},
|
|
23
|
+
"cap:add:android": "cap add android",
|
|
24
|
+
"cap:add:ios": "cap add ios",
|
|
25
|
+
"cap:sync": "pnpm build && cap sync",
|
|
26
|
+
"cap:sync:android": "pnpm build && cap sync android",
|
|
27
|
+
"cap:sync:ios": "pnpm build && cap sync ios",
|
|
28
|
+
"cap:android": "cap open android",
|
|
29
|
+
"cap:ios": "cap open ios",
|
|
30
|
+
"cap:run:android": "cap run android",
|
|
31
|
+
"cap:run:ios": "cap run ios",
|
|
32
|
+
"cap:build:android:debug": "pnpm build && cap sync android && cd android && gradlew.bat assembleDebug",
|
|
33
|
+
"cap:build:android:release": "pnpm build && cap sync android && cap build android --androidreleasetype APK",
|
|
34
|
+
"cap:build:ios": "pnpm build && cap sync ios && cap build ios"{{/if}}
|
|
23
35
|
},
|
|
24
36
|
"dependencies": {
|
|
25
|
-
|
|
26
|
-
"@h-ai/
|
|
27
|
-
"@h-ai/
|
|
28
|
-
"@h-ai/
|
|
29
|
-
|
|
30
|
-
"@h-ai/
|
|
31
|
-
"@h-ai/
|
|
32
|
-
"@h-ai/
|
|
33
|
-
"@h-ai/
|
|
34
|
-
"@h-ai/
|
|
35
|
-
"@h-ai/
|
|
36
|
-
"@h-ai/
|
|
37
|
-
"@h-ai/
|
|
38
|
-
"@h-ai/
|
|
39
|
-
"@h-ai/
|
|
40
|
-
"@h-ai/
|
|
41
|
-
"@h-ai/
|
|
42
|
-
"@h-ai/
|
|
43
|
-
"@h-ai/
|
|
44
|
-
"@h-ai/
|
|
37
|
+
{{#if isSvelteOnlyApp}}
|
|
38
|
+
"@h-ai/api-client": "{{haiPackageSpecifier}}",
|
|
39
|
+
"@h-ai/capacitor": "{{haiPackageSpecifier}}",
|
|
40
|
+
"@h-ai/ui": "{{haiPackageSpecifier}}"
|
|
41
|
+
{{else}}
|
|
42
|
+
"@h-ai/core": "{{haiPackageSpecifier}}",
|
|
43
|
+
"@h-ai/kit": "{{haiPackageSpecifier}}"{{#if hasUi}},
|
|
44
|
+
"@h-ai/ui": "{{haiPackageSpecifier}}"{{/if}}{{#if features.db}},
|
|
45
|
+
"@h-ai/reldb": "{{haiPackageSpecifier}}"{{/if}}{{#if features.cache}},
|
|
46
|
+
"@h-ai/cache": "{{haiPackageSpecifier}}"{{/if}}{{#if features.iam}},
|
|
47
|
+
"@h-ai/iam": "{{haiPackageSpecifier}}"{{/if}}{{#if features.crypto}},
|
|
48
|
+
"@h-ai/crypto": "{{haiPackageSpecifier}}"{{/if}}{{#if features.storage}},
|
|
49
|
+
"@h-ai/storage": "{{haiPackageSpecifier}}"{{/if}}{{#if features.ai}},
|
|
50
|
+
"@h-ai/ai": "{{haiPackageSpecifier}}"{{/if}}{{#if features.audit}},
|
|
51
|
+
"@h-ai/audit": "{{haiPackageSpecifier}}"{{/if}}{{#if features.reach}},
|
|
52
|
+
"@h-ai/reach": "{{haiPackageSpecifier}}"{{/if}}{{#if features.payment}},
|
|
53
|
+
"@h-ai/payment": "{{haiPackageSpecifier}}"{{/if}}{{#if features.vecdb}},
|
|
54
|
+
"@h-ai/vecdb": "{{haiPackageSpecifier}}"{{/if}}{{#if features.datapipe}},
|
|
55
|
+
"@h-ai/datapipe": "{{haiPackageSpecifier}}"{{/if}}{{#if features.scheduler}},
|
|
56
|
+
"@h-ai/scheduler": "{{haiPackageSpecifier}}"{{/if}}{{#if features.deploy}},
|
|
57
|
+
"@h-ai/deploy": "{{haiPackageSpecifier}}"{{/if}}{{#if features.api-client}},
|
|
58
|
+
"@h-ai/api-client": "{{haiPackageSpecifier}}"{{/if}}{{#if features.capacitor}},
|
|
59
|
+
"@h-ai/capacitor": "{{haiPackageSpecifier}}"{{/if}}{{#if isCapacitorApp}}{{#unless features.api-client}},
|
|
60
|
+
"@h-ai/api-client": "{{haiPackageSpecifier}}"{{/unless}}{{#unless features.capacitor}},
|
|
61
|
+
"@h-ai/capacitor": "{{haiPackageSpecifier}}"{{/unless}}{{/if}},
|
|
45
62
|
"zod": "^4.4.3"
|
|
63
|
+
{{/if}}
|
|
46
64
|
},
|
|
47
65
|
"devDependencies": {
|
|
48
66
|
"@antfu/eslint-config": "^9.0.0",
|
|
49
67
|
"@playwright/test": "^1.60.0",
|
|
50
68
|
{{#if isCapacitorApp}}
|
|
51
|
-
|
|
69
|
+
"@aparajita/capacitor-secure-storage": "^8.0.0",
|
|
52
70
|
"@capacitor/app": "^8.0.1",
|
|
53
|
-
"@capacitor/camera": "^8.0.
|
|
71
|
+
"@capacitor/camera": "^8.0.1",
|
|
54
72
|
"@capacitor/cli": "^8.3.4",
|
|
55
73
|
"@capacitor/core": "^8.3.4",
|
|
56
74
|
"@capacitor/android": "^8.3.4",
|
|
57
75
|
"@capacitor/device": "^8.0.1",
|
|
76
|
+
"@capacitor/ios": "^8.3.4",
|
|
58
77
|
"@capacitor/preferences": "^8.0.1",
|
|
59
|
-
"@capacitor/push-notifications": "^8.0.
|
|
78
|
+
"@capacitor/push-notifications": "^8.0.1",
|
|
60
79
|
"@capacitor/status-bar": "^8.0.1",
|
|
61
|
-
"@sveltejs/adapter-static": "^3.0.10",
|
|
62
80
|
{{else}}
|
|
63
81
|
{{#if_eq appType 'api'}}
|
|
64
82
|
"@sveltejs/adapter-node": "^5.5.4",
|
|
@@ -66,13 +84,14 @@
|
|
|
66
84
|
"@sveltejs/adapter-auto": "^7.0.1",
|
|
67
85
|
{{/if_eq}}
|
|
68
86
|
{{/if}}
|
|
87
|
+
{{#unless isSvelteOnlyApp}}
|
|
69
88
|
"@sveltejs/kit": "^2.61.1",
|
|
89
|
+
{{/unless}}
|
|
70
90
|
"@sveltejs/vite-plugin-svelte": "^7.1.2",
|
|
71
91
|
"@types/node": "^25.9.1",
|
|
72
92
|
"eslint": "^10.4.0",
|
|
73
93
|
"eslint-plugin-format": "^2.0.1",
|
|
74
94
|
"eslint-plugin-svelte": "^3.17.1",
|
|
75
|
-
"pino-pretty": "^13.1.3",
|
|
76
95
|
"rimraf": "^6.1.3",
|
|
77
96
|
"svelte": "^5.55.9",
|
|
78
97
|
"svelte-check": "^4.4.8",
|
|
@@ -1,7 +1,34 @@
|
|
|
1
1
|
import process from 'node:process'
|
|
2
2
|
import { defineConfig } from '@playwright/test'
|
|
3
3
|
|
|
4
|
-
const
|
|
4
|
+
const DEFAULT_BASE_URL = 'http://localhost:4173'
|
|
5
|
+
const baseURL = process.env.BASE_URL || DEFAULT_BASE_URL
|
|
6
|
+
const previewHost = resolveHostFromBaseUrl(baseURL, 'localhost')
|
|
7
|
+
const previewPort = resolvePortFromBaseUrl(baseURL, '4173')
|
|
8
|
+
|
|
9
|
+
function resolveHostFromBaseUrl(urlString: string, fallbackHost: string): string {
|
|
10
|
+
try {
|
|
11
|
+
const url = new URL(urlString)
|
|
12
|
+
return url.hostname || fallbackHost
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return fallbackHost
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function resolvePortFromBaseUrl(urlString: string, fallbackPort: string): string {
|
|
20
|
+
try {
|
|
21
|
+
const url = new URL(urlString)
|
|
22
|
+
if (url.port) {
|
|
23
|
+
return url.port
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return url.protocol === 'https:' ? '443' : '80'
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return fallbackPort
|
|
30
|
+
}
|
|
31
|
+
}
|
|
5
32
|
|
|
6
33
|
/**
|
|
7
34
|
* Playwright E2E 测试配置
|
|
@@ -23,8 +50,8 @@ export default defineConfig({
|
|
|
23
50
|
},
|
|
24
51
|
|
|
25
52
|
webServer: {
|
|
26
|
-
command:
|
|
27
|
-
env: { HAI_E2E: '1' },
|
|
53
|
+
command: `pnpm build && pnpm preview --host ${previewHost} --port ${previewPort} --strictPort`,
|
|
54
|
+
env: { HAI_E2E: '1', BASE_URL: baseURL },
|
|
28
55
|
url: baseURL,
|
|
29
56
|
reuseExistingServer: false,
|
|
30
57
|
timeout: 180_000,
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Svelte 配置
|
|
3
3
|
*/
|
|
4
|
+
{{#unless isSvelteOnlyApp}}
|
|
4
5
|
import process from 'node:process'
|
|
6
|
+
{{/unless}}
|
|
5
7
|
{{#if hasUi}}
|
|
6
8
|
import { autoImportHaiUi } from '@h-ai/ui/auto-import'
|
|
7
9
|
{{/if}}
|
|
10
|
+
{{#unless isSvelteOnlyApp}}
|
|
8
11
|
{{#if isCapacitorApp}}
|
|
9
12
|
import adapter from '@sveltejs/adapter-static'
|
|
10
13
|
{{else}}
|
|
@@ -14,8 +17,46 @@ import adapter from '@sveltejs/adapter-node'
|
|
|
14
17
|
import adapter from '@sveltejs/adapter-auto'
|
|
15
18
|
{{/if_eq}}
|
|
16
19
|
{{/if}}
|
|
20
|
+
{{/unless}}
|
|
17
21
|
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
|
|
18
22
|
|
|
23
|
+
{{#if isSvelteOnlyApp}}
|
|
24
|
+
/** @type {import('@sveltejs/vite-plugin-svelte').SvelteConfig} */
|
|
25
|
+
const config = {
|
|
26
|
+
preprocess: [{{#if hasUi}}autoImportHaiUi(), {{/if}}vitePreprocess()],
|
|
27
|
+
compilerOptions: {
|
|
28
|
+
runes: true,
|
|
29
|
+
},
|
|
30
|
+
}
|
|
31
|
+
{{else}}
|
|
32
|
+
const DEFAULT_E2E_ORIGINS = ['http://localhost:4173', 'http://127.0.0.1:4173']
|
|
33
|
+
|
|
34
|
+
function resolveTrustedOrigins() {
|
|
35
|
+
if (process.env.HAI_E2E !== '1')
|
|
36
|
+
return []
|
|
37
|
+
|
|
38
|
+
const rawBaseUrl = process.env.BASE_URL ?? DEFAULT_E2E_ORIGINS[0]
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
const url = new URL(rawBaseUrl)
|
|
42
|
+
const origins = new Set([url.origin])
|
|
43
|
+
|
|
44
|
+
if (url.hostname === 'localhost') {
|
|
45
|
+
url.hostname = '127.0.0.1'
|
|
46
|
+
origins.add(url.origin)
|
|
47
|
+
}
|
|
48
|
+
else if (url.hostname === '127.0.0.1') {
|
|
49
|
+
url.hostname = 'localhost'
|
|
50
|
+
origins.add(url.origin)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return [...origins]
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return DEFAULT_E2E_ORIGINS
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
19
60
|
/** @type {import('@sveltejs/kit').Config} */
|
|
20
61
|
const config = {
|
|
21
62
|
preprocess: [{{#if hasUi}}autoImportHaiUi(), {{/if}}vitePreprocess()],
|
|
@@ -33,9 +74,7 @@ const config = {
|
|
|
33
74
|
adapter: adapter(),
|
|
34
75
|
{{/if}}
|
|
35
76
|
csrf: {
|
|
36
|
-
trustedOrigins:
|
|
37
|
-
? ['http://localhost:4173', 'http://127.0.0.1:4173']
|
|
38
|
-
: [],
|
|
77
|
+
trustedOrigins: resolveTrustedOrigins(),
|
|
39
78
|
},
|
|
40
79
|
alias: {
|
|
41
80
|
$components: './src/lib/components',
|
|
@@ -44,5 +83,6 @@ const config = {
|
|
|
44
83
|
},
|
|
45
84
|
},
|
|
46
85
|
}
|
|
86
|
+
{{/if}}
|
|
47
87
|
|
|
48
88
|
export default config
|
|
@@ -20,10 +20,17 @@ describe('generated scaffold', () => {
|
|
|
20
20
|
expect(pkg.scripts['test:e2e']).toBeDefined()
|
|
21
21
|
})
|
|
22
22
|
|
|
23
|
+
{{#if isSvelteOnlyApp}}
|
|
24
|
+
it('renders the Vite app shell entry', async () => {
|
|
25
|
+
const indexHtml = await readFile(join(rootDir, 'index.html'), 'utf-8')
|
|
26
|
+
expect(indexHtml).toContain('<div id="app"></div>')
|
|
27
|
+
})
|
|
28
|
+
{{else}}
|
|
23
29
|
it('renders the app shell locale marker', async () => {
|
|
24
30
|
const appHtml = await readFile(join(rootDir, 'src/app.html'), 'utf-8')
|
|
25
31
|
expect(appHtml).toContain('lang="{{#if hasI18n}}{{#if isCapacitorApp}}{{defaultLocale}}{{else}}%lang%{{/if}}{{else}}{{defaultLocale}}{{/if}}"')
|
|
26
32
|
})
|
|
33
|
+
{{/if}}
|
|
27
34
|
{{#unless isCapacitorApp}}
|
|
28
35
|
|
|
29
36
|
it('ships an application config loaded at startup', async () => {
|