diff --git a/.env.example b/.env.example
index d5a1612..c3e8201 100644
--- a/.env.example
+++ b/.env.example
@@ -1,7 +1,3 @@
-# Apple Development Team ID
-# 用于 iOS 应用签名和打包
-APPLE_DEVELOPMENT_TEAM=
-
# Microsoft Clarity:复用 Cook 项目;显式留空可关闭统计
# 静态部署须在构建前设置;分叉项目请使用自己的项目 ID 和域名
NUXT_PUBLIC_CLARITY_PROJECT_ID=ks1ebw03i5
diff --git a/CLAUDE.md b/CLAUDE.md
index fbdc1ef..69c9338 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
## Project Overview
-Cook (食用手册) is a Chinese recipe web/mobile app for finding recipes based on available ingredients. Built with Nuxt 4 (Vue 3, CSR-only), Ionic UI, and Capacitor for native iOS/Android apps. The UI and content are in Chinese.
+Cook (食用手册) is a Chinese recipe web app for finding recipes based on available ingredients. Built with Nuxt 4 (Vue 3, CSR-only) and Ionic UI, shipped as a Web app only (browser + YunLeFun container). The UI and content are in Chinese.
## Common Commands
@@ -14,7 +14,7 @@ pnpm convert # Convert CSV recipe data → JSON (required before fi
pnpm validate # Validate recipe.csv (ids, ingredient/tool dictionary, values, video ids)
pnpm feedback:pull # Pull in-app feedback + search signals from CloudBase (needs .env)
pnpm eval:search # Evaluate recommendation ranking against real search signals
-pnpm fixtures # Regenerate shared Web/iOS recommendation fixtures (after data, alias or ranking changes)
+pnpm fixtures # Regenerate shared recommendation fixtures (after data, alias or ranking changes)
pnpm dev # Dev server on http://localhost:3333
pnpm lint # ESLint check (uses @antfu/eslint-config flat config)
pnpm lint --fix # Auto-fix lint issues
@@ -24,15 +24,6 @@ pnpm test -- --run # Run tests once without watch
pnpm build # Full production build (convert + nuxt generate)
```
-### Mobile Development
-
-```bash
-pnpm dev:ios # iOS with live reload (cap run ios -l)
-pnpm dev:android # Android dev
-pnpm ios # Open in Xcode
-pnpm android # Open in Android Studio
-```
-
## Architecture
### Data Pipeline
@@ -43,14 +34,14 @@ Project decisions are recorded in `docs/decisions/` — read the relevant one be
### Monorepo Structure (pnpm workspaces)
-Layout follows `docs/decisions/0003-native-ios-monorepo.md`; the plan is in `docs/dev/ios-roadmap.md`.
+Layout follows `docs/decisions/0004-web-only.md`.
-- **apps/web** — Nuxt app (main application). Root scripts (`pnpm dev`, `pnpm build`, `pnpm typecheck`) proxy to it; `pnpm build` copies `apps/web/dist` to the root `dist/` that deploy targets and Capacitor read
-- **packages/data** — Data shared by Web and iOS: recipe CSV sources and the JSON generated from them (imported in the web app as `@cook/data/*`), the food dictionary (`food.json`), pantry defaults (`pantry.json`), ingredient aliases (`aliases.json`), and recommendation fixtures (`fixtures/recommend.json`, regenerate with `pnpm fixtures`)
-- **packages/cook** — Types, recommendation/search logic (the TS core the iOS CookCore mirrors), and the CLI (`convert`, `search`)
+- **apps/web** — Nuxt app (main application). Root scripts (`pnpm dev`, `pnpm build`, `pnpm typecheck`) proxy to it; `pnpm build` copies `apps/web/dist` to the root `dist/` that deploy targets read
+- **packages/data** — Recipe CSV sources and the JSON generated from them (imported in the web app as `@cook/data/*`), the food dictionary (`food.json`), pantry defaults (`pantry.json`), ingredient aliases (`aliases.json`), and recommendation fixtures (`fixtures/recommend.json`, regenerate with `pnpm fixtures`)
+- **packages/cook** — Types, recommendation/search logic, and the CLI (`convert`, `search`)
- **docs** — VitePress documentation site
- **scripts** — Build/utility scripts
-- **Root** — Workspace tooling, tests (`test/`), Capacitor shell (`capacitor.config.ts`, `ios/`, `android/`), `cloudfunctions/`
+- **Root** — Workspace tooling, tests (`test/`), `cloudfunctions/`
### App Source (`apps/web/app/`)
@@ -84,13 +75,14 @@ pnpm test -- test/recipe.test.ts
## Code Style
-Uses `@antfu/eslint-config` (flat config) with UnoCSS and formatters enabled. Pre-commit hook runs `lint-staged` via `simple-git-hooks`. Ignored paths include `packages/data/**/*.json`, `ios/`, `android/`, `dist/`.
+Uses `@antfu/eslint-config` (flat config) with UnoCSS and formatters enabled. Pre-commit hook runs `lint-staged` via `simple-git-hooks`. Ignored paths include `packages/data/**/*.json`, `dist/`.
## Environment Variables
See `.env.example`:
-- `APPLE_DEVELOPMENT_TEAM` — iOS signing
+- `NUXT_PUBLIC_CLARITY_PROJECT_ID` / `NUXT_PUBLIC_CLARITY_DOMAINS` — Microsoft Clarity statistics (leave the project ID empty to disable)
+- `COOK_FEEDBACK_URL` / `COOK_FEEDBACK_TOKEN` — feedback export endpoint and its token (used by `pnpm feedback:pull`)
## Node/Package Manager
diff --git a/README.md b/README.md
index c2571b2..19db653 100644
--- a/README.md
+++ b/README.md
@@ -37,9 +37,8 @@
### Features
-~~本项目支持 PWA,使用浏览器打开时,可将其添加到主屏幕以获得近原生 APP 的体验。~~
-
-我们正在开发新的 APP 版本,敬请期待。
+本项目只维护 Web 版本(浏览器 + 云乐坊 App 容器)。原生 iOS / Android 应用已随
+[0004 只保留 Web](/docs/decisions/0004-web-only) 移除,不再提供安装包。
## 开发
@@ -73,10 +72,6 @@ pnpm search --stuff "鸡蛋,番茄"
更多 CLI 使用说明请查看 [Cook CLI 文档](https://cook.yunyoujun.cn/docs/dev/cli)。
-### 开发 APP
-
-> [Local Development](https://ionic.nuxtjs.org/cookbook/local-development)
-
## 部署
### 网站统计
diff --git a/android/.gitignore b/android/.gitignore
deleted file mode 100644
index 2fdf46a..0000000
--- a/android/.gitignore
+++ /dev/null
@@ -1,102 +0,0 @@
-# Using Android gitignore template: https://github.com/github/gitignore/blob/HEAD/Android.gitignore
-
-# Built application files
-*.apk
-*.aar
-*.ap_
-*.aab
-
-# Files for the ART/Dalvik VM
-*.dex
-
-# Java class files
-*.class
-
-# Generated files
-bin/
-gen/
-out/
-# Uncomment the following line in case you need and you don't have the release build type files in your app
-# release/
-
-# Gradle files
-.gradle/
-build/
-
-# Local configuration file (sdk path, etc)
-local.properties
-
-# Proguard folder generated by Eclipse
-proguard/
-
-# Log Files
-*.log
-
-# Android Studio Navigation editor temp files
-.navigation/
-
-# Android Studio captures folder
-captures/
-
-# IntelliJ
-*.iml
-.idea/workspace.xml
-.idea/tasks.xml
-.idea/gradle.xml
-.idea/assetWizardSettings.xml
-.idea/dictionaries
-.idea/libraries
-# Android Studio 3 in .gitignore file.
-.idea/caches
-.idea/modules.xml
-# Comment next line if keeping position of elements in Navigation Editor is relevant for you
-.idea/navEditor.xml
-
-# Keystore files
-*.jks
-*.keystore
-key.properties
-keystore.properties
-
-# External native build folder generated in Android Studio 2.2 and later
-.externalNativeBuild
-.cxx/
-
-# Google Services (e.g. APIs or Firebase)
-# google-services.json
-
-# Freeline
-freeline.py
-freeline/
-freeline_project_description.json
-
-# fastlane
-fastlane/report.xml
-fastlane/Preview.html
-fastlane/screenshots
-fastlane/test_output
-fastlane/readme.md
-
-# Version control
-vcs.xml
-
-# lint
-lint/intermediates/
-lint/generated/
-lint/outputs/
-lint/tmp/
-# lint/reports/
-
-# Android Profiling
-*.hprof
-
-# Cordova plugins for Capacitor
-capacitor-cordova-android-plugins
-
-# Copied web assets
-app/src/main/assets/public
-
-# Generated Config files
-app/src/main/assets/capacitor.config.json
-app/src/main/assets/capacitor.plugins.json
-app/src/main/res/xml/config.xml
diff --git a/android/app/.gitignore b/android/app/.gitignore
deleted file mode 100644
index 043df80..0000000
--- a/android/app/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-/build/*
-!/build/.npmkeep
diff --git a/android/app/build.gradle b/android/app/build.gradle
deleted file mode 100644
index c9be30a..0000000
--- a/android/app/build.gradle
+++ /dev/null
@@ -1,54 +0,0 @@
-apply plugin: 'com.android.application'
-
-android {
- namespace = "cn.yunyoujun.cook"
- compileSdk = rootProject.ext.compileSdkVersion
- defaultConfig {
- applicationId = "cn.yunyoujun.cook"
- minSdk = rootProject.ext.minSdkVersion
- targetSdk = rootProject.ext.targetSdkVersion
- versionCode = 2
- versionName = "1.0.1"
- testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
- aaptOptions {
- // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
- // Default: https://android.googlesource.com/platform/frameworks/base/+/282e181b58cf72b6ca770dc7ca5f91f135444502/tools/aapt/AaptAssets.cpp#61
- ignoreAssetsPattern = '!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~'
- }
- }
- buildTypes {
- release {
- minifyEnabled = false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- }
- }
-}
-
-repositories {
- flatDir{
- dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs'
- }
-}
-
-dependencies {
- implementation fileTree(include: ['*.jar'], dir: 'libs')
- implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
- implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion"
- implementation "androidx.core:core-splashscreen:$coreSplashScreenVersion"
- implementation project(':capacitor-android')
- testImplementation "junit:junit:$junitVersion"
- androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
- androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
- implementation project(':capacitor-cordova-android-plugins')
-}
-
-apply from: 'capacitor.build.gradle'
-
-try {
- def servicesJSON = file('google-services.json')
- if (servicesJSON.text) {
- apply plugin: 'com.google.gms.google-services'
- }
-} catch(Exception e) {
- logger.info("google-services.json not found, google-services plugin not applied. Push Notifications won't work")
-}
diff --git a/android/app/capacitor.build.gradle b/android/app/capacitor.build.gradle
deleted file mode 100644
index e5ade1d..0000000
--- a/android/app/capacitor.build.gradle
+++ /dev/null
@@ -1,25 +0,0 @@
-// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN
-
-android {
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_21
- targetCompatibility JavaVersion.VERSION_21
- }
-}
-
-apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
-dependencies {
- implementation project(':capacitor-app')
- implementation project(':capacitor-browser')
- implementation project(':capacitor-dialog')
- implementation project(':capacitor-haptics')
- implementation project(':capacitor-keyboard')
- implementation project(':capacitor-preferences')
- implementation project(':capacitor-status-bar')
-
-}
-
-
-if (hasProperty('postBuildExtras')) {
- postBuildExtras()
-}
diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro
deleted file mode 100644
index f1b4245..0000000
--- a/android/app/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
diff --git a/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java b/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java
deleted file mode 100644
index f2c2217..0000000
--- a/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.getcapacitor.myapp;
-
-import static org.junit.Assert.*;
-
-import android.content.Context;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.platform.app.InstrumentationRegistry;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Instrumented test, which will execute on an Android device.
- *
- * @see Testing documentation
- */
-@RunWith(AndroidJUnit4.class)
-public class ExampleInstrumentedTest {
-
- @Test
- public void useAppContext() throws Exception {
- // Context of the app under test.
- Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
-
- assertEquals("com.getcapacitor.app", appContext.getPackageName());
- }
-}
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
deleted file mode 100644
index 0a3549e..0000000
--- a/android/app/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/android/app/src/main/java/cn/yunyoujun/cook/MainActivity.java b/android/app/src/main/java/cn/yunyoujun/cook/MainActivity.java
deleted file mode 100644
index d5895da..0000000
--- a/android/app/src/main/java/cn/yunyoujun/cook/MainActivity.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package cn.yunyoujun.cook;
-
-import com.getcapacitor.BridgeActivity;
-
-public class MainActivity extends BridgeActivity {}
diff --git a/android/app/src/main/res/drawable-land-hdpi/splash.png b/android/app/src/main/res/drawable-land-hdpi/splash.png
deleted file mode 100644
index e31573b..0000000
Binary files a/android/app/src/main/res/drawable-land-hdpi/splash.png and /dev/null differ
diff --git a/android/app/src/main/res/drawable-land-mdpi/splash.png b/android/app/src/main/res/drawable-land-mdpi/splash.png
deleted file mode 100644
index f7a6492..0000000
Binary files a/android/app/src/main/res/drawable-land-mdpi/splash.png and /dev/null differ
diff --git a/android/app/src/main/res/drawable-land-xhdpi/splash.png b/android/app/src/main/res/drawable-land-xhdpi/splash.png
deleted file mode 100644
index 8077255..0000000
Binary files a/android/app/src/main/res/drawable-land-xhdpi/splash.png and /dev/null differ
diff --git a/android/app/src/main/res/drawable-land-xxhdpi/splash.png b/android/app/src/main/res/drawable-land-xxhdpi/splash.png
deleted file mode 100644
index 14c6c8f..0000000
Binary files a/android/app/src/main/res/drawable-land-xxhdpi/splash.png and /dev/null differ
diff --git a/android/app/src/main/res/drawable-land-xxxhdpi/splash.png b/android/app/src/main/res/drawable-land-xxxhdpi/splash.png
deleted file mode 100644
index 244ca25..0000000
Binary files a/android/app/src/main/res/drawable-land-xxxhdpi/splash.png and /dev/null differ
diff --git a/android/app/src/main/res/drawable-port-hdpi/splash.png b/android/app/src/main/res/drawable-port-hdpi/splash.png
deleted file mode 100644
index 74faaa5..0000000
Binary files a/android/app/src/main/res/drawable-port-hdpi/splash.png and /dev/null differ
diff --git a/android/app/src/main/res/drawable-port-mdpi/splash.png b/android/app/src/main/res/drawable-port-mdpi/splash.png
deleted file mode 100644
index e944f4a..0000000
Binary files a/android/app/src/main/res/drawable-port-mdpi/splash.png and /dev/null differ
diff --git a/android/app/src/main/res/drawable-port-xhdpi/splash.png b/android/app/src/main/res/drawable-port-xhdpi/splash.png
deleted file mode 100644
index 564a82f..0000000
Binary files a/android/app/src/main/res/drawable-port-xhdpi/splash.png and /dev/null differ
diff --git a/android/app/src/main/res/drawable-port-xxhdpi/splash.png b/android/app/src/main/res/drawable-port-xxhdpi/splash.png
deleted file mode 100644
index bfabe68..0000000
Binary files a/android/app/src/main/res/drawable-port-xxhdpi/splash.png and /dev/null differ
diff --git a/android/app/src/main/res/drawable-port-xxxhdpi/splash.png b/android/app/src/main/res/drawable-port-xxxhdpi/splash.png
deleted file mode 100644
index 6929071..0000000
Binary files a/android/app/src/main/res/drawable-port-xxxhdpi/splash.png and /dev/null differ
diff --git a/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
deleted file mode 100644
index c7bd21d..0000000
--- a/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/android/app/src/main/res/drawable/ic_launcher_background.xml b/android/app/src/main/res/drawable/ic_launcher_background.xml
deleted file mode 100644
index d5fccc5..0000000
--- a/android/app/src/main/res/drawable/ic_launcher_background.xml
+++ /dev/null
@@ -1,170 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/android/app/src/main/res/drawable/splash.png b/android/app/src/main/res/drawable/splash.png
deleted file mode 100644
index f7a6492..0000000
Binary files a/android/app/src/main/res/drawable/splash.png and /dev/null differ
diff --git a/android/app/src/main/res/layout/activity_main.xml b/android/app/src/main/res/layout/activity_main.xml
deleted file mode 100644
index b5ad138..0000000
--- a/android/app/src/main/res/layout/activity_main.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
deleted file mode 100644
index 036d09b..0000000
--- a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
deleted file mode 100644
index 036d09b..0000000
--- a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index cb3fd1b..0000000
Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
deleted file mode 100644
index 4ce0249..0000000
Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
deleted file mode 100644
index cb3fd1b..0000000
Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and /dev/null differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index e5af8f0..0000000
Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
deleted file mode 100644
index 56f644d..0000000
Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
deleted file mode 100644
index e5af8f0..0000000
Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and /dev/null differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index 376e845..0000000
Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
deleted file mode 100644
index 8e9d672..0000000
Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
deleted file mode 100644
index 376e845..0000000
Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index b005fd3..0000000
Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
deleted file mode 100644
index 66bbc8f..0000000
Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
deleted file mode 100644
index b005fd3..0000000
Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index 7c8c750..0000000
Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
deleted file mode 100644
index 8471f18..0000000
Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
deleted file mode 100644
index 7c8c750..0000000
Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/android/app/src/main/res/values/ic_launcher_background.xml b/android/app/src/main/res/values/ic_launcher_background.xml
deleted file mode 100644
index c31f02d..0000000
--- a/android/app/src/main/res/values/ic_launcher_background.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
- #07855F
-
diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml
deleted file mode 100644
index a254c16..0000000
--- a/android/app/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
- 食用手册
- 食用手册
- cn.yunyoujun.cook
- cn.yunyoujun.cook
-
diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml
deleted file mode 100644
index be874e5..0000000
--- a/android/app/src/main/res/values/styles.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/android/app/src/main/res/xml/file_paths.xml b/android/app/src/main/res/xml/file_paths.xml
deleted file mode 100644
index bd0c4d8..0000000
--- a/android/app/src/main/res/xml/file_paths.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java b/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java
deleted file mode 100644
index 0297327..0000000
--- a/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.getcapacitor.myapp;
-
-import static org.junit.Assert.*;
-
-import org.junit.Test;
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * @see Testing documentation
- */
-public class ExampleUnitTest {
-
- @Test
- public void addition_isCorrect() throws Exception {
- assertEquals(4, 2 + 2);
- }
-}
diff --git a/android/build.gradle b/android/build.gradle
deleted file mode 100644
index f8f0e43..0000000
--- a/android/build.gradle
+++ /dev/null
@@ -1,29 +0,0 @@
-// Top-level build file where you can add configuration options common to all sub-projects/modules.
-
-buildscript {
-
- repositories {
- google()
- mavenCentral()
- }
- dependencies {
- classpath 'com.android.tools.build:gradle:8.13.0'
- classpath 'com.google.gms:google-services:4.4.4'
-
- // NOTE: Do not place your application dependencies here; they belong
- // in the individual module build.gradle files
- }
-}
-
-apply from: "variables.gradle"
-
-allprojects {
- repositories {
- google()
- mavenCentral()
- }
-}
-
-task clean(type: Delete) {
- delete rootProject.buildDir
-}
diff --git a/android/capacitor.settings.gradle b/android/capacitor.settings.gradle
deleted file mode 100644
index 0bfba64..0000000
--- a/android/capacitor.settings.gradle
+++ /dev/null
@@ -1,24 +0,0 @@
-// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN
-include ':capacitor-android'
-project(':capacitor-android').projectDir = new File('../node_modules/.pnpm/@capacitor+android@8.5.0_@capacitor+core@8.5.0/node_modules/@capacitor/android/capacitor')
-
-include ':capacitor-app'
-project(':capacitor-app').projectDir = new File('../node_modules/.pnpm/@capacitor+app@8.1.1_@capacitor+core@8.5.0/node_modules/@capacitor/app/android')
-
-include ':capacitor-browser'
-project(':capacitor-browser').projectDir = new File('../node_modules/.pnpm/@capacitor+browser@8.0.4_@capacitor+core@8.5.0/node_modules/@capacitor/browser/android')
-
-include ':capacitor-dialog'
-project(':capacitor-dialog').projectDir = new File('../node_modules/.pnpm/@capacitor+dialog@8.0.1_@capacitor+core@8.5.0/node_modules/@capacitor/dialog/android')
-
-include ':capacitor-haptics'
-project(':capacitor-haptics').projectDir = new File('../node_modules/.pnpm/@capacitor+haptics@8.0.2_@capacitor+core@8.5.0/node_modules/@capacitor/haptics/android')
-
-include ':capacitor-keyboard'
-project(':capacitor-keyboard').projectDir = new File('../node_modules/.pnpm/@capacitor+keyboard@8.0.5_@capacitor+core@8.5.0/node_modules/@capacitor/keyboard/android')
-
-include ':capacitor-preferences'
-project(':capacitor-preferences').projectDir = new File('../node_modules/.pnpm/@capacitor+preferences@8.0.1_@capacitor+core@8.5.0/node_modules/@capacitor/preferences/android')
-
-include ':capacitor-status-bar'
-project(':capacitor-status-bar').projectDir = new File('../node_modules/.pnpm/@capacitor+status-bar@8.0.3_@capacitor+core@8.5.0/node_modules/@capacitor/status-bar/android')
diff --git a/android/gradle.properties b/android/gradle.properties
deleted file mode 100644
index 2e87c52..0000000
--- a/android/gradle.properties
+++ /dev/null
@@ -1,22 +0,0 @@
-# Project-wide Gradle settings.
-
-# IDE (e.g. Android Studio) users:
-# Gradle settings configured through the IDE *will override*
-# any settings specified in this file.
-
-# For more details on how to configure your build environment visit
-# http://www.gradle.org/docs/current/userguide/build_environment.html
-
-# Specifies the JVM arguments used for the daemon process.
-# The setting is particularly useful for tweaking memory settings.
-org.gradle.jvmargs=-Xmx1536m
-
-# When configured, Gradle will run in incubating parallel mode.
-# This option should only be used with decoupled projects. More details, visit
-# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
-# org.gradle.parallel=true
-
-# AndroidX package structure to make it clearer which packages are bundled with the
-# Android operating system, and which are packaged with your app's APK
-# https://developer.android.com/topic/libraries/support-library/androidx-rn
-android.useAndroidX=true
diff --git a/android/gradle/wrapper/gradle-wrapper.jar b/android/gradle/wrapper/gradle-wrapper.jar
deleted file mode 100644
index a4b76b9..0000000
Binary files a/android/gradle/wrapper/gradle-wrapper.jar and /dev/null differ
diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties
deleted file mode 100644
index 7705927..0000000
--- a/android/gradle/wrapper/gradle-wrapper.properties
+++ /dev/null
@@ -1,7 +0,0 @@
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip
-networkTimeout=10000
-validateDistributionUrl=true
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
diff --git a/android/gradlew b/android/gradlew
deleted file mode 100644
index f5feea6..0000000
--- a/android/gradlew
+++ /dev/null
@@ -1,252 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright © 2015-2021 the original authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# SPDX-License-Identifier: Apache-2.0
-#
-
-##############################################################################
-#
-# Gradle start up script for POSIX generated by Gradle.
-#
-# Important for running:
-#
-# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
-# noncompliant, but you have some other compliant shell such as ksh or
-# bash, then to run this script, type that shell name before the whole
-# command line, like:
-#
-# ksh Gradle
-#
-# Busybox and similar reduced shells will NOT work, because this script
-# requires all of these POSIX shell features:
-# * functions;
-# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
-# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
-# * compound commands having a testable exit status, especially «case»;
-# * various built-in commands including «command», «set», and «ulimit».
-#
-# Important for patching:
-#
-# (2) This script targets any POSIX shell, so it avoids extensions provided
-# by Bash, Ksh, etc; in particular arrays are avoided.
-#
-# The "traditional" practice of packing multiple parameters into a
-# space-separated string is a well documented source of bugs and security
-# problems, so this is (mostly) avoided, by progressively accumulating
-# options in "$@", and eventually passing that to Java.
-#
-# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
-# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
-# see the in-line comments for details.
-#
-# There are tweaks for specific operating systems such as AIX, CygWin,
-# Darwin, MinGW, and NonStop.
-#
-# (3) This script is generated from the Groovy template
-# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
-# within the Gradle project.
-#
-# You can find Gradle at https://github.com/gradle/gradle/.
-#
-##############################################################################
-
-# Attempt to set APP_HOME
-
-# Resolve links: $0 may be a link
-app_path=$0
-
-# Need this for daisy-chained symlinks.
-while
- APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
- [ -h "$app_path" ]
-do
- ls=$( ls -ld "$app_path" )
- link=${ls#*' -> '}
- case $link in #(
- /*) app_path=$link ;; #(
- *) app_path=$APP_HOME$link ;;
- esac
-done
-
-# This is normally unused
-# shellcheck disable=SC2034
-APP_BASE_NAME=${0##*/}
-# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
-APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
-' "$PWD" ) || exit
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD=maximum
-
-warn () {
- echo "$*"
-} >&2
-
-die () {
- echo
- echo "$*"
- echo
- exit 1
-} >&2
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-nonstop=false
-case "$( uname )" in #(
- CYGWIN* ) cygwin=true ;; #(
- Darwin* ) darwin=true ;; #(
- MSYS* | MINGW* ) msys=true ;; #(
- NONSTOP* ) nonstop=true ;;
-esac
-
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
-
-
-# Determine the Java command to use to start the JVM.
-if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD=$JAVA_HOME/jre/sh/java
- else
- JAVACMD=$JAVA_HOME/bin/java
- fi
- if [ ! -x "$JAVACMD" ] ; then
- die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
- fi
-else
- JAVACMD=java
- if ! command -v java >/dev/null 2>&1
- then
- die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
- fi
-fi
-
-# Increase the maximum file descriptors if we can.
-if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
- case $MAX_FD in #(
- max*)
- # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
- # shellcheck disable=SC2039,SC3045
- MAX_FD=$( ulimit -H -n ) ||
- warn "Could not query maximum file descriptor limit"
- esac
- case $MAX_FD in #(
- '' | soft) :;; #(
- *)
- # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
- # shellcheck disable=SC2039,SC3045
- ulimit -n "$MAX_FD" ||
- warn "Could not set maximum file descriptor limit to $MAX_FD"
- esac
-fi
-
-# Collect all arguments for the java command, stacking in reverse order:
-# * args from the command line
-# * the main class name
-# * -classpath
-# * -D...appname settings
-# * --module-path (only if needed)
-# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
-
-# For Cygwin or MSYS, switch paths to Windows format before running java
-if "$cygwin" || "$msys" ; then
- APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
- CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
-
- JAVACMD=$( cygpath --unix "$JAVACMD" )
-
- # Now convert the arguments - kludge to limit ourselves to /bin/sh
- for arg do
- if
- case $arg in #(
- -*) false ;; # don't mess with options #(
- /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
- [ -e "$t" ] ;; #(
- *) false ;;
- esac
- then
- arg=$( cygpath --path --ignore --mixed "$arg" )
- fi
- # Roll the args list around exactly as many times as the number of
- # args, so each arg winds up back in the position where it started, but
- # possibly modified.
- #
- # NB: a `for` loop captures its iteration list before it begins, so
- # changing the positional parameters here affects neither the number of
- # iterations, nor the values presented in `arg`.
- shift # remove old arg
- set -- "$@" "$arg" # push replacement arg
- done
-fi
-
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
-
-# Collect all arguments for the java command:
-# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
-# and any embedded shellness will be escaped.
-# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
-# treated as '${Hostname}' itself on the command line.
-
-set -- \
- "-Dorg.gradle.appname=$APP_BASE_NAME" \
- -classpath "$CLASSPATH" \
- org.gradle.wrapper.GradleWrapperMain \
- "$@"
-
-# Stop when "xargs" is not available.
-if ! command -v xargs >/dev/null 2>&1
-then
- die "xargs is not available"
-fi
-
-# Use "xargs" to parse quoted args.
-#
-# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
-#
-# In Bash we could simply go:
-#
-# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
-# set -- "${ARGS[@]}" "$@"
-#
-# but POSIX shell has neither arrays nor command substitution, so instead we
-# post-process each arg (as a line of input to sed) to backslash-escape any
-# character that might be a shell metacharacter, then use eval to reverse
-# that process (while maintaining the separation between arguments), and wrap
-# the whole thing up as a single "set" statement.
-#
-# This will of course break if any of these variables contains a newline or
-# an unmatched quote.
-#
-
-eval "set -- $(
- printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
- xargs -n1 |
- sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
- tr '\n' ' '
- )" '"$@"'
-
-exec "$JAVACMD" "$@"
diff --git a/android/gradlew.bat b/android/gradlew.bat
deleted file mode 100644
index 9d21a21..0000000
--- a/android/gradlew.bat
+++ /dev/null
@@ -1,94 +0,0 @@
-@rem
-@rem Copyright 2015 the original author or authors.
-@rem
-@rem Licensed under the Apache License, Version 2.0 (the "License");
-@rem you may not use this file except in compliance with the License.
-@rem You may obtain a copy of the License at
-@rem
-@rem https://www.apache.org/licenses/LICENSE-2.0
-@rem
-@rem Unless required by applicable law or agreed to in writing, software
-@rem distributed under the License is distributed on an "AS IS" BASIS,
-@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-@rem See the License for the specific language governing permissions and
-@rem limitations under the License.
-@rem
-@rem SPDX-License-Identifier: Apache-2.0
-@rem
-
-@if "%DEBUG%"=="" @echo off
-@rem ##########################################################################
-@rem
-@rem Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-set DIRNAME=%~dp0
-if "%DIRNAME%"=="" set DIRNAME=.
-@rem This is normally unused
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Resolve any "." and ".." in APP_HOME to make it shorter.
-for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if %ERRORLEVEL% equ 0 goto execute
-
-echo. 1>&2
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
-echo. 1>&2
-echo Please set the JAVA_HOME variable in your environment to match the 1>&2
-echo location of your Java installation. 1>&2
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto execute
-
-echo. 1>&2
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
-echo. 1>&2
-echo Please set the JAVA_HOME variable in your environment to match the 1>&2
-echo location of your Java installation. 1>&2
-
-goto fail
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
-
-:end
-@rem End local scope for the variables with windows NT shell
-if %ERRORLEVEL% equ 0 goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-set EXIT_CODE=%ERRORLEVEL%
-if %EXIT_CODE% equ 0 set EXIT_CODE=1
-if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
-exit /b %EXIT_CODE%
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
diff --git a/android/settings.gradle b/android/settings.gradle
deleted file mode 100644
index 3b4431d..0000000
--- a/android/settings.gradle
+++ /dev/null
@@ -1,5 +0,0 @@
-include ':app'
-include ':capacitor-cordova-android-plugins'
-project(':capacitor-cordova-android-plugins').projectDir = new File('./capacitor-cordova-android-plugins/')
-
-apply from: 'capacitor.settings.gradle'
\ No newline at end of file
diff --git a/android/variables.gradle b/android/variables.gradle
deleted file mode 100644
index e14d745..0000000
--- a/android/variables.gradle
+++ /dev/null
@@ -1,16 +0,0 @@
-ext {
- minSdkVersion = 24
- compileSdkVersion = 36
- targetSdkVersion = 36
- androidxActivityVersion = '1.11.0'
- androidxAppCompatVersion = '1.7.1'
- androidxCoordinatorLayoutVersion = '1.3.0'
- androidxCoreVersion = '1.17.0'
- androidxFragmentVersion = '1.8.9'
- coreSplashScreenVersion = '1.2.0'
- androidxWebkitVersion = '1.14.0'
- junitVersion = '4.13.2'
- androidxJunitVersion = '1.3.0'
- androidxEspressoCoreVersion = '3.7.0'
- cordovaAndroidVersion = '14.0.1'
-}
diff --git a/apps/web/app/adapters/yunlefunAuth.ts b/apps/web/app/adapters/yunlefunAuth.ts
index ffda998..89af55d 100644
--- a/apps/web/app/adapters/yunlefunAuth.ts
+++ b/apps/web/app/adapters/yunlefunAuth.ts
@@ -2,23 +2,15 @@ import type {
AcquisitionContext,
SsoAuthorizationResult,
} from '@yunlefun/sso'
-import type {
- NativeSsoTransaction,
- NativeSsoTransactionStore,
-} from '~/utils/nativeSso'
import type {
YunlefunAccount,
YunlefunAuthorizationAdapter,
- YunlefunAuthorizationResult,
YunlefunIdentityAdapter,
} from '~/utils/yunlefunAuth'
import type { YunlefunSsoConfig } from '~/utils/yunlefunSsoConfig'
-import { Browser } from '@capacitor/browser'
-import { Preferences } from '@capacitor/preferences'
import {
adoptSsoCode,
consumeSsoRedirect,
- sanitizeAcquisitionContext,
startSsoRedirect,
} from '@yunlefun/sso'
import {
@@ -26,13 +18,6 @@ import {
SsoIdentityAdoptionError,
} from '@yunlefun/sso/browser'
import { readCookAcquisition } from '~/utils/acquisition'
-import {
- consumeNativeSsoCallback,
- isNativeSsoCallbackUrl,
- openNativeSsoRedirect,
-} from '~/utils/nativeSso'
-
-const NATIVE_TRANSACTION_KEY = 'cook:sso:v3:native-transaction'
interface CloudbaseUser {
avatar_url?: string
@@ -94,11 +79,6 @@ interface CloudbaseModule {
}) => CloudbaseApp
}
-export interface NativeYunlefunAuthorizationAdapter extends YunlefunAuthorizationAdapter {
- cancel: () => Promise
- consumeUrl: (url: string) => Promise
-}
-
export interface CloudbaseIdentityDependencies {
getAuth?: (env: string) => Promise
}
@@ -151,43 +131,6 @@ export function createWebYunlefunAuthorizationAdapter(
}
}
-export function createNativeYunlefunAuthorizationAdapter(
- config: YunlefunSsoConfig,
- initialUrl: () => Promise,
- readAcquisition: () => AcquisitionContext | null = readCookAcquisition,
-): NativeYunlefunAuthorizationAdapter {
- const store = createNativeTransactionStore()
-
- async function consumeUrl(url: string): Promise {
- if (!isNativeSsoCallbackUrl(url, config.redirect.redirectUri))
- return null
-
- const result = await consumeNativeSsoCallback(url, store)
- await Browser.close().catch(() => undefined)
- return result
- }
-
- return {
- cancel: async () => store.clear(),
- consumeInitial: async () => {
- const url = await initialUrl()
- return url ? consumeUrl(url) : null
- },
- consumeUrl,
- start: async () => {
- const acquisition = readAcquisition()
- await openNativeSsoRedirect({
- ...config.redirect,
- prompt: 'consent',
- ...(acquisition ? { acquisition } : {}),
- }, store, async (url) => {
- await Browser.open({ url })
- })
- return null
- },
- }
-}
-
export function createCloudbaseIdentityAdapter(
config: YunlefunSsoConfig,
dependencies: CloudbaseIdentityDependencies = {},
@@ -212,32 +155,6 @@ export function createCloudbaseIdentityAdapter(
}
}
-function createNativeTransactionStore(): NativeSsoTransactionStore {
- return {
- clear: async () => {
- await Preferences.remove({ key: NATIVE_TRANSACTION_KEY })
- },
- load: async () => {
- const { value } = await Preferences.get({ key: NATIVE_TRANSACTION_KEY })
- if (!value)
- return null
-
- try {
- return readNativeTransaction(JSON.parse(value) as unknown)
- }
- catch {
- return null
- }
- },
- save: async (transaction) => {
- await Preferences.set({
- key: NATIVE_TRANSACTION_KEY,
- value: JSON.stringify(transaction),
- })
- },
- }
-}
-
function getCloudbaseApp(env: string): Promise {
if (cachedCloudbaseApp) {
if (cachedCloudbaseEnv !== env)
@@ -339,33 +256,3 @@ function normalizeAccount(user: CloudbaseUser | null | undefined): YunlefunAccou
function firstString(...values: unknown[]): string | undefined {
return values.find(value => typeof value === 'string' && value.trim())?.toString().trim()
}
-
-function readNativeTransaction(value: unknown): NativeSsoTransaction | null {
- if (!isRecord(value)
- || typeof value.clientId !== 'string'
- || typeof value.codeVerifier !== 'string'
- || typeof value.createdAt !== 'number'
- || typeof value.issuer !== 'string'
- || typeof value.nonce !== 'string'
- || typeof value.redirectUri !== 'string'
- || !Array.isArray(value.scope)
- || !value.scope.every(scope => typeof scope === 'string')) {
- return null
- }
-
- const acquisition = sanitizeAcquisitionContext(value.acquisition)
- return {
- clientId: value.clientId,
- codeVerifier: value.codeVerifier,
- createdAt: value.createdAt,
- issuer: value.issuer,
- nonce: value.nonce,
- redirectUri: value.redirectUri,
- scope: value.scope,
- ...(acquisition ? { acquisition } : {}),
- }
-}
-
-function isRecord(value: unknown): value is Record {
- return value !== null && typeof value === 'object' && !Array.isArray(value)
-}
diff --git a/apps/web/app/composables/dark.ts b/apps/web/app/composables/dark.ts
index 7eb9779..acbd857 100644
--- a/apps/web/app/composables/dark.ts
+++ b/apps/web/app/composables/dark.ts
@@ -1,5 +1,3 @@
-import { Capacitor } from '@capacitor/core'
-import { StatusBar, Style } from '@capacitor/status-bar'
import { ionDarkClass } from '~/constants'
/**
@@ -13,24 +11,14 @@ export const useDarkMode = createSharedComposable(() => {
const color = useColorMode()
const isDark = computed(() => color.value === 'dark')
- async function setLightMode() {
+ function setLightMode() {
document.documentElement.classList.remove(ionDarkClass)
syncThemeColor('#f2f2f6')
-
- if (Capacitor.isNativePlatform()) {
- await StatusBar.setStyle({ style: Style.Light })
- await StatusBar.setBackgroundColor({ color: '#f2f2f6ff' })
- }
}
- async function setDarkMode() {
+ function setDarkMode() {
document.documentElement.classList.add(ionDarkClass)
syncThemeColor('#000000')
-
- if (Capacitor.isNativePlatform()) {
- await StatusBar.setStyle({ style: Style.Dark })
- await StatusBar.setBackgroundColor({ color: '#ff000000' })
- }
}
return {
@@ -39,7 +27,7 @@ export const useDarkMode = createSharedComposable(() => {
setLightMode,
setDarkMode,
- async toggleDark() {
+ toggleDark() {
const targetMode = color.value === 'dark' ? 'light' : 'dark'
color.preference = targetMode
diff --git a/apps/web/app/composables/useYunlefunAuth.ts b/apps/web/app/composables/useYunlefunAuth.ts
index d1b2732..dd0807f 100644
--- a/apps/web/app/composables/useYunlefunAuth.ts
+++ b/apps/web/app/composables/useYunlefunAuth.ts
@@ -1,18 +1,12 @@
-import type { NativeYunlefunAuthorizationAdapter } from '~/adapters/yunlefunAuth'
import type {
YunlefunAuthController,
YunlefunAuthSnapshot,
} from '~/utils/yunlefunAuth'
-import { App } from '@capacitor/app'
-import { Browser } from '@capacitor/browser'
-import { Capacitor } from '@capacitor/core'
import {
callCloudbaseFunction,
createCloudbaseIdentityAdapter,
- createNativeYunlefunAuthorizationAdapter,
createWebYunlefunAuthorizationAdapter,
} from '~/adapters/yunlefunAuth'
-import { stripNativeSsoCallbackHash } from '~/utils/nativeSso'
import { createYunlefunAuthController } from '~/utils/yunlefunAuth'
import { resolveYunlefunSsoConfig } from '~/utils/yunlefunSsoConfig'
@@ -21,8 +15,6 @@ interface YunlefunRuntimeConfig {
yunlefunCloudbaseEnv?: string
yunlefunSsoClientId?: string
yunlefunSsoExchangeUrl?: string
- yunlefunSsoNativeClientId?: string
- yunlefunSsoNativeRedirectUri?: string
yunlefunSsoOrigin?: string
yunlefunSsoRedirectUri?: string
yunlefunSsoRedirectUris?: string
@@ -32,10 +24,7 @@ interface YunlefunRuntimeConfig {
let controller: YunlefunAuthController | undefined
let cloudbaseEnv = ''
-let nativeAdapter: NativeYunlefunAuthorizationAdapter | undefined
let initialization: Promise | undefined
-let nativeUrlListenerInstalled = false
-let handlingNativeCallback = false
export function useYunlefunAuth() {
const runtimeConfig = useRuntimeConfig() as unknown as YunlefunRuntimeConfig
@@ -98,35 +87,16 @@ async function initializeOnce(
if (!import.meta.client)
return
- const platform = Capacitor.isNativePlatform() ? 'native' : 'web'
- if (platform === 'web'
- && window.location.pathname === '/auth/callback'
- && new URLSearchParams(window.location.search).get('platform') === 'native') {
- const sanitizedPath = stripNativeSsoCallbackHash(window.location.href)
- if (sanitizedPath)
- window.history.replaceState(window.history.state, '', sanitizedPath)
- configurationMessage.value = '未能自动返回 Cook,请确认已安装最新版应用后重新授权'
- snapshot.value = {
- account: null,
- errorMessage: '',
- status: 'signed-out',
- }
- return
- }
-
const result = resolveYunlefunSsoConfig({
clientId: runtimeConfig.public.yunlefunSsoClientId,
cloudbaseEnv: runtimeConfig.public.yunlefunCloudbaseEnv,
exchangeUrl: runtimeConfig.public.yunlefunSsoExchangeUrl,
- nativeClientId: runtimeConfig.public.yunlefunSsoNativeClientId,
- nativeRedirectUri: runtimeConfig.public.yunlefunSsoNativeRedirectUri,
redirectUri: runtimeConfig.public.yunlefunSsoRedirectUri,
redirectUris: runtimeConfig.public.yunlefunSsoRedirectUris,
scope: runtimeConfig.public.yunlefunSsoScope,
ssoOrigin: runtimeConfig.public.yunlefunSsoOrigin,
}, {
currentOrigin: window.location.origin,
- platform,
})
if (!result.ok) {
@@ -140,59 +110,14 @@ async function initializeOnce(
}
cloudbaseEnv = result.config.cloudbaseEnv
- const web = createWebYunlefunAuthorizationAdapter(result.config)
- nativeAdapter = createNativeYunlefunAuthorizationAdapter(result.config, async () => {
- const launch = await App.getLaunchUrl()
- return launch?.url ?? null
- })
controller = createYunlefunAuthController({
identity: createCloudbaseIdentityAdapter(result.config),
- native: nativeAdapter,
- platform,
- web,
+ web: createWebYunlefunAuthorizationAdapter(result.config),
})
- if (platform === 'native' && !nativeUrlListenerInstalled) {
- nativeUrlListenerInstalled = true
- await App.addListener('appUrlOpen', async ({ url }) => {
- if (!controller || !nativeAdapter)
- return
-
- handlingNativeCallback = true
- try {
- const authorization = await nativeAdapter.consumeUrl(url)
- if (!authorization)
- return
-
- await controller.handleAuthorization(authorization)
- publishSnapshot(snapshot)
- if (controller.snapshot().status === 'signed-in')
- await navigateTo('/my', { replace: true })
- }
- finally {
- handlingNativeCallback = false
- }
- })
- await Browser.addListener('browserFinished', async () => {
- if (!controller
- || handlingNativeCallback
- || controller.snapshot().status !== 'signing-in') {
- return
- }
-
- await nativeAdapter?.cancel().catch(() => undefined)
- await controller.handleAuthorization({
- ok: false,
- reason: 'access_denied',
- })
- publishSnapshot(snapshot)
- })
- }
-
await controller.initialize()
publishSnapshot(snapshot)
- if (platform === 'web'
- && window.location.pathname === '/auth/callback'
+ if (window.location.pathname === '/auth/callback'
&& controller.snapshot().status === 'signed-in') {
await navigateTo('/my', { replace: true })
}
diff --git a/apps/web/app/constants/acknowledgements.ts b/apps/web/app/constants/acknowledgements.ts
index 989c448..b545698 100644
--- a/apps/web/app/constants/acknowledgements.ts
+++ b/apps/web/app/constants/acknowledgements.ts
@@ -101,12 +101,6 @@ export const acknowledgements: Acknowledgement[] = [
href: 'https://ionicframework.com',
target: '_blank',
},
- {
- type: 'website',
- label: 'Capacitor',
- href: 'https://capacitorjs.com',
- target: '_blank',
- },
{
type: 'website',
label: 'VueUse',
diff --git a/apps/web/app/constants/index.ts b/apps/web/app/constants/index.ts
index e07d669..f2a9c1b 100644
--- a/apps/web/app/constants/index.ts
+++ b/apps/web/app/constants/index.ts
@@ -2,7 +2,7 @@ export const appName = '食用手册'
export const appDescription = '好的,今天我们来做菜!'
export const namespace = 'cook'
-export const lastDbUpdated = '2026-10-20 11:02:43'
+export const lastDbUpdated = '2026-10-21 12:26:30'
export const icp = '苏ICP备17038157号'
diff --git a/apps/web/app/pages/tabs.vue b/apps/web/app/pages/tabs.vue
index 2db39fa..ac34cd0 100644
--- a/apps/web/app/pages/tabs.vue
+++ b/apps/web/app/pages/tabs.vue
@@ -1,7 +1,4 @@
diff --git a/apps/web/app/utils/dialog.ts b/apps/web/app/utils/dialog.ts
index 31b39d2..3aecde7 100644
--- a/apps/web/app/utils/dialog.ts
+++ b/apps/web/app/utils/dialog.ts
@@ -2,7 +2,7 @@ import { actionSheetController, alertController } from '@ionic/vue'
import { yunleHaptic } from './yunleHost'
/**
- * iOS 风格的弹窗:替代 @capacitor/dialog(Web 上会退化成 window.alert / confirm / prompt)
+ * iOS 风格的弹窗:统一走 Ionic 的 alert / actionSheet
*/
export async function showAlert(header: string, message: string): Promise {
diff --git a/apps/web/app/utils/nativeSso.ts b/apps/web/app/utils/nativeSso.ts
deleted file mode 100644
index 11c57d3..0000000
--- a/apps/web/app/utils/nativeSso.ts
+++ /dev/null
@@ -1,211 +0,0 @@
-import type {
- AcquisitionContext,
- RedirectSsoOptions,
- SsoAuthorizationResult,
- SsoRedirectResult,
-} from '@yunlefun/sso'
-import {
- buildSsoRequestUrl,
- deriveSsoPkceChallenge,
- isSsoPkceVerifier,
- parseSsoRedirectResult,
- readSsoClientId,
- readSsoRedirectUri,
- readSsoScope,
- sanitizeAcquisitionContext,
- YLF_DEFAULT_SSO_ORIGIN,
-} from '@yunlefun/sso'
-
-const TRANSACTION_TTL_MS = 10 * 60 * 1000
-const NONCE_RE = /^[\w-]{32,128}$/
-const BASE64_PADDING_RE = /=+$/
-
-export interface NativeSsoTransaction {
- clientId: string
- codeVerifier: string
- createdAt: number
- issuer: string
- nonce: string
- redirectUri: string
- scope: string[]
- acquisition?: AcquisitionContext
-}
-
-export interface NativeSsoTransactionStore {
- clear: () => Promise
- load: () => Promise
- save: (transaction: NativeSsoTransaction) => Promise
-}
-
-export interface NativeSsoDependencies {
- now?: () => number
- randomBase64Url?: () => string
-}
-
-export async function beginNativeSsoRedirect(
- options: RedirectSsoOptions,
- store: NativeSsoTransactionStore,
- dependencies: NativeSsoDependencies = {},
-): Promise {
- const issuer = new URL(options.ssoOrigin ?? YLF_DEFAULT_SSO_ORIGIN).origin
- const random = dependencies.randomBase64Url ?? (() => randomBase64Url(32))
- const nonce = random()
- const codeVerifier = random()
- const codeChallenge = await deriveSsoPkceChallenge(codeVerifier)
- const acquisition = sanitizeAcquisitionContext(options.acquisition)
- const authorizationUrl = buildSsoRequestUrl({
- clientId: options.clientId,
- codeChallenge,
- nonce,
- redirectUri: options.redirectUri,
- scope: options.scope,
- ssoOrigin: issuer,
- ...(options.prompt ? { prompt: options.prompt } : {}),
- ...(acquisition ? { acquisition } : {}),
- })
-
- await store.save({
- clientId: options.clientId,
- codeVerifier,
- createdAt: (dependencies.now ?? Date.now)(),
- issuer,
- nonce,
- redirectUri: options.redirectUri,
- scope: [...options.scope],
- ...(acquisition ? { acquisition } : {}),
- })
-
- return authorizationUrl
-}
-
-export async function openNativeSsoRedirect(
- options: RedirectSsoOptions,
- store: NativeSsoTransactionStore,
- open: (url: string) => Promise,
- dependencies: NativeSsoDependencies = {},
-): Promise {
- const url = await beginNativeSsoRedirect(options, store, dependencies)
- try {
- await open(url)
- }
- catch (error) {
- await store.clear()
- throw error
- }
-}
-
-export async function consumeNativeSsoCallback(
- callbackUrl: string,
- store: NativeSsoTransactionStore,
- dependencies: Pick = {},
-): Promise | null> {
- const stored = await store.load()
- await store.clear()
-
- const transaction = normalizeTransaction(stored)
- const now = (dependencies.now ?? Date.now)()
- if (!transaction
- || transaction.createdAt + TRANSACTION_TTL_MS <= now
- || !callbackMatchesRedirect(callbackUrl, transaction.redirectUri)) {
- return null
- }
-
- const result = parseSsoRedirectResult({
- expectedIssuer: transaction.issuer,
- expectedNonce: transaction.nonce,
- hash: new URL(callbackUrl).hash,
- })
- if (!result?.ok)
- return result
-
- return Object.freeze({
- ...result,
- clientId: transaction.clientId,
- codeVerifier: transaction.codeVerifier,
- redirectUri: transaction.redirectUri,
- scope: Object.freeze([...transaction.scope]),
- ...(transaction.acquisition ? { acquisition: transaction.acquisition } : {}),
- })
-}
-
-export function isNativeSsoCallbackUrl(callbackUrl: string, redirectUri: string): boolean {
- return callbackMatchesRedirect(callbackUrl, redirectUri)
-}
-
-export function stripNativeSsoCallbackHash(callbackUrl: string): string {
- try {
- const url = new URL(callbackUrl)
- return `${url.pathname}${url.search}`
- }
- catch {
- return ''
- }
-}
-
-function callbackMatchesRedirect(callbackUrl: string, redirectUri: string): boolean {
- try {
- const callback = new URL(callbackUrl)
- const callbackWithoutHash = `${callback.origin}${callback.pathname}${callback.search}`
- return callback.protocol === 'https:'
- && !callback.username
- && !callback.password
- && Boolean(callback.hash)
- && callbackWithoutHash === redirectUri
- }
- catch {
- return false
- }
-}
-
-function normalizeTransaction(value: NativeSsoTransaction | null): NativeSsoTransaction | null {
- if (!value)
- return null
-
- const clientId = readSsoClientId(value.clientId)
- const redirectUri = readSsoRedirectUri(value.redirectUri)
- const scope = readSsoScope(value.scope.join(' '))
- let issuer = ''
- try {
- const issuerUrl = new URL(value.issuer)
- issuer = issuerUrl.protocol === 'https:' && issuerUrl.origin === value.issuer
- ? issuerUrl.origin
- : ''
- }
- catch {
- issuer = ''
- }
-
- if (!clientId
- || !redirectUri
- || scope.length === 0
- || !issuer
- || !NONCE_RE.test(value.nonce)
- || !isSsoPkceVerifier(value.codeVerifier)
- || !Number.isSafeInteger(value.createdAt)) {
- return null
- }
-
- const acquisition = sanitizeAcquisitionContext(value.acquisition)
- return {
- clientId,
- codeVerifier: value.codeVerifier,
- createdAt: value.createdAt,
- issuer,
- nonce: value.nonce,
- redirectUri,
- scope,
- ...(acquisition ? { acquisition } : {}),
- }
-}
-
-function randomBase64Url(byteLength: number): string {
- const bytes = new Uint8Array(byteLength)
- globalThis.crypto.getRandomValues(bytes)
- let binary = ''
- for (const byte of bytes)
- binary += String.fromCharCode(byte)
- return globalThis.btoa(binary)
- .replace(/\+/g, '-')
- .replace(/\//g, '_')
- .replace(BASE64_PADDING_RE, '')
-}
diff --git a/apps/web/app/utils/yunleHost.ts b/apps/web/app/utils/yunleHost.ts
index 6bca1f6..58343d3 100644
--- a/apps/web/app/utils/yunleHost.ts
+++ b/apps/web/app/utils/yunleHost.ts
@@ -1,6 +1,6 @@
/**
* 云乐坊 App 内嵌容器(apps.yunle.fun)注入的 `window.ylf` JSAPI。
- * 普通浏览器与 Cook 自己的 Capacitor 外壳中不存在,所有调用都要特性检测。
+ * 普通浏览器中不存在,所有调用都要特性检测。
*
* @see https://github.com/YunLeFun/apps.yunle.fun/blob/main/docs/guide/jsapi.md
*/
diff --git a/apps/web/app/utils/yunlefunAuth.ts b/apps/web/app/utils/yunlefunAuth.ts
index 78a3a66..ed5c60b 100644
--- a/apps/web/app/utils/yunlefunAuth.ts
+++ b/apps/web/app/utils/yunlefunAuth.ts
@@ -48,15 +48,13 @@ export interface YunlefunAuthController {
interface YunlefunAuthControllerOptions {
identity: YunlefunIdentityAdapter
- native: YunlefunAuthorizationAdapter
- platform: 'native' | 'web'
web: YunlefunAuthorizationAdapter
}
export function createYunlefunAuthController(
options: YunlefunAuthControllerOptions,
): YunlefunAuthController {
- const authorization = options.platform === 'native' ? options.native : options.web
+ const authorization = options.web
let initialized = false
let state: YunlefunAuthSnapshot = {
account: null,
diff --git a/apps/web/app/utils/yunlefunSsoConfig.ts b/apps/web/app/utils/yunlefunSsoConfig.ts
index ede3619..26ff4e1 100644
--- a/apps/web/app/utils/yunlefunSsoConfig.ts
+++ b/apps/web/app/utils/yunlefunSsoConfig.ts
@@ -9,8 +9,6 @@ export interface YunlefunSsoConfigInput {
clientId?: string
cloudbaseEnv?: string
exchangeUrl?: string
- nativeClientId?: string
- nativeRedirectUri?: string
redirectUri?: string
redirectUris?: string | string[]
scope?: string
@@ -19,7 +17,6 @@ export interface YunlefunSsoConfigInput {
export interface YunlefunSsoConfigContext {
currentOrigin: string
- platform: 'native' | 'web'
}
export interface YunlefunSsoConfig {
@@ -39,22 +36,18 @@ export function resolveYunlefunSsoConfig(
input: YunlefunSsoConfigInput,
context: YunlefunSsoConfigContext,
): YunlefunSsoConfigResult {
- const clientId = readSsoClientId(
- context.platform === 'native' ? input.nativeClientId : input.clientId,
- )
+ const clientId = readSsoClientId(input.clientId)
const cloudbaseEnv = normalizeValue(input.cloudbaseEnv)
const exchangeUrl = readSsoRedirectUri(input.exchangeUrl)
const webRedirectUris = readWebRedirectUris(input.redirectUris ?? input.redirectUri)
- const redirectUri = context.platform === 'native'
- ? readSsoRedirectUri(input.nativeRedirectUri)
- : webRedirectUris.find(uri => new URL(uri).origin === context.currentOrigin)
+ const redirectUri = webRedirectUris.find(uri => new URL(uri).origin === context.currentOrigin)
const scope = readSsoScope(input.scope)
const ssoOrigin = normalizeHttpsOrigin(input.ssoOrigin)
if (!clientId
|| !CLOUDBASE_ENV_RE.test(cloudbaseEnv)
|| !exchangeUrl
- || (context.platform === 'native' ? !redirectUri : webRedirectUris.length === 0)
+ || webRedirectUris.length === 0
|| scope.length === 0
|| !ssoOrigin) {
return {
diff --git a/apps/web/nuxt.config.ts b/apps/web/nuxt.config.ts
index 3657d1f..32645d5 100644
--- a/apps/web/nuxt.config.ts
+++ b/apps/web/nuxt.config.ts
@@ -121,8 +121,6 @@ export default defineNuxtConfig({
yunlefunCloudbaseEnv: process.env.NUXT_PUBLIC_YUNLEFUN_CLOUDBASE_ENV || 'yunlefun-8g7ybcxc7345c490',
yunlefunSsoClientId: process.env.NUXT_PUBLIC_YUNLEFUN_SSO_CLIENT_ID || 'cook-web',
yunlefunSsoExchangeUrl: process.env.NUXT_PUBLIC_YUNLEFUN_SSO_EXCHANGE_URL || 'https://api.yunle.fun/sso-ticket',
- yunlefunSsoNativeClientId: process.env.NUXT_PUBLIC_YUNLEFUN_SSO_NATIVE_CLIENT_ID || 'cook-mobile',
- yunlefunSsoNativeRedirectUri: process.env.NUXT_PUBLIC_YUNLEFUN_SSO_NATIVE_REDIRECT_URI || 'https://cook.yunyoujun.cn/auth/callback?platform=native',
yunlefunSsoOrigin: process.env.NUXT_PUBLIC_YUNLEFUN_SSO_ORIGIN || 'https://www.yunle.fun',
yunlefunSsoRedirectUri: process.env.NUXT_PUBLIC_YUNLEFUN_SSO_REDIRECT_URI || 'https://cook.yunyoujun.cn/auth/callback',
yunlefunSsoRedirectUris: process.env.NUXT_PUBLIC_YUNLEFUN_SSO_REDIRECT_URIS || [
diff --git a/apps/web/package.json b/apps/web/package.json
index 07591e8..9b0e78c 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -13,14 +13,6 @@
"typecheck": "nuxt typecheck"
},
"dependencies": {
- "@capacitor/app": "8.1.1",
- "@capacitor/browser": "8.0.4",
- "@capacitor/core": "8.5.0",
- "@capacitor/dialog": "8.0.1",
- "@capacitor/haptics": "8.0.2",
- "@capacitor/keyboard": "8.0.5",
- "@capacitor/preferences": "8.0.1",
- "@capacitor/status-bar": "8.0.3",
"@cloudbase/js-sdk": "3.7.1",
"@yunlefun/sso": "0.7.0",
"@yunyoujun/cook": "workspace:*",
diff --git a/capacitor.config.ts b/capacitor.config.ts
deleted file mode 100644
index b970184..0000000
--- a/capacitor.config.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-///
-
-import type { CapacitorConfig } from '@capacitor/cli'
-
-const config: CapacitorConfig = {
- appId: 'cn.yunyoujun.cook',
- appName: '食用手册',
- webDir: 'dist',
-
- server: {
- hostname: 'cook.yunyoujun.cn',
- androidScheme: 'https',
- iosScheme: 'https',
- },
-
- plugins: {
- StatusBar: {
- overlaysWebView: false,
- style: 'DARK',
- backgroundColor: '#ffffffff',
- },
- },
-}
-
-export default config
diff --git a/docs/.vitepress/config/index.ts b/docs/.vitepress/config/index.ts
index 859d69f..03e1a27 100644
--- a/docs/.vitepress/config/index.ts
+++ b/docs/.vitepress/config/index.ts
@@ -34,9 +34,8 @@ export default defineConfig({
text: '开发文档',
items: [
{ text: 'Cook CLI', link: '/dev/cli' },
- { text: '移动应用', link: '/dev/app' },
+ { text: 'Web 应用', link: '/dev/app' },
{ text: '菜谱数据', link: '/dev/data' },
- { text: 'iOS App 打磨目标', link: '/dev/ios-roadmap' },
],
},
],
@@ -48,6 +47,7 @@ export default defineConfig({
{ text: '0001 菜谱数据', link: '/decisions/0001-recipe-data' },
{ text: '0002 反馈与固定 id', link: '/decisions/0002-feedback-and-ids' },
{ text: '0003 原生 iOS 与 monorepo', link: '/decisions/0003-native-ios-monorepo' },
+ { text: '0004 只保留 Web', link: '/decisions/0004-web-only' },
],
},
],
diff --git a/docs/decisions/0003-native-ios-monorepo.md b/docs/decisions/0003-native-ios-monorepo.md
index d29aa74..0d4ecb1 100644
--- a/docs/decisions/0003-native-ios-monorepo.md
+++ b/docs/decisions/0003-native-ios-monorepo.md
@@ -1,6 +1,6 @@
# 0003 原生 iOS App 与 monorepo 结构
-- 状态:已采纳
+- 状态:被 [0004 只保留 Web,移除 Capacitor 原生壳](./0004-web-only) 取代
- 日期:2026-10-18
- 关联:调整 [#98](https://github.com/YunYouJun/cook/issues/98) 的阶段 4
@@ -68,4 +68,4 @@ docs/ 不变
- iOS 开发、构建和 UI 调试需要 macOS + Xcode 26,云端环境只能写代码和跑纯 Swift / TS 测试。
- 推荐逻辑的改动成本变成两份,靠共享用例兜底;核心逻辑应尽量保持小而纯。
- 搬迁会和进行中的 PR 冲突,需要等它们合并后再开始,且搬迁 PR 要尽快合并。
-- 打磨计划和验收标准见 [iOS App 打磨目标](/dev/ios-roadmap)。
+- 打磨计划和验收标准见 iOS App 打磨目标(该计划已随 [0004](/decisions/0004-web-only) 作废)。
diff --git a/docs/decisions/0004-web-only.md b/docs/decisions/0004-web-only.md
new file mode 100644
index 0000000..7c246d6
--- /dev/null
+++ b/docs/decisions/0004-web-only.md
@@ -0,0 +1,62 @@
+# 0004 只保留 Web,移除 Capacitor 原生壳
+
+- 状态:已采纳
+- 日期:2026-10-21
+- 关联:取代 [0003 原生 iOS App 与 monorepo 结构](./0003-native-ios-monorepo)
+
+## 背景
+
+- 仓库同时维护着三套东西:Nuxt Web 应用、Capacitor 的 iOS 壳、Capacitor 的 Android 壳。
+- Capacitor 依赖比想象中深:登录走原生浏览器 + 原生回调 URL,暗色模式改原生状态栏,Android 有物理返回键处理,
+ SSO 事务存在 `Preferences` 里。为此多出了 `nativeSso.ts`、`createNativeYunlefunAuthorizationAdapter`、
+ `resolveYunlefunSsoConfig` 的 `platform` 分支,以及 6 个只为原生分支存在的测试文件。
+- 0003 决定用 SwiftUI 原生版替换 Capacitor 版,把 iOS 当作要上架收费的主力。但 SwiftUI 工程
+ (`apps/ios`)至今没有开工,Capacitor 壳反而成了长期负担:每次升级 `@capacitor/*` 都要在 Web 侧
+ 重新验证原生分支,而这些分支在浏览器里根本走不到。
+- 实际使用中,Web 版已经同时服务普通浏览器和云乐坊容器(`window.ylf` JSAPI),原生壳带来的能力
+ (状态栏配色、物理返回键、原生 SSO 回跳)都有 Web 侧的等价实现。
+
+## 方案对比
+
+| 问题 | 方案 | 取舍 |
+| ---------- | ---------------------------- | ------------------------------------------------------------ |
+| 原生壳去留 | 保留 Capacitor iOS + Android | 两条壳都要跟 `@capacitor/*` 版本走;Web 侧原生分支长期没人跑 |
+| | 只删 Android,保留 iOS | iOS 壳仍在,Capacitor 依赖无法卸掉,清理不彻底 |
+| | **全部移除,只保留 Web** | 失去上架 App 与原生 SSO;换来单一代码路径和持续可维护的 Web |
+
+## 决定
+
+### 删除
+
+- `android/`、`ios/` 两个 Capacitor 原生壳工程。
+- `capacitor.config.ts`、根 `ionic.config.json`。
+- `scripts/android/`、`scripts/ios.sh`。
+- 根与 `apps/web` 的 `package.json` 里全部 `@capacitor/*` 依赖,以及 `dev:android`、`build:android`、
+ `dev:ios`、`ios`、`android`、`open:ios`、`open:android`、`sync` 等脚本。
+
+### Web 侧去 Capacitor 化
+
+- `composables/dark.ts`:只改 `meta[name="theme-color"]`,不再设置原生状态栏。
+- `pages/tabs.vue`:移除 Android 物理返回键处理(浏览器自带返回,无需拦截)。
+- `adapters/yunlefunAuth.ts`:删掉原生授权适配器和基于 `Preferences` 的事务存储,只保留 Web 授权适配器。
+- `utils/nativeSso.ts`:整体删除。它的产物只是原生 SSO 的 PKCE 事务与回调解析,Web 端走
+ `@yunlefun/sso` 的顶层重定向,不需要。
+- `utils/yunlefunAuth.ts` / `utils/yunlefunSsoConfig.ts`:控制器和配置解析去掉 `platform` 分支,
+ 只保留 Web 一种形态。
+- `nuxt.config.ts`:去掉 `yunlefunSsoNativeClientId` / `yunlefunSsoNativeRedirectUri`。
+
+### 保留
+
+- `@nuxtjs/ionic` 与 Ionic UI:Ionic 是 Web UI 框架,与 Capacitor 无关。
+- `utils/yunleHost.ts` 与云乐坊容器(`window.ylf`)集成:这是 Web 被嵌入第三方 App 容器时的适配层,
+ 和 Capacitor 无关。
+- PWA 安装、Service Worker、离线能力:都是 Web 能力。
+
+## 影响
+
+- 不再有 iOS / Android 安装包。若之后要上架,需要另起仓库做原生工程,而不是把 Capacitor 壳捡回来。
+- 云乐坊 SSO 在 Web 上继续可用:容器内走宿主授权面板,容器外走顶层重定向回到
+ `https://cook.yunyoujun.cn/auth/callback`。PKCE 与 HTTPS 回跳地址的约束不变。
+- `docs/dev/ios-roadmap.md` 与 `docs/decisions/0003-native-ios-monorepo.md` 随之作废。
+- `@nuxtjs/ionic` 自身仍会传递依赖 `@capacitor/cli` / `@capacitor/core`(构建期使用,运行时不会调用),
+ `pnpm-workspace.yaml` 里对应的 override 保留。
diff --git a/docs/decisions/index.md b/docs/decisions/index.md
index 2a4e60f..d934778 100644
--- a/docs/decisions/index.md
+++ b/docs/decisions/index.md
@@ -10,8 +10,9 @@
## 列表
-| 编号 | 标题 | 状态 |
-| ---------------------------------- | --------------------------------- | ------ |
-| [0001](./0001-recipe-data) | 菜谱数据的来源、质量与反馈闭环 | 提议中 |
-| [0002](./0002-feedback-and-ids) | 菜谱固定 id、应用内反馈与筛选信号 | 已采纳 |
-| [0003](./0003-native-ios-monorepo) | 原生 iOS App 与 monorepo 结构 | 已采纳 |
+| 编号 | 标题 | 状态 |
+| ---------------------------------- | --------------------------------- | ------------ |
+| [0001](./0001-recipe-data) | 菜谱数据的来源、质量与反馈闭环 | 提议中 |
+| [0002](./0002-feedback-and-ids) | 菜谱固定 id、应用内反馈与筛选信号 | 已采纳 |
+| [0003](./0003-native-ios-monorepo) | 原生 iOS App 与 monorepo 结构 | 被 0004 取代 |
+| [0004](./0004-web-only) | 只保留 Web,移除 Capacitor 原生壳 | 已采纳 |
diff --git a/docs/dev/acquisition.md b/docs/dev/acquisition.md
index 20d3851..2ea87dc 100644
--- a/docs/dev/acquisition.md
+++ b/docs/dev/acquisition.md
@@ -6,7 +6,7 @@ Cook 在文档初次进入时记录来源。`firstTouch` 保存在当前域名
来源只携带落地域名、路径、外部 referrer 域名以及 `utm_source`、`utm_medium`、`utm_campaign`。`yunle.fun`、其全部子域、`cook.yunyoujun.cn` 和当前域名的站内跳转不会计入外部 referrer,避免 SSO 或 Apps 往返被统计成获客渠道。查询、hash 和凭证不会写入来源记录。没有 referrer/UTM 表示来源缺失,不能据此断言为直接访问。
-登录前读取同一份 `{ version: 1, firstTouch, registerTouch }`,同时覆盖 Web 顶层重定向、Apps host bridge 和 Cook 原生浏览器。来源为客户端上报数据;统一登录服务依据 Registry 验证应用入口并依据 Auth 判断账号是否真正新注册,不能按 Cook 首次登录或公开资料创建时间判断。后续登录不会覆盖账号已保存的注册来源。
+登录前读取同一份 `{ version: 1, firstTouch, registerTouch }`,同时覆盖 Web 顶层重定向和 Apps host bridge。来源为客户端上报数据;统一登录服务依据 Registry 验证应用入口并依据 Auth 判断账号是否真正新注册,不能按 Cook 首次登录或公开资料创建时间判断。后续登录不会覆盖账号已保存的注册来源。
## 本地联调
@@ -25,10 +25,10 @@ node scripts/qa/verify-acquisition-sdk.mjs --sdk-root=/path/to/ylf --build --typ
1. 先发布账户私有来源集合/写入 API 与统一登录、SSO 服务端(它们可先接收可选字段并继续兼容旧客户端)。
2. 从 `YunLeFun/ylf` 发布已验证的 `@yunlefun/sso@0.7.0`;该版本给现有 PKCE 协议增加可选来源字段。
3. 在 Cook 解析并更新 0.7.0 的 lockfile,复核保留当前其他依赖改动,再执行 frozen install、typecheck 和构建并发布。
-4. 发布 Apps 的来源透传代码;原生“使用其他账号”分支还需要新的 iOS/Android 容器版本。
+4. 发布 Apps 的来源透传代码。
`@yunlefun/sso@0.7.0` 已由公开的 `YunLeFun/ylf` 仓库通过 OIDC 发布,附带 GitHub Actions provenance。Cook 的 lockfile 使用实际 registry integrity,安装与发布不依赖临时本地路径或 override。`minimumReleaseAgeExclude` 只为已核验的自有版本 `@yunlefun/sso@0.7.0` 提供精确例外,其余依赖继续遵循 24 小时等待和供应链策略。
-Cook 主域名 `cook.yunyoujun.cn` 对应 EdgeOne Upload 项目 `yunyoujun-cook`,发布时使用该项目名;`cook.yunle.fun` 是另一个 Git 集成项目。原生容器与应用商店发布仍按各自流程验收。
+Cook 主域名 `cook.yunyoujun.cn` 对应 EdgeOne Upload 项目 `yunyoujun-cook`,发布时使用该项目名;`cook.yunle.fun` 是另一个 Git 集成项目。云乐坊容器内的发布仍按各自流程验收。
历史用户最多保留来自 SSO 时间关联的应用入口推断;不能把 GA 总体流量比例回填为某个 UID 的外部渠道。各域名、不同浏览器和被清除的存储也无法恢复此前未采集的触达。
diff --git a/docs/dev/analytics.md b/docs/dev/analytics.md
index 787110c..17ec02c 100644
--- a/docs/dev/analytics.md
+++ b/docs/dev/analytics.md
@@ -17,7 +17,7 @@ NUXT_PUBLIC_CLARITY_PROJECT_ID=ks1ebw03i5
NUXT_PUBLIC_CLARITY_DOMAINS=cook.yunyoujun.cn,cook.yunle.fun
```
-显式设置空项目 ID 可关闭统计。开发模式、未授权域名、原生 Capacitor WebView、Do Not Track 和 Global Privacy Control 开启的浏览器不加载统计。页面就绪后异步加载 Clarity,不代理或打包第三方脚本。
+显式设置空项目 ID 可关闭统计。开发模式、未授权域名、Do Not Track 和 Global Privacy Control 开启的浏览器不加载统计。页面就绪后异步加载 Clarity,不代理或打包第三方脚本。
静态托管须在**构建前**设置配置,执行 `pnpm build` 并发布 `dist`。容器启动后修改环境变量不会改变静态资源。Docker 支持同名 `--build-arg`,GitHub Docker 工作流读取同名 Repository variables,未设置时使用 Cook 默认值。工作流中需要禁用时可将项目 ID 设置为 `disabled`,它无法通过 ID 校验。
diff --git a/docs/dev/app.md b/docs/dev/app.md
index 5cf0250..86bac6a 100644
--- a/docs/dev/app.md
+++ b/docs/dev/app.md
@@ -1,33 +1,24 @@
-# APP
+# Web 应用
-考虑到跨平台和开发效率,计划使用:
+Cook 只保留 Web 一套代码,服务普通浏览器和云乐坊容器。技术栈:
-- [Capacitor](https://capacitorjs.com/)
-- [Ionic](https://ionicframework.com/)
-- [Nuxt Ionic](https://ionic.nuxtjs.org/)
+- [Nuxt 4](https://nuxt.com/)(Vue 3,CSR-only,静态生成)
+- [Ionic](https://ionicframework.com/) + [Nuxt Ionic](https://ionic.nuxtjs.org/)(Web UI 框架,与 Capacitor 无关)
+- [UnoCSS](https://unocss.dev/) 原子化样式
-## 云乐坊 SSO 回调
+原生 App(iOS / Android)的代码已随 [0004 只保留 Web,移除 Capacitor 原生壳](/decisions/0004-web-only) 一并移除。
-移动端使用系统浏览器打开云乐坊授权页,并通过已验证的 HTTPS Universal Links / App Links
-返回 `https://cook.yunyoujun.cn/auth/callback?platform=native`。不要改用自定义 URL Scheme;
-PKCE 能阻止授权码被旁路窃取,但不能阻止恶意 App 主动冒充公开客户端发起授权。
+## 云乐坊 SSO
-iOS 的 Associated Domains 与站点 `apple-app-site-association` 已纳入项目。Android 上架前还需用
-Google Play App Signing 的发布证书 SHA-256 生成站点文件
-`apps/web/public/.well-known/assetlinks.json`,关系必须限定为:
+Web 端有两种登录路径:
-```json
-[
- {
- "relation": ["delegate_permission/common.handle_all_urls"],
- "target": {
- "namespace": "android_app",
- "package_name": "cn.yunyoujun.cook",
- "sha256_cert_fingerprints": [""]
- }
- }
-]
-```
+- **在云乐坊 App 容器内**:通过宿主注入的 `window.ylf` JSAPI 直接请求宿主授权面板,用户不离开当前页面。
+- **在普通浏览器中**:走顶层重定向到云乐坊授权页,授权完成后回到
+ `https://cook.yunyoujun.cn/auth/callback`,由该页面换回登录票据。
-不要把本机 debug keystore 指纹发布到生产站点。完成证书配置后,需在真机验证已登录快捷授权、
-显式同意、取消、返回键、超时、伪造回调和授权码重放。
+回跳地址必须是已在云乐坊登记的 HTTPS 地址,且不能带 `?platform=native` 之类的原生标记。
+PKCE 能阻止授权码被旁路窃取,但不能阻止恶意客户端主动冒充公开客户端发起授权,
+因此不要放宽回跳地址的登记要求。
+
+回跳域名有多个时(`cook.yunyoujun.cn`、`cook.yunle.fun`),按当前页面 origin 选对应的那个,
+`yunlefunSsoRedirectUris` 里没登记的域名会直接判定为配置错误并拒绝登录。
diff --git a/docs/dev/ios-roadmap.md b/docs/dev/ios-roadmap.md
deleted file mode 100644
index c522c88..0000000
--- a/docs/dev/ios-roadmap.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# iOS App 打磨目标
-
-目标:做出一个能在 App Store 上架、值得用户付费的「食用手册」iOS App,同时 Web 继续可用。背景和取舍见 [0003 原生 iOS App 与 monorepo 结构](/decisions/0003-native-ios-monorepo)。
-
-每个阶段完成验收项后才进入下一阶段。数字类指标是起始目标,做出第一版后按实测调整。
-
-## M0 仓库改成 monorepo
-
-- [x] 把 Nuxt 应用搬到 `apps/web`、菜谱 CSV 和生成的 JSON 搬到 `packages/data`,只改路径不改逻辑。根目录的 `pnpm build` 仍然输出到 `dist/`,CI、EdgeOne、Netlify、Vercel、Docker、Capacitor 不用改配置。
-- [x] 食材词典、常备调料、别名改成 `packages/data` 里的 JSON(`food.json`、`pantry.json`、`aliases.json`),Web 和 iOS 读同一份。
-- [x] 两端共用的推荐用例 `packages/data/fixtures/recommend.json`,`pnpm fixtures` 生成,`pnpm test` 检查是否过期。`packages/cook` 的推荐逻辑本身不依赖 Vue / Node,不再单独拆 `packages/core`。
-
-验收:`pnpm lint`、`typecheck`、`test`、`build` 全绿;线上 Web 部署后行为不变;`pnpm eval:search` 指标与搬迁前一致。
-
-## M1 数据与核心逻辑两端一致
-
-- JSON 加 `schemaVersion`、`dataVersion` 和 JSON Schema。
-- 共享用例补上相克判断和搜索;收集到真实筛选信号后,把 `test/fixtures/search-eval.json` 也纳入。
-- `apps/ios/CookCore`(Swift Package)实现菜谱加载、推荐、搜索、相克判断。
-
-验收:TS 和 Swift 跑同一份用例全部通过;CI 两边都跑(Swift 部分可先用 Linux 上的 `swift test`,或 macOS runner)。
-
-## M2 iOS 第一版(可上 TestFlight)
-
-- 食材选择 → 推荐结果、菜谱详情(B 站视频跳转)、随机一道菜、收藏、浏览历史、设置。
-- 只用系统控件搭界面:`TabView`、`NavigationStack`、`List`、sheet,自动获得 Liquid Glass。
-- SwiftData 本地存储,CloudKit 同步收藏和历史。
-- 深色模式、动态字体、VoiceOver、横竖屏和 iPad 基本可用。
-
-验收:核心流程不依赖网络;冷启动到可点击不超过 1 秒(iPhone 12 级别设备);滚动无明显掉帧;VoiceOver 能走完「选食材 → 打开菜谱」;TestFlight 内测无崩溃。
-
-## M3 打磨
-
-- Widget:「今天吃什么」随机推荐、最近收藏。
-- App Intents / 快捷指令 / Siri:「我有土豆和鸡蛋,能做什么」。
-- Spotlight 索引菜谱,系统分享面板,触感反馈,空状态和引导页。
-- 菜谱数据在线更新(按 `dataVersion` 从 CDN 拉取),失败时用内置数据。
-- 从 Capacitor 版迁移:首次启动导入旧版收藏和历史(方案待验证,备选是旧版先同步到云端)。
-
-验收:每项功能有截图走查记录;旧版用户升级后收藏不丢;崩溃率和卡顿通过 Xcode Organizer 观察一周无异常。
-
-## M4 会员与上架
-
-- StoreKit 2 会员:CloudBase 跨平台同步,以及之后确定的高级功能;恢复购买;Web 已购会员登录后解锁。
-- 付费墙、隐私清单、App Store 截图和文案、审核备注。
-- 以更新的方式替换现有 `cn.yunyoujun.cook` 商店条目。
-
-验收:沙盒环境走通购买、续订、退订、恢复;审核通过并上架。
-
-## M5 收尾
-
-- 移除 Capacitor(`ios/`、`capacitor.config.ts`、`@capacitor/*`、`nativeSso` 等);`android/` 去留单独决定。
-- 更新 #98 的阶段 4 和 `docs/dev/app.md`。
-
-## 分工说明
-
-- 云端 Claude 可以完成 M0、M1 的 TS 部分、Swift 代码编写和纯逻辑测试。
-- Xcode 构建、模拟器和真机调试、TestFlight、App Store Connect 需要在你的 Mac 上进行(可以用 Remote Control 让 Claude 在你的电脑上跑)。
diff --git a/docs/guide/getting-started.md b/docs/guide/getting-started.md
index 99e5efd..680f617 100644
--- a/docs/guide/getting-started.md
+++ b/docs/guide/getting-started.md
@@ -55,48 +55,26 @@ pnpm build
pnpm preview
```
-### 移动应用
-
-#### iOS
-
-```bash
-# 构建 iOS 应用
-pnpm build:ios
-
-# 在 Xcode 中打开
-open ios/App/App.xcworkspace
-```
-
-#### Android
-
-```bash
-# 构建 Android 应用
-pnpm build:android
-
-# 在 Android Studio 中打开
-# File > Open > android/
-```
-
## 项目结构
```
cook/
-├── app/ # 应用源码
-│ ├── components/ # Vue 组件
-│ ├── composables/ # 组合式函数
-│ ├── data/ # 菜谱数据 (CSV + JSON)
-│ ├── pages/ # 页面路由
-│ └── utils/ # 工具函数
+├── apps/web/ # Web 应用(Nuxt)
+│ ├── app/ # 应用源码
+│ │ ├── components/ # Vue 组件
+│ │ ├── composables/# 组合式函数
+│ │ ├── pages/ # 页面路由
+│ │ └── utils/ # 工具函数
+│ └── public/ # 静态资源
├── docs/ # 文档网站
├── packages/
-│ └── cook/ # CLI 工具
-├── android/ # Android 应用
-├── ios/ # iOS 应用
-└── public/ # 静态资源
+│ ├── cook/ # CLI 工具与推荐/搜索核心
+│ └── data/ # 菜谱数据 (CSV + JSON)
+└── test/ # 测试
```
## 下一步
- 📖 查看 [CLI 文档](/dev/cli) 了解数据管理
-- 📱 查看 [移动应用开发](/dev/app) 了解跨平台构建
+- 💻 查看 [Web 应用开发](/dev/app) 了解技术栈与登录流程
- 🍳 开始添加你喜欢的菜谱!
diff --git a/eslint.config.js b/eslint.config.js
index f3df0fb..ea72e7a 100644
--- a/eslint.config.js
+++ b/eslint.config.js
@@ -11,8 +11,8 @@ export default nuxt(
{
ignores: [
'packages/data/**/*.json',
- 'ios/**/*',
- 'android/**/*',
+ // 设计原型静态稿,不是产品源码。
+ 'prototype/**/*',
'apps/web/public/**/*',
'node_modules/**/*',
'**/.nuxt/**/*',
diff --git a/ionic.config.json b/ionic.config.json
deleted file mode 100644
index 04bb007..0000000
--- a/ionic.config.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "name": "cook",
- "integrations": {
- "capacitor": {}
- },
- "type": "vue"
-}
diff --git a/ios/.gitignore b/ios/.gitignore
deleted file mode 100644
index f470299..0000000
--- a/ios/.gitignore
+++ /dev/null
@@ -1,13 +0,0 @@
-App/build
-App/Pods
-App/output
-App/App/public
-DerivedData
-xcuserdata
-
-# Cordova plugins for Capacitor
-capacitor-cordova-ios-plugins
-
-# Generated Config files
-App/App/capacitor.config.json
-App/App/config.xml
diff --git a/ios/App/App.xcodeproj/project.pbxproj b/ios/App/App.xcodeproj/project.pbxproj
deleted file mode 100644
index 8f15de8..0000000
--- a/ios/App/App.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,416 +0,0 @@
-// !$*UTF8*$!
-{
- archiveVersion = 1;
- classes = {
- };
- objectVersion = 48;
- objects = {
-
-/* Begin PBXBuildFile section */
- 2FAD9763203C412B000D30F8 /* config.xml in Resources */ = {isa = PBXBuildFile; fileRef = 2FAD9762203C412B000D30F8 /* config.xml */; };
- 50379B232058CBB4000EE86E /* capacitor.config.json in Resources */ = {isa = PBXBuildFile; fileRef = 50379B222058CBB4000EE86E /* capacitor.config.json */; };
- 504EC3081FED79650016851F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 504EC3071FED79650016851F /* AppDelegate.swift */; };
- 019FF4A10000000000000001 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 019FF4A10000000000000002 /* SceneDelegate.swift */; };
- 504EC30D1FED79650016851F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 504EC30B1FED79650016851F /* Main.storyboard */; };
- 504EC30F1FED79650016851F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 504EC30E1FED79650016851F /* Assets.xcassets */; };
- 504EC3121FED79650016851F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 504EC3101FED79650016851F /* LaunchScreen.storyboard */; };
- 50B271D11FEDC1A000F3C39B /* public in Resources */ = {isa = PBXBuildFile; fileRef = 50B271D01FEDC1A000F3C39B /* public */; };
- A084ECDBA7D38E1E42DFC39D /* Pods_App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF277DCFFFF123FFC6DF26C7 /* Pods_App.framework */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXFileReference section */
- 2FAD9762203C412B000D30F8 /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = config.xml; sourceTree = ""; };
- 50379B222058CBB4000EE86E /* capacitor.config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = capacitor.config.json; sourceTree = ""; };
- 504EC3041FED79650016851F /* App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = App.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 504EC3071FED79650016851F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
- 019FF4A10000000000000002 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; };
- 504EC30C1FED79650016851F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
- 504EC30E1FED79650016851F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
- 504EC3111FED79650016851F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
- 504EC3131FED79650016851F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
- 50B271D01FEDC1A000F3C39B /* public */ = {isa = PBXFileReference; lastKnownFileType = folder; path = public; sourceTree = ""; };
- AF277DCFFFF123FFC6DF26C7 /* Pods_App.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_App.framework; sourceTree = BUILT_PRODUCTS_DIR; };
- AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.release.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.release.xcconfig"; sourceTree = ""; };
- FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.debug.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.debug.xcconfig"; sourceTree = ""; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
- 504EC3011FED79650016851F /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- A084ECDBA7D38E1E42DFC39D /* Pods_App.framework in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
- 27E2DDA53C4D2A4D1A88CE4A /* Frameworks */ = {
- isa = PBXGroup;
- children = (
- AF277DCFFFF123FFC6DF26C7 /* Pods_App.framework */,
- );
- name = Frameworks;
- sourceTree = "";
- };
- 504EC2FB1FED79650016851F = {
- isa = PBXGroup;
- children = (
- 504EC3061FED79650016851F /* App */,
- 504EC3051FED79650016851F /* Products */,
- 7F8756D8B27F46E3366F6CEA /* Pods */,
- 27E2DDA53C4D2A4D1A88CE4A /* Frameworks */,
- );
- sourceTree = "";
- };
- 504EC3051FED79650016851F /* Products */ = {
- isa = PBXGroup;
- children = (
- 504EC3041FED79650016851F /* App.app */,
- );
- name = Products;
- sourceTree = "";
- };
- 504EC3061FED79650016851F /* App */ = {
- isa = PBXGroup;
- children = (
- 50379B222058CBB4000EE86E /* capacitor.config.json */,
- 504EC3071FED79650016851F /* AppDelegate.swift */,
- 019FF4A10000000000000002 /* SceneDelegate.swift */,
- 504EC30B1FED79650016851F /* Main.storyboard */,
- 504EC30E1FED79650016851F /* Assets.xcassets */,
- 504EC3101FED79650016851F /* LaunchScreen.storyboard */,
- 504EC3131FED79650016851F /* Info.plist */,
- 2FAD9762203C412B000D30F8 /* config.xml */,
- 50B271D01FEDC1A000F3C39B /* public */,
- );
- path = App;
- sourceTree = "";
- };
- 7F8756D8B27F46E3366F6CEA /* Pods */ = {
- isa = PBXGroup;
- children = (
- FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */,
- AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */,
- );
- name = Pods;
- sourceTree = "";
- };
-/* End PBXGroup section */
-
-/* Begin PBXNativeTarget section */
- 504EC3031FED79650016851F /* App */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = 504EC3161FED79650016851F /* Build configuration list for PBXNativeTarget "App" */;
- buildPhases = (
- 6634F4EFEBD30273BCE97C65 /* [CP] Check Pods Manifest.lock */,
- 504EC3001FED79650016851F /* Sources */,
- 504EC3011FED79650016851F /* Frameworks */,
- 504EC3021FED79650016851F /* Resources */,
- 9592DBEFFC6D2A0C8D5DEB22 /* [CP] Embed Pods Frameworks */,
- );
- buildRules = (
- );
- dependencies = (
- );
- name = App;
- productName = App;
- productReference = 504EC3041FED79650016851F /* App.app */;
- productType = "com.apple.product-type.application";
- };
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
- 504EC2FC1FED79650016851F /* Project object */ = {
- isa = PBXProject;
- attributes = {
- LastSwiftUpdateCheck = 0920;
- LastUpgradeCheck = 0920;
- TargetAttributes = {
- 504EC3031FED79650016851F = {
- CreatedOnToolsVersion = 9.2;
- LastSwiftMigration = 1100;
- ProvisioningStyle = Automatic;
- };
- };
- };
- buildConfigurationList = 504EC2FF1FED79650016851F /* Build configuration list for PBXProject "App" */;
- compatibilityVersion = "Xcode 8.0";
- developmentRegion = en;
- hasScannedForEncodings = 0;
- knownRegions = (
- en,
- Base,
- );
- mainGroup = 504EC2FB1FED79650016851F;
- packageReferences = (
- );
- productRefGroup = 504EC3051FED79650016851F /* Products */;
- projectDirPath = "";
- projectRoot = "";
- targets = (
- 504EC3031FED79650016851F /* App */,
- );
- };
-/* End PBXProject section */
-
-/* Begin PBXResourcesBuildPhase section */
- 504EC3021FED79650016851F /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 504EC3121FED79650016851F /* LaunchScreen.storyboard in Resources */,
- 50B271D11FEDC1A000F3C39B /* public in Resources */,
- 504EC30F1FED79650016851F /* Assets.xcassets in Resources */,
- 50379B232058CBB4000EE86E /* capacitor.config.json in Resources */,
- 504EC30D1FED79650016851F /* Main.storyboard in Resources */,
- 2FAD9763203C412B000D30F8 /* config.xml in Resources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXResourcesBuildPhase section */
-
-/* Begin PBXShellScriptBuildPhase section */
- 6634F4EFEBD30273BCE97C65 /* [CP] Check Pods Manifest.lock */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
- "${PODS_ROOT}/Manifest.lock",
- );
- name = "[CP] Check Pods Manifest.lock";
- outputPaths = (
- "$(DERIVED_FILE_DIR)/Pods-App-checkManifestLockResult.txt",
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
- showEnvVarsInLog = 0;
- };
- 9592DBEFFC6D2A0C8D5DEB22 /* [CP] Embed Pods Frameworks */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- name = "[CP] Embed Pods Frameworks";
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-App/Pods-App-frameworks.sh\"\n";
- showEnvVarsInLog = 0;
- };
-/* End PBXShellScriptBuildPhase section */
-
-/* Begin PBXSourcesBuildPhase section */
- 504EC3001FED79650016851F /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 504EC3081FED79650016851F /* AppDelegate.swift in Sources */,
- 019FF4A10000000000000001 /* SceneDelegate.swift in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXSourcesBuildPhase section */
-
-/* Begin PBXVariantGroup section */
- 504EC30B1FED79650016851F /* Main.storyboard */ = {
- isa = PBXVariantGroup;
- children = (
- 504EC30C1FED79650016851F /* Base */,
- );
- name = Main.storyboard;
- sourceTree = "";
- };
- 504EC3101FED79650016851F /* LaunchScreen.storyboard */ = {
- isa = PBXVariantGroup;
- children = (
- 504EC3111FED79650016851F /* Base */,
- );
- name = LaunchScreen.storyboard;
- sourceTree = "";
- };
-/* End PBXVariantGroup section */
-
-/* Begin XCBuildConfiguration section */
- 504EC3141FED79650016851F /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- CLANG_ANALYZER_NONNULL = YES;
- CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
- CLANG_CXX_LIBRARY = "libc++";
- CLANG_ENABLE_MODULES = YES;
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_COMMA = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INFINITE_RECURSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
- CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
- CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
- CLANG_WARN_STRICT_PROTOTYPES = YES;
- CLANG_WARN_SUSPICIOUS_MOVE = YES;
- CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- CODE_SIGN_IDENTITY = "iPhone Developer";
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = dwarf;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- ENABLE_TESTABILITY = YES;
- GCC_C_LANGUAGE_STANDARD = gnu11;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PREPROCESSOR_DEFINITIONS = (
- "DEBUG=1",
- "$(inherited)",
- );
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 15.0;
- MTL_ENABLE_DEBUG_INFO = YES;
- ONLY_ACTIVE_ARCH = YES;
- SDKROOT = iphoneos;
- SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
- SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- };
- name = Debug;
- };
- 504EC3151FED79650016851F /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- CLANG_ANALYZER_NONNULL = YES;
- CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
- CLANG_CXX_LIBRARY = "libc++";
- CLANG_ENABLE_MODULES = YES;
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_COMMA = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INFINITE_RECURSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
- CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
- CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
- CLANG_WARN_STRICT_PROTOTYPES = YES;
- CLANG_WARN_SUSPICIOUS_MOVE = YES;
- CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- CODE_SIGN_IDENTITY = "iPhone Developer";
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- ENABLE_NS_ASSERTIONS = NO;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- GCC_C_LANGUAGE_STANDARD = gnu11;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 15.0;
- MTL_ENABLE_DEBUG_INFO = NO;
- SDKROOT = iphoneos;
- SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
- VALIDATE_PRODUCT = YES;
- };
- name = Release;
- };
- 504EC3171FED79650016851F /* Debug */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */;
- buildSettings = {
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- CODE_SIGN_ENTITLEMENTS = App/App.entitlements;
- CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 1;
- DEVELOPMENT_TEAM = N3885VFNCL;
- INFOPLIST_FILE = App/Info.plist;
- IPHONEOS_DEPLOYMENT_TARGET = 15.0;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
- MARKETING_VERSION = 1.0;
- OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
- PRODUCT_BUNDLE_IDENTIFIER = cn.yunyoujun.cook;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
- SWIFT_VERSION = 5.0;
- TARGETED_DEVICE_FAMILY = "1,2";
- };
- name = Debug;
- };
- 504EC3181FED79650016851F /* Release */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */;
- buildSettings = {
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- CODE_SIGN_ENTITLEMENTS = App/App.entitlements;
- CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 1;
- DEVELOPMENT_TEAM = N3885VFNCL;
- INFOPLIST_FILE = App/Info.plist;
- IPHONEOS_DEPLOYMENT_TARGET = 15.0;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
- MARKETING_VERSION = 1.0;
- PRODUCT_BUNDLE_IDENTIFIER = cn.yunyoujun.cook;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_ACTIVE_COMPILATION_CONDITIONS = "";
- SWIFT_VERSION = 5.0;
- TARGETED_DEVICE_FAMILY = "1,2";
- };
- name = Release;
- };
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
- 504EC2FF1FED79650016851F /* Build configuration list for PBXProject "App" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 504EC3141FED79650016851F /* Debug */,
- 504EC3151FED79650016851F /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- 504EC3161FED79650016851F /* Build configuration list for PBXNativeTarget "App" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 504EC3171FED79650016851F /* Debug */,
- 504EC3181FED79650016851F /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
-/* End XCConfigurationList section */
- };
- rootObject = 504EC2FC1FED79650016851F /* Project object */;
-}
diff --git a/ios/App/App.xcworkspace/contents.xcworkspacedata b/ios/App/App.xcworkspace/contents.xcworkspacedata
deleted file mode 100644
index b301e82..0000000
--- a/ios/App/App.xcworkspace/contents.xcworkspacedata
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
diff --git a/ios/App/App.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/App/App.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
deleted file mode 100644
index 18d9810..0000000
--- a/ios/App/App.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
- IDEDidComputeMac32BitWarning
-
-
-
diff --git a/ios/App/App/App.entitlements b/ios/App/App/App.entitlements
deleted file mode 100644
index 732fcf9..0000000
--- a/ios/App/App/App.entitlements
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
- com.apple.developer.associated-domains
-
- applinks:cook.yunyoujun.cn
-
-
-
diff --git a/ios/App/App/AppDelegate.swift b/ios/App/App/AppDelegate.swift
deleted file mode 100644
index 8ccc4e8..0000000
--- a/ios/App/App/AppDelegate.swift
+++ /dev/null
@@ -1,58 +0,0 @@
-import UIKit
-import Capacitor
-
-@UIApplicationMain
-class AppDelegate: UIResponder, UIApplicationDelegate {
-
- var window: UIWindow?
-
- func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
- // Override point for customization after application launch.
- return true
- }
-
- func applicationWillResignActive(_ application: UIApplication) {
- // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
- // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
- }
-
- func applicationDidEnterBackground(_ application: UIApplication) {
- // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
- // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
- }
-
- func applicationWillEnterForeground(_ application: UIApplication) {
- // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
- }
-
- func applicationDidBecomeActive(_ application: UIApplication) {
- // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
- }
-
- func applicationWillTerminate(_ application: UIApplication) {
- // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
- }
-
- func application(_ application: UIApplication,
- configurationForConnecting connectingSceneSession: UISceneSession,
- options: UIScene.ConnectionOptions) -> UISceneConfiguration {
- let config = UISceneConfiguration(name: "Default Configuration",
- sessionRole: connectingSceneSession.role)
- config.delegateClass = SceneDelegate.self
- return config
- }
-
- func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
- // Called when the app was launched with a url. Feel free to add additional processing here,
- // but if you want the App API to support tracking app url opens, make sure to keep this call
- return ApplicationDelegateProxy.shared.application(app, open: url, options: options)
- }
-
- func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
- // Called when the app was launched with an activity, including Universal Links.
- // Feel free to add additional processing here, but if you want the App API to support
- // tracking app url opens, make sure to keep this call
- return ApplicationDelegateProxy.shared.application(application, continue: userActivity, restorationHandler: restorationHandler)
- }
-
-}
diff --git a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png b/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png
deleted file mode 100644
index 89cc39f..0000000
Binary files a/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png and /dev/null differ
diff --git a/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json
deleted file mode 100644
index 00b5bd3..0000000
--- a/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "images": [
- {
- "filename": "AppIcon-512@2x.png",
- "idiom": "universal",
- "platform": "ios",
- "size": "1024x1024"
- }
- ],
- "info": {
- "author": "xcode",
- "version": 1
- }
-}
diff --git a/ios/App/App/Assets.xcassets/Contents.json b/ios/App/App/Assets.xcassets/Contents.json
deleted file mode 100644
index 97a8662..0000000
--- a/ios/App/App/Assets.xcassets/Contents.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "info": {
- "version": 1,
- "author": "xcode"
- }
-}
diff --git a/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json b/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json
deleted file mode 100644
index b781492..0000000
--- a/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "images": [
- {
- "idiom": "universal",
- "filename": "splash-2732x2732-2.png",
- "scale": "1x"
- },
- {
- "idiom": "universal",
- "filename": "splash-2732x2732-1.png",
- "scale": "2x"
- },
- {
- "idiom": "universal",
- "filename": "splash-2732x2732.png",
- "scale": "3x"
- }
- ],
- "info": {
- "version": 1,
- "author": "xcode"
- }
-}
diff --git a/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png b/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png
deleted file mode 100644
index 33ea6c9..0000000
Binary files a/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png and /dev/null differ
diff --git a/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png b/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png
deleted file mode 100644
index 33ea6c9..0000000
Binary files a/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png and /dev/null differ
diff --git a/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png b/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png
deleted file mode 100644
index 33ea6c9..0000000
Binary files a/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png and /dev/null differ
diff --git a/ios/App/App/Base.lproj/LaunchScreen.storyboard b/ios/App/App/Base.lproj/LaunchScreen.storyboard
deleted file mode 100644
index e7ae5d7..0000000
--- a/ios/App/App/Base.lproj/LaunchScreen.storyboard
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/ios/App/App/Base.lproj/Main.storyboard b/ios/App/App/Base.lproj/Main.storyboard
deleted file mode 100644
index b44df7b..0000000
--- a/ios/App/App/Base.lproj/Main.storyboard
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/ios/App/App/Info.plist b/ios/App/App/Info.plist
deleted file mode 100644
index 71bca43..0000000
--- a/ios/App/App/Info.plist
+++ /dev/null
@@ -1,68 +0,0 @@
-
-
-
-
- CFBundleDevelopmentRegion
- en
- CFBundleDisplayName
- 食用手册
- CFBundleExecutable
- $(EXECUTABLE_NAME)
- CFBundleIdentifier
- $(PRODUCT_BUNDLE_IDENTIFIER)
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- $(PRODUCT_NAME)
- CFBundlePackageType
- APPL
- CFBundleShortVersionString
- $(MARKETING_VERSION)
- CFBundleVersion
- $(CURRENT_PROJECT_VERSION)
- LSRequiresIPhoneOS
-
- UILaunchStoryboardName
- LaunchScreen
- UIMainStoryboardFile
- Main
- UIApplicationSceneManifest
-
- UIApplicationSupportsMultipleScenes
-
- UISceneConfigurations
-
- UIWindowSceneSessionRoleApplication
-
-
- UISceneConfigurationName
- Default Configuration
- UISceneDelegateClassName
- $(PRODUCT_MODULE_NAME).SceneDelegate
- UISceneStoryboardFile
- Main
-
-
-
-
- UIRequiredDeviceCapabilities
-
- armv7
-
- UISupportedInterfaceOrientations
-
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
-
- UISupportedInterfaceOrientations~ipad
-
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationPortraitUpsideDown
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
-
- UIViewControllerBasedStatusBarAppearance
-
-
-
diff --git a/ios/App/App/SceneDelegate.swift b/ios/App/App/SceneDelegate.swift
deleted file mode 100644
index f0e4eaa..0000000
--- a/ios/App/App/SceneDelegate.swift
+++ /dev/null
@@ -1,22 +0,0 @@
-import UIKit
-import Capacitor
-
-class SceneDelegate: UIResponder, UIWindowSceneDelegate {
- var window: UIWindow?
-
- func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
- guard let windowScene = scene as? UIWindowScene else { return }
- window = UIWindow(windowScene: windowScene)
- window?.rootViewController = CAPBridgeViewController()
- window?.makeKeyAndVisible()
- SceneDelegateProxy.shared.scene(scene, willConnectTo: session, options: connectionOptions)
- }
-
- func scene(_ scene: UIScene, openURLContexts URLContexts: Set) {
- SceneDelegateProxy.shared.scene(scene, openURLContexts: URLContexts)
- }
-
- func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
- SceneDelegateProxy.shared.scene(scene, continue: userActivity)
- }
-}
diff --git a/ios/App/Podfile b/ios/App/Podfile
deleted file mode 100644
index cd0bc6b..0000000
--- a/ios/App/Podfile
+++ /dev/null
@@ -1,30 +0,0 @@
-require_relative '../../node_modules/.pnpm/@capacitor+ios@8.5.0_@capacitor+core@8.5.0/node_modules/@capacitor/ios/scripts/pods_helpers'
-
-platform :ios, '15.0'
-use_frameworks!
-
-# workaround to avoid Xcode caching of Pods that requires
-# Product -> Clean Build Folder after new Cordova plugins installed
-# Requires CocoaPods 1.6 or newer
-install! 'cocoapods', :disable_input_output_paths => true
-
-def capacitor_pods
- pod 'Capacitor', :path => '../../node_modules/.pnpm/@capacitor+ios@8.5.0_@capacitor+core@8.5.0/node_modules/@capacitor/ios'
- pod 'CapacitorCordova', :path => '../../node_modules/.pnpm/@capacitor+ios@8.5.0_@capacitor+core@8.5.0/node_modules/@capacitor/ios'
- pod 'CapacitorApp', :path => '../../node_modules/.pnpm/@capacitor+app@8.1.1_@capacitor+core@8.5.0/node_modules/@capacitor/app'
- pod 'CapacitorBrowser', :path => '../../node_modules/.pnpm/@capacitor+browser@8.0.4_@capacitor+core@8.5.0/node_modules/@capacitor/browser'
- pod 'CapacitorDialog', :path => '../../node_modules/.pnpm/@capacitor+dialog@8.0.1_@capacitor+core@8.5.0/node_modules/@capacitor/dialog'
- pod 'CapacitorHaptics', :path => '../../node_modules/.pnpm/@capacitor+haptics@8.0.2_@capacitor+core@8.5.0/node_modules/@capacitor/haptics'
- pod 'CapacitorKeyboard', :path => '../../node_modules/.pnpm/@capacitor+keyboard@8.0.5_@capacitor+core@8.5.0/node_modules/@capacitor/keyboard'
- pod 'CapacitorPreferences', :path => '../../node_modules/.pnpm/@capacitor+preferences@8.0.1_@capacitor+core@8.5.0/node_modules/@capacitor/preferences'
- pod 'CapacitorStatusBar', :path => '../../node_modules/.pnpm/@capacitor+status-bar@8.0.3_@capacitor+core@8.5.0/node_modules/@capacitor/status-bar'
-end
-
-target 'App' do
- capacitor_pods
- # Add your Pods here
-end
-
-post_install do |installer|
- assertDeploymentTarget(installer)
-end
diff --git a/ios/App/Podfile.lock b/ios/App/Podfile.lock
deleted file mode 100644
index 37f97b9..0000000
--- a/ios/App/Podfile.lock
+++ /dev/null
@@ -1,64 +0,0 @@
-PODS:
- - Capacitor (8.5.0):
- - CapacitorCordova
- - CapacitorApp (8.1.1):
- - Capacitor
- - CapacitorBrowser (8.0.4):
- - Capacitor
- - CapacitorCordova (8.5.0)
- - CapacitorDialog (8.0.1):
- - Capacitor
- - CapacitorHaptics (8.0.2):
- - Capacitor
- - CapacitorKeyboard (8.0.5):
- - Capacitor
- - CapacitorPreferences (8.0.1):
- - Capacitor
- - CapacitorStatusBar (8.0.3):
- - Capacitor
-
-DEPENDENCIES:
- - "Capacitor (from `../../node_modules/.pnpm/@capacitor+ios@8.5.0_@capacitor+core@8.5.0/node_modules/@capacitor/ios`)"
- - "CapacitorApp (from `../../node_modules/.pnpm/@capacitor+app@8.1.1_@capacitor+core@8.5.0/node_modules/@capacitor/app`)"
- - "CapacitorBrowser (from `../../node_modules/.pnpm/@capacitor+browser@8.0.4_@capacitor+core@8.5.0/node_modules/@capacitor/browser`)"
- - "CapacitorCordova (from `../../node_modules/.pnpm/@capacitor+ios@8.5.0_@capacitor+core@8.5.0/node_modules/@capacitor/ios`)"
- - "CapacitorDialog (from `../../node_modules/.pnpm/@capacitor+dialog@8.0.1_@capacitor+core@8.5.0/node_modules/@capacitor/dialog`)"
- - "CapacitorHaptics (from `../../node_modules/.pnpm/@capacitor+haptics@8.0.2_@capacitor+core@8.5.0/node_modules/@capacitor/haptics`)"
- - "CapacitorKeyboard (from `../../node_modules/.pnpm/@capacitor+keyboard@8.0.5_@capacitor+core@8.5.0/node_modules/@capacitor/keyboard`)"
- - "CapacitorPreferences (from `../../node_modules/.pnpm/@capacitor+preferences@8.0.1_@capacitor+core@8.5.0/node_modules/@capacitor/preferences`)"
- - "CapacitorStatusBar (from `../../node_modules/.pnpm/@capacitor+status-bar@8.0.3_@capacitor+core@8.5.0/node_modules/@capacitor/status-bar`)"
-
-EXTERNAL SOURCES:
- Capacitor:
- :path: "../../node_modules/.pnpm/@capacitor+ios@8.5.0_@capacitor+core@8.5.0/node_modules/@capacitor/ios"
- CapacitorApp:
- :path: "../../node_modules/.pnpm/@capacitor+app@8.1.1_@capacitor+core@8.5.0/node_modules/@capacitor/app"
- CapacitorBrowser:
- :path: "../../node_modules/.pnpm/@capacitor+browser@8.0.4_@capacitor+core@8.5.0/node_modules/@capacitor/browser"
- CapacitorCordova:
- :path: "../../node_modules/.pnpm/@capacitor+ios@8.5.0_@capacitor+core@8.5.0/node_modules/@capacitor/ios"
- CapacitorDialog:
- :path: "../../node_modules/.pnpm/@capacitor+dialog@8.0.1_@capacitor+core@8.5.0/node_modules/@capacitor/dialog"
- CapacitorHaptics:
- :path: "../../node_modules/.pnpm/@capacitor+haptics@8.0.2_@capacitor+core@8.5.0/node_modules/@capacitor/haptics"
- CapacitorKeyboard:
- :path: "../../node_modules/.pnpm/@capacitor+keyboard@8.0.5_@capacitor+core@8.5.0/node_modules/@capacitor/keyboard"
- CapacitorPreferences:
- :path: "../../node_modules/.pnpm/@capacitor+preferences@8.0.1_@capacitor+core@8.5.0/node_modules/@capacitor/preferences"
- CapacitorStatusBar:
- :path: "../../node_modules/.pnpm/@capacitor+status-bar@8.0.3_@capacitor+core@8.5.0/node_modules/@capacitor/status-bar"
-
-SPEC CHECKSUMS:
- Capacitor: 00b87168591cc006ea6f5c0de681ec5c39a2c8eb
- CapacitorApp: 305bd13c44f6f9d164e2ee66a4faa956ed8c0e06
- CapacitorBrowser: 752e0208aa07c7aa63d1f7cde895a3e9519b2656
- CapacitorCordova: 9d3acbb574048e7167d2af127a0af2123e619f2f
- CapacitorDialog: 854c5dac405081cae697c177ca43bcaa95ae67bf
- CapacitorHaptics: 296f771ecd89c7a1bd92a7b6826a7d268e2e70f5
- CapacitorKeyboard: b6b0744890cdb1d9a96e2cafcc9253fdcc55de3b
- CapacitorPreferences: cca2021f386efb75947c850334447d9ff22b14f1
- CapacitorStatusBar: eca7bc2b58d9f886f1ef9edb66e57a9b29c121af
-
-PODFILE CHECKSUM: 7777423e7d2feb91cce29e1870d3b5b2ddd10758
-
-COCOAPODS: 1.17.0
diff --git a/package.json b/package.json
index ef75c8d..87d28e5 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,6 @@
"build": "pnpm run convert && pnpm -C apps/web run generate && tsx scripts/copy-web-output.ts",
"build:full": "pnpm run build",
"build:nuxt": "pnpm -C apps/web run build",
- "build:android": "bash ./scripts/android/build.sh",
"convert": "pnpm -C packages/cook run convert",
"validate": "tsx scripts/validate-recipes.ts",
"check:videos": "tsx scripts/check-video-links.ts",
@@ -21,13 +20,6 @@
"fixtures": "tsx scripts/gen-fixtures.ts",
"dev": "pnpm -C apps/web run dev",
"dev:pwa": "pnpm -C apps/web run dev:pwa",
- "dev:android": "bash ./scripts/android/dev.sh",
- "bash:ios": "bash ./scripts/ios.sh",
- "dev:ios": "cap run ios -l",
- "ios": "cap run ios",
- "android": "cap run android",
- "open:ios": "cap open ios",
- "open:android": "cap open android",
"docs:dev": "pnpm -C docs run docs:dev",
"docs:build": "pnpm -C docs run docs:build",
"generate": "pnpm -C apps/web run generate && tsx scripts/copy-web-output.ts",
@@ -36,27 +28,13 @@
"lint": "eslint .",
"preview": "pnpm -C apps/web run preview",
"release": "bumpp",
- "sync": "cap sync",
"test": "vitest",
"test:coverage": "vitest run --coverage",
"typecheck": "pnpm -C packages/cook run build && pnpm -C apps/web run typecheck",
"pack:skill": "tsx scripts/pack-skill.ts"
},
- "dependencies": {
- "@capacitor/app": "8.1.1",
- "@capacitor/browser": "8.0.4",
- "@capacitor/core": "8.5.0",
- "@capacitor/dialog": "8.0.1",
- "@capacitor/haptics": "8.0.2",
- "@capacitor/ios": "8.5.0",
- "@capacitor/keyboard": "8.0.5",
- "@capacitor/preferences": "8.0.1",
- "@capacitor/status-bar": "8.0.3"
- },
"devDependencies": {
"@antfu/eslint-config": "^8.3.0",
- "@capacitor/android": "8.5.0",
- "@capacitor/cli": "8.5.0",
"@types/node": "^25.9.5",
"@unocss/eslint-config": "^66.7.5",
"@vue/test-utils": "^2.4.11",
diff --git a/packages/cook/README.md b/packages/cook/README.md
index c20214d..029154e 100644
--- a/packages/cook/README.md
+++ b/packages/cook/README.md
@@ -5,7 +5,7 @@ Cook CLI 工具 - 用于管理菜谱数据和检索菜谱的命令行工具。
## 功能
- 🔍 按食材/厨具/难度/标签/做法检索菜谱(支持食材别名)
-- CSV ↔ JSON 双向转换
+- CSV ↔ JSON 双向转换
- ✅ 完整的单元测试覆盖
- 🔄 数据格式一致性保证
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 93c0f03..03d371d 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -14,44 +14,10 @@ overrides:
importers:
.:
- dependencies:
- '@capacitor/app':
- specifier: 8.1.1
- version: 8.1.1(@capacitor/core@8.5.0)
- '@capacitor/browser':
- specifier: 8.0.4
- version: 8.0.4(@capacitor/core@8.5.0)
- '@capacitor/core':
- specifier: 8.5.0
- version: 8.5.0
- '@capacitor/dialog':
- specifier: 8.0.1
- version: 8.0.1(@capacitor/core@8.5.0)
- '@capacitor/haptics':
- specifier: 8.0.2
- version: 8.0.2(@capacitor/core@8.5.0)
- '@capacitor/ios':
- specifier: 8.5.0
- version: 8.5.0(@capacitor/core@8.5.0)
- '@capacitor/keyboard':
- specifier: 8.0.5
- version: 8.0.5(@capacitor/core@8.5.0)
- '@capacitor/preferences':
- specifier: 8.0.1
- version: 8.0.1(@capacitor/core@8.5.0)
- '@capacitor/status-bar':
- specifier: 8.0.3
- version: 8.0.3(@capacitor/core@8.5.0)
devDependencies:
'@antfu/eslint-config':
specifier: ^8.3.0
version: 8.3.0(@typescript-eslint/typescript-estree@8.67.0(supports-color@10.2.2)(typescript@5.9.3))(@typescript-eslint/utils@8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3))(@unocss/eslint-plugin@66.7.5(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3))(@vue/compiler-sfc@3.5.41)(eslint-plugin-format@2.0.1(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)))(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3)(vitest@4.1.10(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@29.1.1(@noble/hashes@1.8.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))
- '@capacitor/android':
- specifier: 8.5.0
- version: 8.5.0(@capacitor/core@8.5.0)
- '@capacitor/cli':
- specifier: 8.5.0
- version: 8.5.0(supports-color@10.2.2)
'@types/node':
specifier: ^25.9.5
version: 25.9.5
@@ -112,30 +78,6 @@ importers:
apps/web:
dependencies:
- '@capacitor/app':
- specifier: 8.1.1
- version: 8.1.1(@capacitor/core@8.5.0)
- '@capacitor/browser':
- specifier: 8.0.4
- version: 8.0.4(@capacitor/core@8.5.0)
- '@capacitor/core':
- specifier: 8.5.0
- version: 8.5.0
- '@capacitor/dialog':
- specifier: 8.0.1
- version: 8.0.1(@capacitor/core@8.5.0)
- '@capacitor/haptics':
- specifier: 8.0.2
- version: 8.0.2(@capacitor/core@8.5.0)
- '@capacitor/keyboard':
- specifier: 8.0.5
- version: 8.0.5(@capacitor/core@8.5.0)
- '@capacitor/preferences':
- specifier: 8.0.1
- version: 8.0.1(@capacitor/core@8.5.0)
- '@capacitor/status-bar':
- specifier: 8.0.3
- version: 8.0.3(@capacitor/core@8.5.0)
'@cloudbase/js-sdk':
specifier: 3.7.1
version: 3.7.1
@@ -178,13 +120,13 @@ importers:
version: 1.2.5
'@nuxt/devtools':
specifier: ^3.4.1
- version: 3.4.1(@capacitor/preferences@8.0.1(@capacitor/core@8.5.0))(db0@0.3.4)(ioredis@5.11.1(supports-color@10.2.2))(magic-string@1.1.0)(oxc-parser@0.140.0)(rolldown@1.2.3)(supports-color@10.2.2)(unplugin@3.3.0(esbuild@0.28.2)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(vue@3.5.41(typescript@5.9.3))
+ version: 3.4.1(db0@0.3.4)(ioredis@5.11.1(supports-color@10.2.2))(magic-string@1.1.0)(oxc-parser@0.140.0)(rolldown@1.2.3)(supports-color@10.2.2)(unplugin@3.3.0(esbuild@0.28.2)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(vue@3.5.41(typescript@5.9.3))
'@nuxt/eslint':
specifier: ^1.17.0
version: 1.17.0(@typescript-eslint/utils@8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@5.9.3))(@vue/compiler-sfc@3.5.41)(esbuild@0.28.2)(eslint-plugin-format@2.0.1(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2)))(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(magic-string@1.1.0)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.3)(rollup@4.62.4)(srvx@0.12.5)(supports-color@10.2.2)(typescript@5.9.3)(unplugin@3.3.0(esbuild@0.28.2)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))
'@nuxt/scripts':
specifier: ^1.3.3
- version: 1.3.3(@capacitor/preferences@8.0.1(@capacitor/core@8.5.0))(@oxc-project/types@0.143.0)(@unhead/vue@3.3.1(@oxc-project/types@0.143.0)(esbuild@0.28.2)(lightningcss@1.33.0)(oxc-parser@0.140.0)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(vue@3.5.41(typescript@5.9.3)))(db0@0.3.4)(esbuild@0.28.2)(ioredis@5.11.1(supports-color@10.2.2))(magicast@0.5.4)(rolldown@1.2.3)(rollup@4.62.4)(typescript@5.9.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(vue@3.5.41(typescript@5.9.3))
+ version: 1.3.3(@oxc-project/types@0.143.0)(@unhead/vue@3.3.1(@oxc-project/types@0.143.0)(esbuild@0.28.2)(lightningcss@1.33.0)(oxc-parser@0.140.0)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(vue@3.5.41(typescript@5.9.3)))(db0@0.3.4)(esbuild@0.28.2)(ioredis@5.11.1(supports-color@10.2.2))(magicast@0.5.4)(rolldown@1.2.3)(rollup@4.62.4)(typescript@5.9.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(vue@3.5.41(typescript@5.9.3))
'@nuxt/test-utils':
specifier: ^4.1.0
version: 4.1.0(@vue/test-utils@2.4.11(@vue/compiler-dom@3.5.41)(@vue/server-renderer@3.5.41)(vue@3.5.41(typescript@5.9.3)))(esbuild@0.28.2)(jsdom@29.1.1(@noble/hashes@1.8.0))(magicast@0.5.4)(rolldown@1.2.3)(rollup@4.62.4)(typescript@5.9.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(vitest@4.1.10(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@29.1.1(@noble/hashes@1.8.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))
@@ -211,19 +153,19 @@ importers:
version: 14.4.0(vue@3.5.41(typescript@5.9.3))
'@vueuse/nuxt':
specifier: ^14.4.0
- version: 14.4.0(magic-string@1.1.0)(magicast@0.5.4)(nuxt@4.5.2(0f4a3527db7795df392b465c3de4796e))(oxc-parser@0.140.0)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.2)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0)))(vue@3.5.41(typescript@5.9.3))
+ version: 14.4.0(magic-string@1.1.0)(magicast@0.5.4)(nuxt@4.5.2(6d56396f49bf900fca9d98148c666e42))(oxc-parser@0.140.0)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.2)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0)))(vue@3.5.41(typescript@5.9.3))
'@yunlefun/ui':
specifier: 0.0.6
version: 0.0.6(sass@1.102.0)
'@yunlefun/vue':
specifier: 0.4.2
- version: 0.4.2(nuxt@4.5.2(0f4a3527db7795df392b465c3de4796e))(sass@1.102.0)(vue@3.5.41(typescript@5.9.3))
+ version: 0.4.2(nuxt@4.5.2(6d56396f49bf900fca9d98148c666e42))(sass@1.102.0)(vue@3.5.41(typescript@5.9.3))
dexie:
specifier: ^4.4.4
version: 4.4.4
nuxt:
specifier: ^4.5.2
- version: 4.5.2(0f4a3527db7795df392b465c3de4796e)
+ version: 4.5.2(6d56396f49bf900fca9d98148c666e42)
pinia:
specifier: ^3.0.4
version: 3.0.4(typescript@5.9.3)(vue@3.5.41(typescript@5.9.3))
@@ -987,21 +929,6 @@ packages:
resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==}
hasBin: true
- '@capacitor/android@8.5.0':
- resolution: {integrity: sha512-Rb3prJeQiTp0pQhSSOReJuG9VgibOGMG4ECs+UhMwr6TCCHZ3NCZO811bDA0HxD0xrT/gCrJAsY5yfEATu84JQ==}
- peerDependencies:
- '@capacitor/core': ^8.5.0
-
- '@capacitor/app@8.1.1':
- resolution: {integrity: sha512-xM2ZTX5jK60tFtmjsmJv+Cdj1Qsb6NcavkqmdEnCPQBeya9oKhamZJxYOnQNj1ZvcJM7sWfG6BEtSLx42pisbA==}
- peerDependencies:
- '@capacitor/core': '>=8.0.0'
-
- '@capacitor/browser@8.0.4':
- resolution: {integrity: sha512-ORZ4u/y+7aMuu6yVuk6SP529fUZyqcbnuHB1q5McpA3o2SYfVoi28iB8rsQjI2ad1qlKJd29ZUuGtspXLBDlWg==}
- peerDependencies:
- '@capacitor/core': '>=8.0.0'
-
'@capacitor/cli@8.5.0':
resolution: {integrity: sha512-rLdzMUM5QV4WITcqoWv04p32i14BXgUH2diqEH6MWQlWaJfiyNrvOyt/+d5vHAfOxOm1klBu637VDEobctlwBA==}
engines: {node: '>=22.0.0'}
@@ -1010,36 +937,6 @@ packages:
'@capacitor/core@8.5.0':
resolution: {integrity: sha512-Ca4krtqH1hothjtBIwf2J2TW7IhYq1ujp8QeItTiJohNsqij8ja2DYYH3DU0l8RmxCWaBAFTGA2TgOgOMCSNsQ==}
- '@capacitor/dialog@8.0.1':
- resolution: {integrity: sha512-Dq0mZBsd++7CvPvpD2gfbUB44k/zCoe5K9IgYmMImQ4Yphu4/MxLVpFDFAqSya011UBBTGPrUQGVacIW3jDNkw==}
- peerDependencies:
- '@capacitor/core': '>=8.0.0'
-
- '@capacitor/haptics@8.0.2':
- resolution: {integrity: sha512-c2hZzRR5Fk1tbTvhG1jhh2XBAf3EhnIerMIb2sl7Mt41Gxx1fhBJFDa0/BI1IbY4loVepyyuqNC9820/GZuoWQ==}
- peerDependencies:
- '@capacitor/core': '>=8.0.0'
-
- '@capacitor/ios@8.5.0':
- resolution: {integrity: sha512-7k1TfohJu5BzRXc1F3g04Q8QQ0fyQgms6h1AvhnHb04VaNr9EdHOx03hL8O+OigEKMQnyJd1ZOjTPPNHCqL5Yw==}
- peerDependencies:
- '@capacitor/core': ^8.5.0
-
- '@capacitor/keyboard@8.0.5':
- resolution: {integrity: sha512-oFXygC4eKYA5l2MdpTR06L2M/4x6e2SLD5yS1T9+UBDKTkzyvhWKEhbYLUaTIBPpLKqlfGudJw1X73S1H9eUzQ==}
- peerDependencies:
- '@capacitor/core': '>=8.0.0'
-
- '@capacitor/preferences@8.0.1':
- resolution: {integrity: sha512-T6no3ebi79XJCk91U3Jp/liJUwgBdvHR+s6vhvPkPxSuch7z3zx5Rv1bdWM6sWruNx+pViuEGqZvbfCdyBvcHQ==}
- peerDependencies:
- '@capacitor/core': '>=8.0.0'
-
- '@capacitor/status-bar@8.0.3':
- resolution: {integrity: sha512-csSpfNeN49Hx9JaQBSJEIiEbOLtXg3kcc2IpScq2fu5L520h3AWEvsxoH8Srk1jxfRKepaJ4S4sqSC3foI4AgA==}
- peerDependencies:
- '@capacitor/core': '>=8.0.0'
-
'@clack/core@1.4.3':
resolution: {integrity: sha512-/kr3UWNtdJfxZtPgDqUOmG2pvwlmcLGheex5yiZKdwbzZJxhV+HMNR9QNmyY5cGwTNV6LrR7Jtp+KjhUAP1qBQ==}
engines: {node: '>= 20.12.0'}
@@ -9709,18 +9606,6 @@ snapshots:
dependencies:
css-tree: 3.2.1
- '@capacitor/android@8.5.0(@capacitor/core@8.5.0)':
- dependencies:
- '@capacitor/core': 8.5.0
-
- '@capacitor/app@8.1.1(@capacitor/core@8.5.0)':
- dependencies:
- '@capacitor/core': 8.5.0
-
- '@capacitor/browser@8.0.4(@capacitor/core@8.5.0)':
- dependencies:
- '@capacitor/core': 8.5.0
-
'@capacitor/cli@8.5.0(supports-color@10.2.2)':
dependencies:
'@ionic/cli-framework-output': 2.2.8(supports-color@10.2.2)
@@ -9748,30 +9633,6 @@ snapshots:
dependencies:
tslib: 2.8.1
- '@capacitor/dialog@8.0.1(@capacitor/core@8.5.0)':
- dependencies:
- '@capacitor/core': 8.5.0
-
- '@capacitor/haptics@8.0.2(@capacitor/core@8.5.0)':
- dependencies:
- '@capacitor/core': 8.5.0
-
- '@capacitor/ios@8.5.0(@capacitor/core@8.5.0)':
- dependencies:
- '@capacitor/core': 8.5.0
-
- '@capacitor/keyboard@8.0.5(@capacitor/core@8.5.0)':
- dependencies:
- '@capacitor/core': 8.5.0
-
- '@capacitor/preferences@8.0.1(@capacitor/core@8.5.0)':
- dependencies:
- '@capacitor/core': 8.5.0
-
- '@capacitor/status-bar@8.0.3(@capacitor/core@8.5.0)':
- dependencies:
- '@capacitor/core': 8.5.0
-
'@clack/core@1.4.3':
dependencies:
fast-wrap-ansi: 0.2.2
@@ -10629,7 +10490,7 @@ snapshots:
pkg-types: 2.3.1
semver: 7.8.5
- '@nuxt/devtools@3.4.1(@capacitor/preferences@8.0.1(@capacitor/core@8.5.0))(db0@0.3.4)(ioredis@5.11.1(supports-color@10.2.2))(magic-string@1.1.0)(oxc-parser@0.140.0)(rolldown@1.2.3)(supports-color@10.2.2)(unplugin@3.3.0(esbuild@0.28.2)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(vue@3.5.41(typescript@5.9.3))':
+ '@nuxt/devtools@3.4.1(db0@0.3.4)(ioredis@5.11.1(supports-color@10.2.2))(magic-string@1.1.0)(oxc-parser@0.140.0)(rolldown@1.2.3)(supports-color@10.2.2)(unplugin@3.3.0(esbuild@0.28.2)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(vue@3.5.41(typescript@5.9.3))':
dependencies:
'@nuxt/devtools-kit': 3.4.1(magic-string@1.1.0)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.2)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))
'@nuxt/devtools-wizard': 3.4.1
@@ -10659,7 +10520,7 @@ snapshots:
sirv: 3.0.2
structured-clone-es: 2.0.1
tinyglobby: 0.2.17
- unstorage: 1.17.5(@capacitor/preferences@8.0.1(@capacitor/core@8.5.0))(db0@0.3.4)(ioredis@5.11.1(supports-color@10.2.2))
+ unstorage: 1.17.5(db0@0.3.4)(ioredis@5.11.1(supports-color@10.2.2))
vite: 8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0)
vite-plugin-inspect: 11.4.1(@nuxt/kit@4.5.2(magic-string@1.1.0)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.2)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))))(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))
vite-plugin-vue-tracer: 1.5.0(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(vue@3.5.41(typescript@5.9.3))
@@ -10832,7 +10693,7 @@ snapshots:
- rolldown
- unplugin
- '@nuxt/nitro-server@4.5.2(@babel/plugin-proposal-decorators@7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7(supports-color@10.2.2)))(@capacitor/preferences@8.0.1(@capacitor/core@8.5.0))(@oxc-project/types@0.143.0)(@parcel/watcher@2.6.0)(@rollup/plugin-babel@6.1.0(@babel/core@7.29.7(supports-color@10.2.2))(rollup@4.62.4)(supports-color@10.2.2))(db0@0.3.4)(esbuild@0.28.2)(ioredis@5.11.1(supports-color@10.2.2))(lightningcss@1.33.0)(magic-string@1.1.0)(magicast@0.5.4)(nuxt@4.5.2(0f4a3527db7795df392b465c3de4796e))(oxc-parser@0.140.0)(rolldown@1.2.3)(rollup@4.62.4)(srvx@0.12.5)(supports-color@10.2.2)(typescript@5.9.3)(unplugin@3.3.0(esbuild@0.28.2)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(xml2js@0.6.2)':
+ '@nuxt/nitro-server@4.5.2(@babel/plugin-proposal-decorators@7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7(supports-color@10.2.2)))(@oxc-project/types@0.143.0)(@parcel/watcher@2.6.0)(@rollup/plugin-babel@6.1.0(@babel/core@7.29.7(supports-color@10.2.2))(rollup@4.62.4)(supports-color@10.2.2))(db0@0.3.4)(esbuild@0.28.2)(ioredis@5.11.1(supports-color@10.2.2))(lightningcss@1.33.0)(magic-string@1.1.0)(magicast@0.5.4)(nuxt@4.5.2(6d56396f49bf900fca9d98148c666e42))(oxc-parser@0.140.0)(rolldown@1.2.3)(rollup@4.62.4)(srvx@0.12.5)(supports-color@10.2.2)(typescript@5.9.3)(unplugin@3.3.0(esbuild@0.28.2)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(xml2js@0.6.2)':
dependencies:
'@nuxt/devalue': 2.0.2
'@nuxt/kit': 4.5.2(magic-string@1.1.0)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.2)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0)))
@@ -10849,9 +10710,9 @@ snapshots:
impound: 1.1.6(esbuild@0.28.2)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))
klona: 2.0.6
mocked-exports: 0.1.1
- nitropack: 2.13.4(@capacitor/preferences@8.0.1(@capacitor/core@8.5.0))(@parcel/watcher@2.6.0)(oxc-parser@0.140.0)(rolldown@1.2.3)(srvx@0.12.5)(supports-color@10.2.2)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(xml2js@0.6.2)
+ nitropack: 2.13.4(@parcel/watcher@2.6.0)(oxc-parser@0.140.0)(rolldown@1.2.3)(srvx@0.12.5)(supports-color@10.2.2)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(xml2js@0.6.2)
nostics: 1.2.0
- nuxt: 4.5.2(0f4a3527db7795df392b465c3de4796e)
+ nuxt: 4.5.2(6d56396f49bf900fca9d98148c666e42)
nypm: 0.6.9
ohash: 2.0.11
pathe: 2.0.3
@@ -10859,7 +10720,7 @@ snapshots:
std-env: 4.2.0
ufo: 1.6.4
unctx: 3.0.0(magic-string@1.1.0)(oxc-parser@0.140.0)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.2)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0)))
- unstorage: 1.17.5(@capacitor/preferences@8.0.1(@capacitor/core@8.5.0))(db0@0.3.4)(ioredis@5.11.1(supports-color@10.2.2))
+ unstorage: 1.17.5(db0@0.3.4)(ioredis@5.11.1(supports-color@10.2.2))
vue: 3.5.41(typescript@5.9.3)
vue-bundle-renderer: 2.3.2
vue-devtools-stub: 0.1.0
@@ -10929,7 +10790,7 @@ snapshots:
pkg-types: 2.3.1
std-env: 4.2.0
- '@nuxt/scripts@1.3.3(@capacitor/preferences@8.0.1(@capacitor/core@8.5.0))(@oxc-project/types@0.143.0)(@unhead/vue@3.3.1(@oxc-project/types@0.143.0)(esbuild@0.28.2)(lightningcss@1.33.0)(oxc-parser@0.140.0)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(vue@3.5.41(typescript@5.9.3)))(db0@0.3.4)(esbuild@0.28.2)(ioredis@5.11.1(supports-color@10.2.2))(magicast@0.5.4)(rolldown@1.2.3)(rollup@4.62.4)(typescript@5.9.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(vue@3.5.41(typescript@5.9.3))':
+ '@nuxt/scripts@1.3.3(@oxc-project/types@0.143.0)(@unhead/vue@3.3.1(@oxc-project/types@0.143.0)(esbuild@0.28.2)(lightningcss@1.33.0)(oxc-parser@0.140.0)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(vue@3.5.41(typescript@5.9.3)))(db0@0.3.4)(esbuild@0.28.2)(ioredis@5.11.1(supports-color@10.2.2))(magicast@0.5.4)(rolldown@1.2.3)(rollup@4.62.4)(typescript@5.9.3)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(vue@3.5.41(typescript@5.9.3))':
dependencies:
'@nuxt/devtools-kit': 3.4.1(magic-string@1.1.0)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.2)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))
'@vueuse/core': 14.4.0(vue@3.5.41(typescript@5.9.3))
@@ -10949,7 +10810,7 @@ snapshots:
ufo: 1.6.4
ultrahtml: 1.7.0
unplugin: 3.3.0(esbuild@0.28.2)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))
- unstorage: 1.17.5(@capacitor/preferences@8.0.1(@capacitor/core@8.5.0))(db0@0.3.4)(ioredis@5.11.1(supports-color@10.2.2))
+ unstorage: 1.17.5(db0@0.3.4)(ioredis@5.11.1(supports-color@10.2.2))
valibot: 1.4.2(typescript@5.9.3)
optionalDependencies:
'@unhead/vue': 3.3.1(@oxc-project/types@0.143.0)(esbuild@0.28.2)(lightningcss@1.33.0)(oxc-parser@0.140.0)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(vue@3.5.41(typescript@5.9.3))
@@ -11043,7 +10904,7 @@ snapshots:
- vite
- webpack
- '@nuxt/vite-builder@4.5.2(@babel/plugin-proposal-decorators@7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2))(@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7(supports-color@10.2.2)))(@types/node@25.9.5)(esbuild@0.28.2)(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(magic-string@1.1.0)(magicast@0.5.4)(nuxt@4.5.2(0f4a3527db7795df392b465c3de4796e))(optionator@0.9.4)(oxc-parser@0.140.0)(rolldown@1.2.3)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.3)(rollup@4.62.4))(rollup@4.62.4)(sass@1.102.0)(supports-color@10.2.2)(terser@5.49.2)(tsx@4.23.12)(typescript@5.9.3)(vue-tsc@3.3.9(typescript@5.9.3))(vue@3.5.41(typescript@5.9.3))(yaml@2.9.0)':
+ '@nuxt/vite-builder@4.5.2(@babel/plugin-proposal-decorators@7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2))(@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7(supports-color@10.2.2)))(@types/node@25.9.5)(esbuild@0.28.2)(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(magic-string@1.1.0)(magicast@0.5.4)(nuxt@4.5.2(6d56396f49bf900fca9d98148c666e42))(optionator@0.9.4)(oxc-parser@0.140.0)(rolldown@1.2.3)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.3)(rollup@4.62.4))(rollup@4.62.4)(sass@1.102.0)(supports-color@10.2.2)(terser@5.49.2)(tsx@4.23.12)(typescript@5.9.3)(vue-tsc@3.3.9(typescript@5.9.3))(vue@3.5.41(typescript@5.9.3))(yaml@2.9.0)':
dependencies:
'@nuxt/kit': 4.5.2(magic-string@1.1.0)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.2)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0)))
'@vitejs/plugin-vue': 6.0.8(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(vue@3.5.41(typescript@5.9.3))
@@ -11061,7 +10922,7 @@ snapshots:
knitwork: 1.3.0
mlly: 1.8.2
mocked-exports: 0.1.1
- nuxt: 4.5.2(0f4a3527db7795df392b465c3de4796e)
+ nuxt: 4.5.2(6d56396f49bf900fca9d98148c666e42)
nypm: 0.6.9
pathe: 2.0.3
pkg-types: 2.3.1
@@ -12655,13 +12516,13 @@ snapshots:
'@vueuse/metadata@14.4.0': {}
- '@vueuse/nuxt@14.4.0(magic-string@1.1.0)(magicast@0.5.4)(nuxt@4.5.2(0f4a3527db7795df392b465c3de4796e))(oxc-parser@0.140.0)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.2)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0)))(vue@3.5.41(typescript@5.9.3))':
+ '@vueuse/nuxt@14.4.0(magic-string@1.1.0)(magicast@0.5.4)(nuxt@4.5.2(6d56396f49bf900fca9d98148c666e42))(oxc-parser@0.140.0)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.2)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0)))(vue@3.5.41(typescript@5.9.3))':
dependencies:
'@nuxt/kit': 4.5.2(magic-string@1.1.0)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.2)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0)))
'@vueuse/core': 14.4.0(vue@3.5.41(typescript@5.9.3))
'@vueuse/metadata': 14.4.0
local-pkg: 1.2.1
- nuxt: 4.5.2(0f4a3527db7795df392b465c3de4796e)
+ nuxt: 4.5.2(6d56396f49bf900fca9d98148c666e42)
vue: 3.5.41(typescript@5.9.3)
transitivePeerDependencies:
- magic-string
@@ -12684,13 +12545,13 @@ snapshots:
optionalDependencies:
sass: 1.102.0
- '@yunlefun/vue@0.4.2(nuxt@4.5.2(0f4a3527db7795df392b465c3de4796e))(sass@1.102.0)(vue@3.5.41(typescript@5.9.3))':
+ '@yunlefun/vue@0.4.2(nuxt@4.5.2(6d56396f49bf900fca9d98148c666e42))(sass@1.102.0)(vue@3.5.41(typescript@5.9.3))':
dependencies:
reka-ui: 2.10.5(vue@3.5.41(typescript@5.9.3))
sass: 1.102.0
vue: 3.5.41(typescript@5.9.3)
optionalDependencies:
- nuxt: 4.5.2(0f4a3527db7795df392b465c3de4796e)
+ nuxt: 4.5.2(6d56396f49bf900fca9d98148c666e42)
transitivePeerDependencies:
- '@vue/composition-api'
@@ -15850,7 +15711,7 @@ snapshots:
netmask@2.1.1: {}
- nitropack@2.13.4(@capacitor/preferences@8.0.1(@capacitor/core@8.5.0))(@parcel/watcher@2.6.0)(oxc-parser@0.140.0)(rolldown@1.2.3)(srvx@0.12.5)(supports-color@10.2.2)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(xml2js@0.6.2):
+ nitropack@2.13.4(@parcel/watcher@2.6.0)(oxc-parser@0.140.0)(rolldown@1.2.3)(srvx@0.12.5)(supports-color@10.2.2)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(xml2js@0.6.2):
dependencies:
'@cloudflare/kv-asset-handler': 0.4.2
'@rollup/plugin-alias': 6.0.0(rollup@4.62.4)
@@ -15917,7 +15778,7 @@ snapshots:
unenv: 2.0.0-rc.24
unimport: 6.4.0(esbuild@0.28.2)(oxc-parser@0.140.0)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))
unplugin-utils: 0.3.2
- unstorage: 1.17.5(@capacitor/preferences@8.0.1(@capacitor/core@8.5.0))(db0@0.3.4)(ioredis@5.11.1(supports-color@10.2.2))
+ unstorage: 1.17.5(db0@0.3.4)(ioredis@5.11.1(supports-color@10.2.2))
untyped: 2.0.0
unwasm: 0.5.3
youch: 4.1.1
@@ -16010,16 +15871,16 @@ snapshots:
dependencies:
boolbase: 1.0.0
- nuxt@4.5.2(0f4a3527db7795df392b465c3de4796e):
+ nuxt@4.5.2(6d56396f49bf900fca9d98148c666e42):
dependencies:
'@dxup/nuxt': 0.5.6(esbuild@0.28.2)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))
'@nuxt/cli': 3.37.0(@nuxt/schema@4.5.2)(@parcel/watcher@2.6.0)(commander@14.0.3)(magicast@0.5.4)(supports-color@10.2.2)
- '@nuxt/devtools': 3.4.1(@capacitor/preferences@8.0.1(@capacitor/core@8.5.0))(db0@0.3.4)(ioredis@5.11.1(supports-color@10.2.2))(magic-string@1.1.0)(oxc-parser@0.140.0)(rolldown@1.2.3)(supports-color@10.2.2)(unplugin@3.3.0(esbuild@0.28.2)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(vue@3.5.41(typescript@5.9.3))
+ '@nuxt/devtools': 3.4.1(db0@0.3.4)(ioredis@5.11.1(supports-color@10.2.2))(magic-string@1.1.0)(oxc-parser@0.140.0)(rolldown@1.2.3)(supports-color@10.2.2)(unplugin@3.3.0(esbuild@0.28.2)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(vue@3.5.41(typescript@5.9.3))
'@nuxt/kit': 4.5.2(magic-string@1.1.0)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.2)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0)))
- '@nuxt/nitro-server': 4.5.2(@babel/plugin-proposal-decorators@7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7(supports-color@10.2.2)))(@capacitor/preferences@8.0.1(@capacitor/core@8.5.0))(@oxc-project/types@0.143.0)(@parcel/watcher@2.6.0)(@rollup/plugin-babel@6.1.0(@babel/core@7.29.7(supports-color@10.2.2))(rollup@4.62.4)(supports-color@10.2.2))(db0@0.3.4)(esbuild@0.28.2)(ioredis@5.11.1(supports-color@10.2.2))(lightningcss@1.33.0)(magic-string@1.1.0)(magicast@0.5.4)(nuxt@4.5.2(0f4a3527db7795df392b465c3de4796e))(oxc-parser@0.140.0)(rolldown@1.2.3)(rollup@4.62.4)(srvx@0.12.5)(supports-color@10.2.2)(typescript@5.9.3)(unplugin@3.3.0(esbuild@0.28.2)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(xml2js@0.6.2)
+ '@nuxt/nitro-server': 4.5.2(@babel/plugin-proposal-decorators@7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7(supports-color@10.2.2)))(@oxc-project/types@0.143.0)(@parcel/watcher@2.6.0)(@rollup/plugin-babel@6.1.0(@babel/core@7.29.7(supports-color@10.2.2))(rollup@4.62.4)(supports-color@10.2.2))(db0@0.3.4)(esbuild@0.28.2)(ioredis@5.11.1(supports-color@10.2.2))(lightningcss@1.33.0)(magic-string@1.1.0)(magicast@0.5.4)(nuxt@4.5.2(6d56396f49bf900fca9d98148c666e42))(oxc-parser@0.140.0)(rolldown@1.2.3)(rollup@4.62.4)(srvx@0.12.5)(supports-color@10.2.2)(typescript@5.9.3)(unplugin@3.3.0(esbuild@0.28.2)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(xml2js@0.6.2)
'@nuxt/schema': 4.5.2
'@nuxt/telemetry': 2.8.0(@nuxt/kit@4.5.2(magic-string@1.1.0)(magicast@0.5.4)(oxc-parser@0.140.0)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.2)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))))
- '@nuxt/vite-builder': 4.5.2(@babel/plugin-proposal-decorators@7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2))(@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7(supports-color@10.2.2)))(@types/node@25.9.5)(esbuild@0.28.2)(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(magic-string@1.1.0)(magicast@0.5.4)(nuxt@4.5.2(0f4a3527db7795df392b465c3de4796e))(optionator@0.9.4)(oxc-parser@0.140.0)(rolldown@1.2.3)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.3)(rollup@4.62.4))(rollup@4.62.4)(sass@1.102.0)(supports-color@10.2.2)(terser@5.49.2)(tsx@4.23.12)(typescript@5.9.3)(vue-tsc@3.3.9(typescript@5.9.3))(vue@3.5.41(typescript@5.9.3))(yaml@2.9.0)
+ '@nuxt/vite-builder': 4.5.2(@babel/plugin-proposal-decorators@7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2))(@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7(supports-color@10.2.2)))(@types/node@25.9.5)(esbuild@0.28.2)(eslint@10.8.1(jiti@2.7.0)(supports-color@10.2.2))(magic-string@1.1.0)(magicast@0.5.4)(nuxt@4.5.2(6d56396f49bf900fca9d98148c666e42))(optionator@0.9.4)(oxc-parser@0.140.0)(rolldown@1.2.3)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.3)(rollup@4.62.4))(rollup@4.62.4)(sass@1.102.0)(supports-color@10.2.2)(terser@5.49.2)(tsx@4.23.12)(typescript@5.9.3)(vue-tsc@3.3.9(typescript@5.9.3))(vue@3.5.41(typescript@5.9.3))(yaml@2.9.0)
'@unhead/vue': 3.3.1(@oxc-project/types@0.143.0)(esbuild@0.28.2)(lightningcss@1.33.0)(oxc-parser@0.140.0)(rolldown@1.2.3)(rollup@4.62.4)(vite@8.2.1(@types/node@25.9.5)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.102.0)(terser@5.49.2)(tsx@4.23.12)(yaml@2.9.0))(vue@3.5.41(typescript@5.9.3))
'@vue/shared': 3.5.41
chokidar: 5.0.0
@@ -18190,7 +18051,7 @@ snapshots:
'@unrs/resolver-binding-win32-ia32-msvc': 1.12.2
'@unrs/resolver-binding-win32-x64-msvc': 1.12.2
- unstorage@1.17.5(@capacitor/preferences@8.0.1(@capacitor/core@8.5.0))(db0@0.3.4)(ioredis@5.11.1(supports-color@10.2.2)):
+ unstorage@1.17.5(db0@0.3.4)(ioredis@5.11.1(supports-color@10.2.2)):
dependencies:
anymatch: 3.1.3
chokidar: 5.0.0
@@ -18201,7 +18062,6 @@ snapshots:
ofetch: 1.5.1
ufo: 1.6.4
optionalDependencies:
- '@capacitor/preferences': 8.0.1(@capacitor/core@8.5.0)
db0: 0.3.4
ioredis: 5.11.1(supports-color@10.2.2)
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index 2038c74..009c990 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -16,8 +16,6 @@ trustPolicyExclude:
- semver@6.3.1
# Google Workbox 7.4.1 pins this exact pre-release build helper.
- '@trickfilm400/rollup-plugin-off-main-thread@3.0.0-pre1'
- # Official Ionic repository, maintainers, signature, and integrity verified.
- - '@capacitor/haptics@8.0.2'
packages:
- apps/*
diff --git a/scripts/android/build.sh b/scripts/android/build.sh
deleted file mode 100644
index c61cec6..0000000
--- a/scripts/android/build.sh
+++ /dev/null
@@ -1 +0,0 @@
-npx cap build android
diff --git a/scripts/android/dev.sh b/scripts/android/dev.sh
deleted file mode 100644
index 5424251..0000000
--- a/scripts/android/dev.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-LIP=$(ipconfig getifaddr en0)
-
-echo "🍦 Starting local development to android device - ensure local dev server is running already"
-echo "🏗️ Type checking and building for development..."
-pnpm run build:dev
-echo "🔃 Capacitor installation, podfile installation, sync and copy to app distribution folders..."
-npx @ionic/cli capacitor sync android --no-build
-echo "🏃 Select an Android device to run the build at local ip address ${LIP} on..."
-eval "npx @ionic/cli capacitor run android --livereload-url=http://${LIP}:3000 --external --mode development"
diff --git a/scripts/copy-web-output.ts b/scripts/copy-web-output.ts
index e86dc6a..5034f70 100644
--- a/scripts/copy-web-output.ts
+++ b/scripts/copy-web-output.ts
@@ -1,7 +1,7 @@
import { cpSync, existsSync, rmSync } from 'node:fs'
import { resolve } from 'node:path'
-// Deploy targets (Netlify, Vercel, Cloudflare Pages, EdgeOne, Docker, Capacitor) read `dist/`
+// Deploy targets (Netlify, Vercel, Cloudflare Pages, EdgeOne, Docker) read `dist/`
// at the repo root, so mirror the web app's static output there.
const root = resolve(import.meta.dirname, '..')
const webDist = resolve(root, 'apps/web/dist')
diff --git a/scripts/ios.sh b/scripts/ios.sh
deleted file mode 100644
index 387c2d0..0000000
--- a/scripts/ios.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-LIP=$(ipconfig getifaddr en0)
-
-echo "🍦 Starting local development to ios device - ensure local dev server is running already"
-echo "🏗️ Type checking and building for development..."
-pnpm run build:dev
-echo "🔃 Capacitor installation, podfile installation, sync and copy to app distribution folders..."
-npx @ionic/cli capacitor sync ios --no-build
-echo "🏃 Select an iOS device to run the build at local ip address ${LIP} on..."
-eval "npx @ionic/cli capacitor run ios --livereload-url=http://${LIP}:3000 --external --mode development"
diff --git a/scripts/qa/verify-acquisition-sdk.mjs b/scripts/qa/verify-acquisition-sdk.mjs
index 54a727f..f594175 100644
--- a/scripts/qa/verify-acquisition-sdk.mjs
+++ b/scripts/qa/verify-acquisition-sdk.mjs
@@ -34,8 +34,8 @@ try {
renameSync(dependency, previous)
replaced = true
symlinkSync(join(temporary, 'package'), dependency, 'dir')
- runCookTool('vitest', ['run', 'test/acquisition.test.ts', 'test/yunlefunAuthAdapter.test.ts', 'test/nativeSso.test.ts', 'test/yunlefunAuth.test.ts', 'test/yunlefunSsoConfig.test.ts'])
- runCookTool('eslint', ['apps/web/app/utils/acquisition.ts', 'apps/web/app/plugins/acquisition.client.ts', 'apps/web/app/plugins/yunlefun-auth.client.ts', 'apps/web/app/adapters/yunlefunAuth.ts', 'apps/web/app/utils/nativeSso.ts', 'test/acquisition.test.ts', 'test/yunlefunAuthAdapter.test.ts', 'test/nativeSso.test.ts', 'scripts/qa/verify-acquisition-sdk.mjs'])
+ runCookTool('vitest', ['run', 'test/acquisition.test.ts', 'test/yunlefunAuthAdapter.test.ts', 'test/yunlefunAuth.test.ts', 'test/yunlefunSsoConfig.test.ts'])
+ runCookTool('eslint', ['apps/web/app/utils/acquisition.ts', 'apps/web/app/plugins/acquisition.client.ts', 'apps/web/app/plugins/yunlefun-auth.client.ts', 'apps/web/app/adapters/yunlefunAuth.ts', 'test/acquisition.test.ts', 'test/yunlefunAuthAdapter.test.ts', 'test/yunlefunAuth.test.ts', 'scripts/qa/verify-acquisition-sdk.mjs'])
if (process.argv.includes('--build'))
runCookTool('nuxt', ['build'])
if (process.argv.includes('--typecheck'))
diff --git a/skills/add-recipe/SKILL.md b/skills/add-recipe/SKILL.md
index 8ec5548..94df2ba 100644
--- a/skills/add-recipe/SKILL.md
+++ b/skills/add-recipe/SKILL.md
@@ -28,16 +28,16 @@ name,stuff,bv,difficulty,tags,methods,tools,id
电饭煲版广式腊肠煲饭,腊肠、米,BV1NE411Q7Jj,简单,广式,煲,电饭煲,0
```
-| 列 | 规则 |
-| --------- | ------------------------------------------------------------------------------------------------------ |
-| name | 必填。菜名要能让人一眼看出做法,习惯写成「厨具版+做法+主料」或「主料+做法」 |
-| stuff | 必填。只能填 `packages/data/food.json` 里的食材标准名,具体品种(虾仁、鲈鱼)要写成标准名(虾、鱼) |
-| bv | B 站 BV 号或 av 号。**可以留空**——应用里点菜走的是 B 站搜索链接,不是这个视频号;填了就必须是真实可播放的视频 |
-| difficulty | 简单 / 普通 / 困难,或留空 |
-| tags | 菜系类别 + 其它标签(快手菜、下饭、汤、杂烩、辣…),见下表 |
-| methods | 做法(炒、煎、蒸、煮、煲、烤、炸…),见下表 |
-| tools | 只能填 `packages/data/food.json` 里的厨具名 |
-| id | 必填,非负整数且唯一。**新菜用当前最大 id + 1**(现在是 637、638…) |
+| 列 | 规则 |
+| ---------- | ------------------------------------------------------------------------------------------------------------- |
+| name | 必填。菜名要能让人一眼看出做法,习惯写成「厨具版+做法+主料」或「主料+做法」 |
+| stuff | 必填。只能填 `packages/data/food.json` 里的食材标准名,具体品种(虾仁、鲈鱼)要写成标准名(虾、鱼) |
+| bv | B 站 BV 号或 av 号。**可以留空**——应用里点菜走的是 B 站搜索链接,不是这个视频号;填了就必须是真实可播放的视频 |
+| difficulty | 简单 / 普通 / 困难,或留空 |
+| tags | 菜系类别 + 其它标签(快手菜、下饭、汤、杂烩、辣…),见下表 |
+| methods | 做法(炒、煎、蒸、煮、煲、烤、炸…),见下表 |
+| tools | 只能填 `packages/data/food.json` 里的厨具名 |
+| id | 必填,非负整数且唯一。**新菜用当前最大 id + 1**(现在是 637、638…) |
**id 一旦发布就不能修改、不能复用。** 收藏、反馈、筛选信号都按 id 记录。新菜一律追加到文件末尾,id 递增。
@@ -59,19 +59,19 @@ name,stuff,bv,difficulty,tags,methods,tools,id
必须从下表里选**标签值**写进 tags,选了哪个菜系筛选就只认哪个标签:
-| 菜系 | 可用标签 |
-| ------ | -------------- |
-| 川菜 | 川菜 |
-| 湘菜 | 湘菜 |
-| 粤菜 | 粤菜、广式 |
-| 苏菜 | 苏菜 |
-| 东北菜 | 东北菜 |
-| 西北菜 | 西北特色 |
-| 日式 | 日式、日式菜 |
-| 意式 | 意式 |
-| 法式 | 法式、法餐 |
-| 西式 | 西式 |
-| 国宴菜 | 国宴菜 |
+| 菜系 | 可用标签 |
+| ------ | ------------ |
+| 川菜 | 川菜 |
+| 湘菜 | 湘菜 |
+| 粤菜 | 粤菜、广式 |
+| 苏菜 | 苏菜 |
+| 东北菜 | 东北菜 |
+| 西北菜 | 西北特色 |
+| 日式 | 日式、日式菜 |
+| 意式 | 意式 |
+| 法式 | 法式、法餐 |
+| 西式 | 西式 |
+| 国宴菜 | 国宴菜 |
**每道新菜都尽量打上菜系标签。** 应用里一旦选了菜系,只有带该标签的菜会出现——标签不全会导致选了菜系就几乎没结果。
@@ -79,16 +79,16 @@ name,stuff,bv,difficulty,tags,methods,tools,id
用户在应用里选的「做法」是分组,按下面的规则命中:
-| 做法分组 | 怎么填 | 备注 |
-| -------- | ---------------------------------------- | -------------------------- |
-| 炒菜 | methods 填「炒」 | |
-| 汤羹 | **tags 填「汤」**,methods 填煮/煲/炖 | 靠标签识别,不是靠 methods |
-| 炖煮 | methods 填炖、煮、煲、卤、焖、烧、灼 | |
-| 蒸 | methods 填「蒸」 | |
-| 炸煎 | methods 填炸、煎、烙 | |
-| 烤 | methods 填烤、烘、焗 | |
-| 凉拌 | methods 填拌、凉拌、腌、腌制、泡菜、油泼 | |
-| 微波 | methods 填「微波加热」 | |
+| 做法分组 | 怎么填 | 备注 |
+| -------- | ---------------------------------------- | ------------------------------------ |
+| 炒菜 | methods 填「炒」 | |
+| 汤羹 | **tags 填「汤」**,methods 填煮/煲/炖 | 靠标签识别,不是靠 methods |
+| 炖煮 | methods 填炖、煮、煲、卤、焖、烧、灼 | |
+| 蒸 | methods 填「蒸」 | |
+| 炸煎 | methods 填炸、煎、烙 | |
+| 烤 | methods 填烤、烘、焗 | |
+| 凉拌 | methods 填拌、凉拌、腌、腌制、泡菜、油泼 | |
+| 微波 | methods 填「微波加热」 | |
| 火锅 | **tags 填「杂烩」**,且食材 **≥10 种** | 靠标签识别;食材少于 10 种不算大杂烩 |
「辣」标签同样靠 tags 识别,选了「不吃辣」时会排除带此标签的菜。
diff --git a/test/analytics.test.ts b/test/analytics.test.ts
index e65255d..44d3f5d 100644
--- a/test/analytics.test.ts
+++ b/test/analytics.test.ts
@@ -8,7 +8,7 @@ describe('clarity configuration', () => {
expect(resolveClarityConfig(config, 'https://cook.yunle.fun/', false)).toEqual({ projectId: config.projectId })
expect(resolveClarityConfig(config, 'https://cook.yunyoujun.cn/', true)).toBeNull()
expect(resolveClarityConfig(config, 'https://preview.example.com/', false)).toBeNull()
- expect(resolveClarityConfig(config, 'capacitor://cook.yunle.fun/', false)).toBeNull()
+ expect(resolveClarityConfig(config, 'app://cook.yunle.fun/', false)).toBeNull()
expect(resolveClarityConfig({ ...config, projectId: '' }, 'https://cook.yunle.fun/', false)).toBeNull()
expect(resolveClarityConfig({ ...config, projectId: '../invalid' }, 'https://cook.yunle.fun/', false)).toBeNull()
})
diff --git a/test/nativeAppMetadata.test.ts b/test/appMetadata.test.ts
similarity index 51%
rename from test/nativeAppMetadata.test.ts
rename to test/appMetadata.test.ts
index 5e675c0..93fc600 100644
--- a/test/nativeAppMetadata.test.ts
+++ b/test/appMetadata.test.ts
@@ -18,40 +18,25 @@ function readPngMetadata(path: string) {
}
}
-describe('native app metadata', () => {
- it('uses 食用手册 as the installed app name on iOS and Android', () => {
- const capacitorConfig = readFileSync(resolve(root, 'capacitor.config.ts'), 'utf8')
- const iosInfo = readFileSync(resolve(root, 'ios/App/App/Info.plist'), 'utf8')
- const androidStrings = readFileSync(
- resolve(root, 'android/app/src/main/res/values/strings.xml'),
- 'utf8',
- )
+describe('web app metadata', () => {
+ it('uses 食用手册 as the app name', () => {
+ const constants = readFileSync(resolve(root, 'apps/web/app/constants/index.ts'), 'utf8')
- expect(capacitorConfig).toContain('appName: \'食用手册\'')
- expect(iosInfo).toContain('食用手册')
- expect(androidStrings).toContain('食用手册')
- expect(androidStrings).toContain('食用手册')
+ expect(constants).toContain('export const appName = \'食用手册\'')
})
- it('ships the selected Cook icon across web, iOS, and Android', () => {
+ it('ships the selected Cook icon across web surfaces', () => {
const appIcon = readFileSync(resolve(root, 'apps/web/public/brand/cook-app-icon.svg'), 'utf8')
const mark = readFileSync(resolve(root, 'apps/web/public/brand/cook-mark.svg'), 'utf8')
- const androidBackground = readFileSync(
- resolve(root, 'android/app/src/main/res/values/ic_launcher_background.xml'),
- 'utf8',
- )
expect(appIcon).toContain('viewBox="0 0 1254 1254"')
expect(appIcon).toContain('')
expect(appIcon).toContain('')
expect(mark).not.toContain('M0 0h1254v1254H0z')
expect(mark).toContain('')
- expect(androidBackground).toContain('#07855F')
expect(readPngMetadata('apps/web/public/pwa-192x192.png')).toMatchObject({ width: 192, height: 192, colorType: 2 })
expect(readPngMetadata('apps/web/public/pwa-512x512.png')).toMatchObject({ width: 512, height: 512, colorType: 2 })
expect(readPngMetadata('apps/web/public/apple-touch-icon.png')).toMatchObject({ width: 180, height: 180, colorType: 2 })
- expect(readPngMetadata('ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png')).toMatchObject({ width: 1024, height: 1024, colorType: 2 })
- expect(readPngMetadata('android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png')).toMatchObject({ width: 108, height: 108, colorType: 6 })
})
})
diff --git a/test/nativeSso.test.ts b/test/nativeSso.test.ts
deleted file mode 100644
index 1625c90..0000000
--- a/test/nativeSso.test.ts
+++ /dev/null
@@ -1,163 +0,0 @@
-import type {
- NativeSsoTransaction,
- NativeSsoTransactionStore,
-} from '../apps/web/app/utils/nativeSso'
-import { encodeSsoRedirectResult } from '@yunlefun/sso'
-import { describe, expect, it } from 'vitest'
-import {
- beginNativeSsoRedirect,
- consumeNativeSsoCallback,
- openNativeSsoRedirect,
- stripNativeSsoCallbackHash,
-} from '../apps/web/app/utils/nativeSso'
-
-class MemoryTransactionStore implements NativeSsoTransactionStore {
- transaction: NativeSsoTransaction | null = null
-
- async clear(): Promise {
- this.transaction = null
- }
-
- async load(): Promise {
- return this.transaction
- }
-
- async save(transaction: NativeSsoTransaction): Promise {
- this.transaction = transaction
- }
-}
-
-const options = {
- clientId: 'cook-mobile',
- redirectUri: 'https://cook.yunyoujun.cn/auth/callback?platform=native',
- scope: ['identity:bootstrap'],
- ssoOrigin: 'https://www.yunle.fun',
-} as const
-
-describe('native SSO redirect', () => {
- it('retains only valid optional acquisition through the native PKCE callback', async () => {
- const touch = {
- capturedAt: 1000,
- landingHost: 'cook.yunle.fun',
- landingPath: '/random',
- referrerHost: 'www.baidu.com',
- utmSource: '',
- utmMedium: '',
- utmCampaign: '',
- }
- const acquisition = { version: 1 as const, firstTouch: touch, registerTouch: touch }
- const store = new MemoryTransactionStore()
- const url = await beginNativeSsoRedirect({ ...options, acquisition }, store, {
- now: () => 1000,
- randomBase64Url: sequence('n'.repeat(43), 'v'.repeat(43)),
- })
- expect(JSON.parse(new URL(url).searchParams.get('acquisition')!)).toEqual(acquisition)
- const result = await consumeNativeSsoCallback(callbackUrl({
- code: 'c'.repeat(43),
- issuer: 'https://www.yunle.fun',
- nonce: 'n'.repeat(43),
- }), store, { now: () => 2000 })
- expect(result).toMatchObject({ ok: true, acquisition })
- })
-
- it('accepts a matching claimed HTTPS callback exactly once', async () => {
- const store = new MemoryTransactionStore()
- const authorizationUrl = await beginNativeSsoRedirect(options, store, {
- now: () => 1_000,
- randomBase64Url: sequence('n'.repeat(43), 'v'.repeat(43)),
- })
- const request = new URL(authorizationUrl)
-
- expect(request.origin + request.pathname).toBe('https://www.yunle.fun/auth/sso')
- expect(request.searchParams.get('client_id')).toBe('cook-mobile')
- expect(request.searchParams.get('redirect_uri')).toBe(options.redirectUri)
- expect(request.searchParams.get('nonce')).toBe('n'.repeat(43))
- expect(request.searchParams.get('code_challenge_method')).toBe('S256')
-
- const callback = callbackUrl({
- code: 'c'.repeat(43),
- issuer: 'https://www.yunle.fun',
- nonce: 'n'.repeat(43),
- })
-
- await expect(consumeNativeSsoCallback(callback, store, { now: () => 2_000 })).resolves.toEqual({
- ok: true,
- clientId: 'cook-mobile',
- code: 'c'.repeat(43),
- codeVerifier: 'v'.repeat(43),
- issuer: 'https://www.yunle.fun',
- nonce: 'n'.repeat(43),
- redirectUri: options.redirectUri,
- scope: ['identity:bootstrap'],
- })
- await expect(consumeNativeSsoCallback(callback, store, { now: () => 2_000 })).resolves.toBeNull()
- })
-
- it('rejects an altered callback path and consumes the pending transaction', async () => {
- const store = new MemoryTransactionStore()
- await beginNativeSsoRedirect(options, store, {
- now: () => 1_000,
- randomBase64Url: sequence('n'.repeat(43), 'v'.repeat(43)),
- })
- const callback = callbackUrl({
- code: 'c'.repeat(43),
- issuer: 'https://www.yunle.fun',
- nonce: 'n'.repeat(43),
- }).replace('/auth/callback', '/evil/callback')
-
- await expect(consumeNativeSsoCallback(callback, store, { now: () => 2_000 })).resolves.toBeNull()
- await expect(consumeNativeSsoCallback(callbackUrl({
- code: 'c'.repeat(43),
- issuer: 'https://www.yunle.fun',
- nonce: 'n'.repeat(43),
- }), store, { now: () => 2_000 })).resolves.toBeNull()
- })
-
- it('rejects an expired transaction', async () => {
- const store = new MemoryTransactionStore()
- await beginNativeSsoRedirect(options, store, {
- now: () => 1_000,
- randomBase64Url: sequence('n'.repeat(43), 'v'.repeat(43)),
- })
-
- await expect(consumeNativeSsoCallback(callbackUrl({
- code: 'c'.repeat(43),
- issuer: 'https://www.yunle.fun',
- nonce: 'n'.repeat(43),
- }), store, { now: () => 601_001 })).resolves.toBeNull()
- })
-
- it('clears the pending transaction when the system browser cannot open', async () => {
- const store = new MemoryTransactionStore()
-
- await expect(openNativeSsoRedirect(options, store, async () => {
- throw new Error('browser unavailable')
- }, {
- now: () => 1_000,
- randomBase64Url: sequence('n'.repeat(43), 'v'.repeat(43)),
- })).rejects.toThrow('browser unavailable')
-
- expect(store.transaction).toBeNull()
- })
-
- it('removes authorization data from a browser fallback URL', () => {
- expect(stripNativeSsoCallbackHash(
- `${options.redirectUri}#ylf_sso=sensitive-authorization-result`,
- )).toBe('/auth/callback?platform=native')
- })
-})
-
-function callbackUrl(input: { code: string, issuer: string, nonce: string }): string {
- const result = encodeSsoRedirectResult({
- code: input.code,
- issuer: input.issuer,
- nonce: input.nonce,
- ok: true,
- })
- return `${options.redirectUri}#ylf_sso=${result}`
-}
-
-function sequence(...values: string[]): () => string {
- let index = 0
- return () => values[index++] ?? ''
-}
diff --git a/test/userDataStore.test.ts b/test/userDataStore.test.ts
index 71eba41..3e0b33a 100644
--- a/test/userDataStore.test.ts
+++ b/test/userDataStore.test.ts
@@ -7,9 +7,6 @@ import { addRecipeHistory, clearRecipeHistories, recipeHistories, removeRecipeHi
import { exportLocalUserData, importLocalUserData, localUserData } from '../apps/web/app/composables/store/userData'
import { userDataMeta } from '../apps/web/app/composables/store/userDataMeta'
-vi.mock('@capacitor/browser', () => ({ Browser: {} }))
-vi.mock('@capacitor/preferences', () => ({ Preferences: {} }))
-
const NOW = 1_800_000_000_000
function recipe(name: string, id?: number): DbRecipeItem {
diff --git a/test/yunlefunAuth.test.ts b/test/yunlefunAuth.test.ts
index 9d5744d..6b4f085 100644
--- a/test/yunlefunAuth.test.ts
+++ b/test/yunlefunAuth.test.ts
@@ -31,8 +31,6 @@ describe('yunlefun auth controller', () => {
const identity = fakeIdentityAdapter()
const controller = createYunlefunAuthController({
identity,
- native: fakeAuthorizationAdapter(),
- platform: 'web',
web,
})
@@ -46,29 +44,17 @@ describe('yunlefun auth controller', () => {
expect(identity.adopted).toEqual([authorization])
})
- it('opens the platform-appropriate authorization surface', async () => {
+ it('opens the web authorization surface', async () => {
const web = fakeAuthorizationAdapter()
- const native = fakeAuthorizationAdapter()
- const webController = createYunlefunAuthController({
+ const controller = createYunlefunAuthController({
identity: fakeIdentityAdapter(),
- native,
- platform: 'web',
- web,
- })
- const nativeController = createYunlefunAuthController({
- identity: fakeIdentityAdapter(),
- native,
- platform: 'native',
web,
})
- await webController.signIn()
- await nativeController.signIn()
+ await controller.signIn()
expect(web.started).toBe(1)
- expect(native.started).toBe(1)
- expect(webController.snapshot().status).toBe('signing-in')
- expect(nativeController.snapshot().status).toBe('signing-in')
+ expect(controller.snapshot().status).toBe('signing-in')
})
it('adopts a host authorization without leaving the current page', async () => {
@@ -76,8 +62,6 @@ describe('yunlefun auth controller', () => {
const identity = fakeIdentityAdapter()
const controller = createYunlefunAuthController({
identity,
- native: fakeAuthorizationAdapter(),
- platform: 'web',
web,
})
@@ -95,8 +79,6 @@ describe('yunlefun auth controller', () => {
const identity = fakeIdentityAdapter(account)
const controller = createYunlefunAuthController({
identity,
- native: fakeAuthorizationAdapter(),
- platform: 'web',
web: fakeAuthorizationAdapter(),
})
await controller.initialize()
@@ -119,8 +101,6 @@ describe('yunlefun auth controller', () => {
}
const controller = createYunlefunAuthController({
identity,
- native: fakeAuthorizationAdapter(),
- platform: 'web',
web: fakeAuthorizationAdapter(),
})
await controller.initialize()
@@ -133,22 +113,6 @@ describe('yunlefun auth controller', () => {
status: 'error',
})
})
-
- it('adopts an authorization delivered after the native app resumes', async () => {
- const identity = fakeIdentityAdapter()
- const controller = createYunlefunAuthController({
- identity,
- native: fakeAuthorizationAdapter(),
- platform: 'native',
- web: fakeAuthorizationAdapter(),
- })
- await controller.initialize()
-
- await controller.handleAuthorization(authorization)
-
- expect(identity.adopted).toEqual([authorization])
- expect(controller.snapshot().status).toBe('signed-in')
- })
})
function fakeAuthorizationAdapter(
diff --git a/test/yunlefunAuthAdapter.test.ts b/test/yunlefunAuthAdapter.test.ts
index 2c7fd91..acae39e 100644
--- a/test/yunlefunAuthAdapter.test.ts
+++ b/test/yunlefunAuthAdapter.test.ts
@@ -1,30 +1,12 @@
import type { AcquisitionContext, SsoAuthorizationResult } from '@yunlefun/sso'
import type { YunlefunSsoConfig } from '../apps/web/app/utils/yunlefunSsoConfig'
-import { Browser } from '@capacitor/browser'
-import { Preferences } from '@capacitor/preferences'
import { SsoIdentityAdoptionError } from '@yunlefun/sso/browser'
-import { beforeEach, describe, expect, it, vi } from 'vitest'
+import { describe, expect, it, vi } from 'vitest'
import {
createCloudbaseIdentityAdapter,
- createNativeYunlefunAuthorizationAdapter,
createWebYunlefunAuthorizationAdapter,
} from '../apps/web/app/adapters/yunlefunAuth'
-vi.mock('@capacitor/browser', () => ({
- Browser: {
- close: vi.fn(),
- open: vi.fn(),
- },
-}))
-
-vi.mock('@capacitor/preferences', () => ({
- Preferences: {
- get: vi.fn(async () => ({ value: null })),
- remove: vi.fn(),
- set: vi.fn(),
- },
-}))
-
const config: YunlefunSsoConfig = {
cloudbaseEnv: 'yunlefun-production',
exchange: {
@@ -135,41 +117,3 @@ describe('cloudbase identity adapter', () => {
await expect(identity.signOut()).rejects.toThrow('CloudBase sign-out failed')
})
})
-
-describe('native authorization adapter', () => {
- beforeEach(() => {
- vi.clearAllMocks()
- })
-
- it('clears the pending transaction when authorization is cancelled', async () => {
- const nativeConfig: YunlefunSsoConfig = {
- ...config,
- redirect: {
- ...config.redirect,
- clientId: 'cook-mobile',
- redirectUri: 'https://cook.yunyoujun.cn/auth/callback?platform=native',
- },
- }
- const adapter = createNativeYunlefunAuthorizationAdapter(nativeConfig, async () => null)
-
- await adapter.start()
- expect(Preferences.set).toHaveBeenCalledOnce()
- expect(Browser.open).toHaveBeenCalledOnce()
-
- await adapter.cancel()
- expect(Preferences.remove).toHaveBeenCalledWith({
- key: 'cook:sso:v3:native-transaction',
- })
- })
-
- it('serializes acquisition into the actual native browser SSO URL', async () => {
- const adapter = createNativeYunlefunAuthorizationAdapter(config, async () => null, () => acquisition)
- await adapter.start()
- const url = new URL(vi.mocked(Browser.open).mock.calls[0]![0].url)
- expect(JSON.parse(url.searchParams.get('acquisition')!)).toEqual(acquisition)
- expect(url.searchParams.get('client_id')).toBe('cook-web')
- expect(url.searchParams.get('code_challenge_method')).toBe('S256')
- const transaction = JSON.parse(vi.mocked(Preferences.set).mock.calls[0]![0].value)
- expect(transaction.acquisition).toEqual(acquisition)
- })
-})
diff --git a/test/yunlefunSsoConfig.test.ts b/test/yunlefunSsoConfig.test.ts
index 5b24a1b..191e0a5 100644
--- a/test/yunlefunSsoConfig.test.ts
+++ b/test/yunlefunSsoConfig.test.ts
@@ -5,8 +5,6 @@ const validConfig = {
clientId: 'cook-web',
cloudbaseEnv: 'yunlefun-8g7ybcxc7345c490',
exchangeUrl: 'https://api.yunle.fun/sso-ticket',
- nativeClientId: 'cook-mobile',
- nativeRedirectUri: 'https://cook.yunyoujun.cn/auth/callback?platform=native',
redirectUri: 'https://cook.yunyoujun.cn/auth/callback',
redirectUris: 'https://cook.yunyoujun.cn/auth/callback,https://cook.yunle.fun/auth/callback',
scope: 'identity:bootstrap',
@@ -17,7 +15,6 @@ describe('resolveYunlefunSsoConfig', () => {
it('accepts the exact registered production web origin', () => {
expect(resolveYunlefunSsoConfig(validConfig, {
currentOrigin: 'https://cook.yunyoujun.cn',
- platform: 'web',
})).toEqual({
ok: true,
config: {
@@ -38,7 +35,6 @@ describe('resolveYunlefunSsoConfig', () => {
it('selects the registered callback for the current production web origin', () => {
expect(resolveYunlefunSsoConfig(validConfig, {
currentOrigin: 'https://cook.yunle.fun',
- platform: 'web',
})).toMatchObject({
ok: true,
config: {
@@ -53,7 +49,6 @@ describe('resolveYunlefunSsoConfig', () => {
it('fails closed on an unregistered HTTP development origin', () => {
expect(resolveYunlefunSsoConfig(validConfig, {
currentOrigin: 'http://127.0.0.1:4173',
- platform: 'web',
})).toEqual({
ok: false,
message: '当前域名尚未登记为登录回跳地址',
@@ -63,27 +58,9 @@ describe('resolveYunlefunSsoConfig', () => {
it('fails closed on an unregistered HTTPS origin', () => {
expect(resolveYunlefunSsoConfig(validConfig, {
currentOrigin: 'https://cook.example.com',
- platform: 'web',
})).toEqual({
ok: false,
message: '当前域名尚未登记为登录回跳地址',
})
})
-
- it('uses only the registered HTTPS callback in a native container', () => {
- const result = resolveYunlefunSsoConfig(validConfig, {
- currentOrigin: 'capacitor://localhost',
- platform: 'native',
- })
-
- expect(result).toMatchObject({
- ok: true,
- config: {
- redirect: {
- clientId: 'cook-mobile',
- redirectUri: 'https://cook.yunyoujun.cn/auth/callback?platform=native',
- },
- },
- })
- })
})