@adep/cli 0.4.1 → 0.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +140 -11
  2. package/dist/index.js +34568 -27795
  3. package/dist/vite.js +279 -19
  4. package/dist/worker-entry.js +201 -2
  5. package/package.json +6 -5
  6. package/templates/app-desktop/README.md +67 -2
  7. package/templates/app-desktop/identity-store.mjs +309 -0
  8. package/templates/app-desktop/identity.mjs +517 -0
  9. package/templates/app-desktop/main.cjs +17 -0
  10. package/templates/app-desktop/main.mjs +218 -2
  11. package/templates/app-desktop/offline-runtime.mjs +72 -3
  12. package/templates/app-desktop/package.json +10 -6
  13. package/templates/app-desktop/recovery-ui.mjs +300 -0
  14. package/templates/app-desktop/sync-loop.mjs +137 -0
  15. package/templates/app-mobile/README.md +47 -9
  16. package/templates/app-mobile/package.json +2 -1
  17. package/templates/app-mobile/plugins/adep-bridge/Package.swift +52 -0
  18. package/templates/app-mobile/plugins/adep-bridge/android/build.gradle +34 -3
  19. package/templates/app-mobile/plugins/adep-bridge/android/src/main/AndroidManifest.xml +12 -5
  20. package/templates/app-mobile/plugins/adep-bridge/android/src/main/java/com/adep/bridge/AdepBridge.kt +198 -12
  21. package/templates/app-mobile/plugins/adep-bridge/android/src/main/java/com/adep/bridge/AdepIdentity.kt +342 -0
  22. package/templates/app-mobile/plugins/adep-bridge/android/src/main/java/com/adep/bridge/AdepKeystore.kt +56 -2
  23. package/templates/app-mobile/plugins/adep-bridge/android/src/main/java/com/adep/bridge/AdepSqlite.kt +506 -0
  24. package/templates/app-mobile/plugins/adep-bridge/android/src/main/java/com/adep/bridge/AdepSqliteLogic.kt +235 -0
  25. package/templates/app-mobile/plugins/adep-bridge/dist/plugin.js +30 -0
  26. package/templates/app-mobile/plugins/adep-bridge/ios/AdepBridge.podspec +7 -1
  27. package/templates/app-mobile/plugins/adep-bridge/ios/Sources/AdepBridge.swift +221 -9
  28. package/templates/app-mobile/plugins/adep-bridge/ios/Sources/AdepIdentity.swift +500 -0
  29. package/templates/app-mobile/plugins/adep-bridge/ios/Sources/AdepKeychain.swift +69 -17
  30. package/templates/app-mobile/plugins/adep-bridge/ios/Sources/AdepPermissionGate.swift +25 -4
  31. package/templates/app-mobile/plugins/adep-bridge/ios/Sources/AdepShellConfig.swift +54 -0
  32. package/templates/app-mobile/plugins/adep-bridge/ios/Sources/AdepSqlite.swift +614 -0
  33. package/templates/app-mobile/plugins/adep-bridge/package.json +10 -0
  34. package/templates/app-mobile/template.json +12 -3
  35. package/templates/app-mobile/web/adep-bridge.js +103 -9
  36. package/templates/app-mobile/web/offline-runtime.js +230 -0
  37. package/templates/app-mobile-xtool/AdepShell-Info.plist +24 -0
  38. package/templates/app-mobile-xtool/Package.swift +59 -0
  39. package/templates/app-mobile-xtool/README.md +81 -0
  40. package/templates/app-mobile-xtool/Sources/AdepShell/App.swift +36 -0
  41. package/templates/app-mobile-xtool/Sources/AdepShell/ShellViewController.swift +223 -0
  42. package/templates/app-mobile-xtool/adep.permissions.json +4 -0
  43. package/templates/app-mobile-xtool/app/site/.gitkeep +0 -0
  44. package/templates/app-mobile-xtool/template.json +15 -0
  45. package/templates/app-mobile-xtool/xtool.yml +35 -0
  46. package/templates/app-mobile/plugins/adep-bridge/capacitor.plugin.json +0 -10
@@ -9,14 +9,29 @@ import Foundation
9
9
  public final class AdepPermissionGate {
10
10
  /// 与 bridge/gate.mjs 共用的契约常量。
11
11
  public static let permissionDenied = "PERMISSION_DENIED"
12
- /// 与 CLI 写入文件名一致的契约常量(app/site/adep.permissions.json → cap sync → Public/)。
13
- static let manifestFileName = "adep.permissions.json"
14
12
 
15
13
  public enum Result {
16
14
  case granted
17
15
  case denied(reason: String)
18
16
  }
19
17
 
18
+ /// 与 CLI 写入文件名一致的契约常量(app/site/adep.permissions.json → cap sync → Public/)。
19
+ static let manifestFileName = "adep.permissions.json"
20
+
21
+ /// 清单可能所在的**包内子目录**,按查找顺序排列(`nil` = 包根)。命中即停。
22
+ ///
23
+ /// 候选表已收敛到 `AdepShellConfig.candidateSubdirectories`(APP-027)——权限清单与
24
+ /// 壳配置(`adep.app.json`)走同一条定位路径。两处各写一份的后果是「一个资源看得到、
25
+ /// 另一个看不到」,而症状分别是「门控不可用」与「身份签发静默跳过」。
26
+ ///
27
+ /// 这里保留同义入口(而不是删掉):文档与排障笔记引用的就是这个符号名。
28
+ static var manifestCandidateSubdirectories: [String?] { AdepShellConfig.candidateSubdirectories }
29
+
30
+ /// 按候选顺序定位清单;全缺返回 nil(调用方 fail-closed)。
31
+ static func manifestURL(in bundle: Bundle) -> URL? {
32
+ AdepShellConfig.resourceURL(named: manifestFileName, in: bundle)
33
+ }
34
+
20
35
  private let permissions: [String]
21
36
  private let audit: AdepAuditLog
22
37
 
@@ -25,13 +40,19 @@ public final class AdepPermissionGate {
25
40
  self.audit = audit
26
41
  }
27
42
 
43
+ /// 已加载的声明清单(只读;启动日志与测试断言用,不对外暴露实现细节)。
44
+ var declaredPermissions: [String] { permissions }
45
+
28
46
  /// 从 bundle 读权限清单并装配门控。
29
47
  /// 清单缺失 → throw(调用方 fail-closed:门控建立不了 = 一切原生能力不可用)。
30
48
  static func load(from bundle: Bundle) throws -> AdepPermissionGate {
31
- guard let url = bundle.url(forResource: manifestFileName, withExtension: nil) else {
49
+ guard let url = manifestURL(in: bundle) else {
32
50
  throw NSError(
33
51
  domain: "AdepBridge", code: 1,
34
- userInfo: [NSLocalizedDescriptionKey: "Bundle 缺少 \(manifestFileName)(CLI build 写入、cap sync 同步)"]
52
+ userInfo: [
53
+ NSLocalizedDescriptionKey:
54
+ "Bundle 缺少 \(manifestFileName)(候选位置:包根 / site/ / public/;CLI build 写入、cap sync 或 xtool resources 复制)"
55
+ ]
35
56
  )
36
57
  }
37
58
  let data = try Data(contentsOf: url)
@@ -0,0 +1,54 @@
1
+ import Foundation
2
+
3
+ /// 壳内随包资源的定位(APP-027 抽出;原先是 `AdepPermissionGate` 的私有候选表)。
4
+ ///
5
+ /// 为什么需要候选表(APP-018 现场实测):`Bundle.url(forResource:withExtension:)` **不递归
6
+ /// 子目录**——本机 flat bundle 实测:根下的文件命中,`site/x.json` 与 `site/sub/deep.txt`
7
+ /// 全返回 nil。而两条壳的落点都在子目录里,且 CLI 改不了另一条壳的落点:
8
+ /// - `site/`:xtool 壳(`xtool.yml` 的 `resources: [app/site]`,Packer 的 `copyItem` 递归复制到
9
+ /// `<.app>/site/`);
10
+ /// - `public/`:Capacitor 壳(`cap sync` 把 `webDir: app/site` 同步进 iOS `Public/`)。
11
+ ///
12
+ /// 包根那条留着兼容「平铺到 .app 根」的打包方式。**顺序固定**:根优先(若有平铺副本,
13
+ /// 用它,避免同包两份各说各话时读到的不是期望那份)。
14
+ ///
15
+ /// ⚠️ 这张表是**唯一真相源**:`AdepPermissionGate`(权限清单)与 `AdepIdentity`(壳配置)
16
+ /// 都经此处定位。两处各写一份候选表的后果是「一个资源看得到、另一个看不到」,
17
+ /// 而症状分别是「门控不可用」与「身份签发静默跳过」——两个都像功能没做。
18
+ ///
19
+ /// ⚠️ 不要改用 `url(forResource:withExtension:subdirectory:)` 拼三遍——那是同一个非递归
20
+ /// 语义换了个写法;也不要指望 Foundation 未来会递归(不是它的契约)。
21
+ public enum AdepShellConfig {
22
+ /// 壳配置文件名(CLI `adep app build` 写入 `app/site/` 后随 cap sync / xtool resources 进包)。
23
+ public static let configFileName = "adep.app.json"
24
+
25
+ /// 包内候选子目录(`nil` = 包根),按查找顺序排列。命中即停。
26
+ public static let candidateSubdirectories: [String?] = [nil, "site", "public"]
27
+
28
+ /// 按候选顺序定位随包资源;全缺返回 nil(调用方决定 fail-closed 还是跳过)。
29
+ public static func resourceURL(named fileName: String, in bundle: Bundle) -> URL? {
30
+ for subdirectory in candidateSubdirectories {
31
+ guard let subdirectory else {
32
+ // 包根:走 Bundle 的资源查找(只命中根,不会递归——这正是候选表存在的原因)。
33
+ if let root = bundle.url(forResource: fileName, withExtension: nil) {
34
+ return root
35
+ }
36
+ continue
37
+ }
38
+ let candidate = bundle.bundleURL
39
+ .appendingPathComponent(subdirectory, isDirectory: true)
40
+ .appendingPathComponent(fileName, isDirectory: false)
41
+ if FileManager.default.fileExists(atPath: candidate.path) {
42
+ return candidate
43
+ }
44
+ }
45
+ return nil
46
+ }
47
+
48
+ /// 读随包资源的字节;缺失或读失败返回 nil(读取失败与「不在包里」对调用方的语义相同:
49
+ /// 拿不到内容——但调用方必须把这两件事记成不同的日志,否则排障时会误以为是打包问题)。
50
+ public static func data(named fileName: String, in bundle: Bundle) -> Data? {
51
+ guard let url = resourceURL(named: fileName, in: bundle) else { return nil }
52
+ return try? Data(contentsOf: url)
53
+ }
54
+ }