expo-invoke 1.3.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/android/src/main/java/expo/modules/invoke/InteractiveWidgetReceiver.kt +47 -0
  2. package/android/src/main/java/expo/modules/invoke/InvokeSliceProvider.kt +83 -0
  3. package/android/src/main/java/expo/modules/invoke/ShortcutsHelper.kt +38 -32
  4. package/build/plugin/android/withAndroidInvoke.d.ts +3 -1
  5. package/build/plugin/android/withAndroidInvoke.js +71 -15
  6. package/build/plugin/android/withAndroidInvoke.js.map +1 -1
  7. package/build/plugin/codegen/generateSwiftAppClip.d.ts +2 -0
  8. package/build/plugin/codegen/generateSwiftAppClip.js +20 -0
  9. package/build/plugin/codegen/generateSwiftAppClip.js.map +1 -0
  10. package/build/plugin/codegen/generateSwiftEntities.d.ts +2 -0
  11. package/build/plugin/codegen/generateSwiftEntities.js +91 -0
  12. package/build/plugin/codegen/generateSwiftEntities.js.map +1 -0
  13. package/build/plugin/codegen/generateSwiftFocusFilters.d.ts +2 -0
  14. package/build/plugin/codegen/generateSwiftFocusFilters.js +42 -0
  15. package/build/plugin/codegen/generateSwiftFocusFilters.js.map +1 -0
  16. package/build/plugin/codegen/generateSwiftIntents.d.ts +2 -0
  17. package/build/plugin/codegen/generateSwiftIntents.js +43 -13
  18. package/build/plugin/codegen/generateSwiftIntents.js.map +1 -1
  19. package/build/plugin/codegen/generateSwiftWidget.d.ts +35 -0
  20. package/build/plugin/codegen/generateSwiftWidget.js +379 -0
  21. package/build/plugin/codegen/generateSwiftWidget.js.map +1 -0
  22. package/build/plugin/ios/withIOSInvoke.d.ts +25 -1
  23. package/build/plugin/ios/withIOSInvoke.js +83 -10
  24. package/build/plugin/ios/withIOSInvoke.js.map +1 -1
  25. package/build/plugin/ios/withWidgetExtension.d.ts +14 -0
  26. package/build/plugin/ios/withWidgetExtension.js +185 -0
  27. package/build/plugin/ios/withWidgetExtension.js.map +1 -0
  28. package/build/plugin/src/withInvoke.d.ts +45 -3
  29. package/build/plugin/src/withInvoke.js +30 -4
  30. package/build/plugin/src/withInvoke.js.map +1 -1
  31. package/build/src/components/AddToSiriButton.d.ts +1 -1
  32. package/build/src/components/AddToSiriButton.d.ts.map +1 -1
  33. package/build/src/components/InvokeDebugger.d.ts +1 -1
  34. package/build/src/components/InvokeDebugger.d.ts.map +1 -1
  35. package/build/src/components/ShortcutChip.d.ts +1 -1
  36. package/build/src/components/ShortcutChip.d.ts.map +1 -1
  37. package/build/src/hooks/useBackgroundIntent.d.ts +15 -0
  38. package/build/src/hooks/useBackgroundIntent.d.ts.map +1 -0
  39. package/build/src/hooks/useBackgroundIntent.js +41 -0
  40. package/build/src/hooks/useBackgroundIntent.js.map +1 -0
  41. package/build/src/hooks/useEntityQuery.d.ts +26 -0
  42. package/build/src/hooks/useEntityQuery.d.ts.map +1 -0
  43. package/build/src/hooks/useEntityQuery.js +47 -0
  44. package/build/src/hooks/useEntityQuery.js.map +1 -0
  45. package/build/src/hooks/useFocusFilter.d.ts +1 -1
  46. package/build/src/hooks/useFocusFilter.d.ts.map +1 -1
  47. package/build/src/hooks/useFocusFilter.js.map +1 -1
  48. package/build/src/hooks/useFocusFilterState.d.ts +28 -0
  49. package/build/src/hooks/useFocusFilterState.d.ts.map +1 -0
  50. package/build/src/hooks/useFocusFilterState.js +47 -0
  51. package/build/src/hooks/useFocusFilterState.js.map +1 -0
  52. package/build/src/hooks/useInvoke.d.ts.map +1 -1
  53. package/build/src/hooks/useInvoke.js +3 -0
  54. package/build/src/hooks/useInvoke.js.map +1 -1
  55. package/build/src/hooks/useInvokeAnalytics.d.ts +10 -14
  56. package/build/src/hooks/useInvokeAnalytics.d.ts.map +1 -1
  57. package/build/src/hooks/useInvokeAnalytics.js +21 -14
  58. package/build/src/hooks/useInvokeAnalytics.js.map +1 -1
  59. package/build/src/hooks/useInvokeQueue.d.ts +32 -0
  60. package/build/src/hooks/useInvokeQueue.d.ts.map +1 -0
  61. package/build/src/hooks/useInvokeQueue.js +77 -0
  62. package/build/src/hooks/useInvokeQueue.js.map +1 -0
  63. package/build/src/hooks/useLiveActivity.d.ts +37 -0
  64. package/build/src/hooks/useLiveActivity.d.ts.map +1 -0
  65. package/build/src/hooks/useLiveActivity.js +74 -0
  66. package/build/src/hooks/useLiveActivity.js.map +1 -0
  67. package/build/src/hooks/useOTAConfig.d.ts +24 -0
  68. package/build/src/hooks/useOTAConfig.d.ts.map +1 -0
  69. package/build/src/hooks/useOTAConfig.js +40 -0
  70. package/build/src/hooks/useOTAConfig.js.map +1 -0
  71. package/build/src/hooks/usePushToTalk.d.ts +35 -0
  72. package/build/src/hooks/usePushToTalk.d.ts.map +1 -0
  73. package/build/src/hooks/usePushToTalk.js +101 -0
  74. package/build/src/hooks/usePushToTalk.js.map +1 -0
  75. package/build/src/hooks/useSlice.d.ts +19 -0
  76. package/build/src/hooks/useSlice.d.ts.map +1 -0
  77. package/build/src/hooks/useSlice.js +22 -0
  78. package/build/src/hooks/useSlice.js.map +1 -0
  79. package/build/src/index.d.ts +19 -3
  80. package/build/src/index.d.ts.map +1 -1
  81. package/build/src/index.js +16 -1
  82. package/build/src/index.js.map +1 -1
  83. package/build/src/module.d.ts +18 -3
  84. package/build/src/module.d.ts.map +1 -1
  85. package/build/src/module.js +77 -0
  86. package/build/src/module.js.map +1 -1
  87. package/build/src/types/index.d.ts +117 -4
  88. package/build/src/types/index.d.ts.map +1 -1
  89. package/build/src/utils/analytics.d.ts +1 -7
  90. package/build/src/utils/analytics.d.ts.map +1 -1
  91. package/build/src/utils/analytics.js +9 -0
  92. package/build/src/utils/analytics.js.map +1 -1
  93. package/build/src/utils/invokeError.d.ts +28 -0
  94. package/build/src/utils/invokeError.d.ts.map +1 -0
  95. package/build/src/utils/invokeError.js +57 -0
  96. package/build/src/utils/invokeError.js.map +1 -0
  97. package/build/src/utils/otaConfig.d.ts +9 -0
  98. package/build/src/utils/otaConfig.d.ts.map +1 -0
  99. package/build/src/utils/otaConfig.js +45 -0
  100. package/build/src/utils/otaConfig.js.map +1 -0
  101. package/build/src/utils/persistentAnalytics.d.ts +5 -0
  102. package/build/src/utils/persistentAnalytics.d.ts.map +1 -0
  103. package/build/src/utils/persistentAnalytics.js +52 -0
  104. package/build/src/utils/persistentAnalytics.js.map +1 -0
  105. package/build/src/utils/validation.d.ts +12 -0
  106. package/build/src/utils/validation.d.ts.map +1 -1
  107. package/build/src/utils/validation.js +81 -1
  108. package/build/src/utils/validation.js.map +1 -1
  109. package/build/src/web/index.d.ts +39 -0
  110. package/build/src/web/index.d.ts.map +1 -0
  111. package/build/src/web/index.js +37 -0
  112. package/build/src/web/index.js.map +1 -0
  113. package/build/src/web/module.d.ts +40 -0
  114. package/build/src/web/module.d.ts.map +1 -0
  115. package/build/src/web/module.js +46 -0
  116. package/build/src/web/module.js.map +1 -0
  117. package/ios/AppClip/AppClipHandler.swift +41 -0
  118. package/ios/Background/BackgroundIntentBridge.swift +56 -0
  119. package/ios/Entities/EntityQueryBridge.swift +40 -0
  120. package/ios/FocusFilter/FocusFilterRegistrar.swift +40 -0
  121. package/ios/LiveActivity/LiveActivityManager.swift +83 -0
  122. package/ios/PTT/PTTManager.swift +51 -0
  123. package/package.json +2 -1
@@ -1,6 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.swiftWidgetFamily = swiftWidgetFamily;
3
4
  exports.generateSwiftIntents = generateSwiftIntents;
5
+ /** Escape a string for safe embedding inside Swift double-quoted string literals. */
6
+ function escapeSwiftString(s) {
7
+ return s
8
+ .replace(/\\/g, '\\\\')
9
+ .replace(/"/g, '\\"')
10
+ .replace(/\n/g, '\\n')
11
+ .replace(/\r/g, '\\r')
12
+ .replace(/\t/g, '\\t');
13
+ }
4
14
  function toPascalCase(id) {
5
15
  return id.split(/[_\s-]+/).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join('');
6
16
  }
@@ -9,6 +19,7 @@ function toCamelCase(id) {
9
19
  return pascal.charAt(0).toLowerCase() + pascal.slice(1);
10
20
  }
11
21
  function swiftParamType(param) {
22
+ var _a;
12
23
  switch (param.type) {
13
24
  case 'text': return 'String';
14
25
  case 'number': return 'Double';
@@ -24,6 +35,7 @@ function swiftParamType(param) {
24
35
  case 'location': return '[LocationEntity]';
25
36
  default: return '[String]';
26
37
  }
38
+ case 'entity': return `${toPascalCase((_a = param.entityId) !== null && _a !== void 0 ? _a : 'app')}Entity`;
27
39
  default: return 'String';
28
40
  }
29
41
  }
@@ -44,6 +56,8 @@ function paramToJSON(param) {
44
56
  return `if let v = ${name} { params["${name}"] = v }`;
45
57
  case 'array':
46
58
  return `if let v = ${name} { params["${name}"] = v }`;
59
+ case 'entity':
60
+ return `if let v = ${name} { params["${name}"] = v.toJSON() }`;
47
61
  default:
48
62
  return `if let v = ${name} { params["${name}"] = v }`;
49
63
  }
@@ -57,7 +71,7 @@ function generateIntentStruct(intent) {
57
71
  const swiftType = swiftParamType(p);
58
72
  const optional = p.optional !== false ? '?' : '';
59
73
  const swiftName = toCamelCase(p.name);
60
- return ` @Parameter(title: "${p.title}")
74
+ return ` @Parameter(title: "${escapeSwiftString(p.title)}")
61
75
  var ${swiftName}: ${swiftType}${optional}`;
62
76
  }).join('\n\n');
63
77
  const paramExtraction = params.map((p) => {
@@ -67,27 +81,30 @@ function generateIntentStruct(intent) {
67
81
  }).join('\n');
68
82
  const spokenResult = intent.spokenResponse
69
83
  ? `
70
- let spoken = "${intent.spokenResponse}"
84
+ let spoken = "${escapeSwiftString(intent.spokenResponse)}"
71
85
  return .result(dialog: IntentDialog(full: .init(stringLiteral: spoken)))`
72
86
  : `
73
87
  return .result()`;
88
+ const backgroundCall = intent.openAppWhenRun === false
89
+ ? ` await ExpoInvokeBackgroundBridge.shared.dispatch(intentId: "${escapeSwiftString(intent.id)}", parameters: params)`
90
+ : ` ExpoInvokeModule.writePendingIntent(
91
+ intentId: "${escapeSwiftString(intent.id)}",
92
+ source: "siri",
93
+ parameters: params,
94
+ spokenResponse: ${intent.spokenResponse ? `"${escapeSwiftString(intent.spokenResponse)}"` : 'nil'}
95
+ )`;
74
96
  return `@available(iOS 16.0, *)
75
97
  struct ${structName}: AppIntent {
76
- static var title: LocalizedStringResource = "${intent.title}"
98
+ static var title: LocalizedStringResource = "${escapeSwiftString(intent.title)}"
77
99
  static var openAppWhenRun: Bool = ${openApp}
78
- static var description = IntentDescription("${(_b = intent.description) !== null && _b !== void 0 ? _b : intent.title}")
100
+ static var description = IntentDescription("${escapeSwiftString((_b = intent.description) !== null && _b !== void 0 ? _b : intent.title)}")
79
101
 
80
102
  ${paramDecls || ' // No parameters'}
81
103
 
82
104
  func perform() async throws -> some IntentResult {
83
105
  var params: [String: Any] = [:]
84
106
  ${paramExtraction}
85
- ExpoInvokeModule.writePendingIntent(
86
- intentId: "${intent.id}",
87
- source: "siri",
88
- parameters: params,
89
- spokenResponse: ${intent.spokenResponse ? `"${intent.spokenResponse}"` : 'nil'}
90
- )${spokenResult}
107
+ ${backgroundCall}${spokenResult}
91
108
  }
92
109
  }`;
93
110
  }
@@ -98,9 +115,9 @@ function generateShortcutsProvider(intents) {
98
115
  var _a, _b;
99
116
  return ` AppShortcut(
100
117
  intent: ${structName}(),
101
- phrases: ["${p}"],
102
- shortTitle: "${(_a = i.shortTitle) !== null && _a !== void 0 ? _a : i.title}",
103
- systemImageName: "${(_b = i.icon) !== null && _b !== void 0 ? _b : 'star'}"
118
+ phrases: ["${escapeSwiftString(p)}"],
119
+ shortTitle: "${escapeSwiftString((_a = i.shortTitle) !== null && _a !== void 0 ? _a : i.title)}",
120
+ systemImageName: "${escapeSwiftString((_b = i.icon) !== null && _b !== void 0 ? _b : 'star')}"
104
121
  )`;
105
122
  }).join(',\n');
106
123
  return phrases;
@@ -114,6 +131,19 @@ ${intentRefs}
114
131
  }
115
132
  }`;
116
133
  }
134
+ const WIDGET_SIZE_MAP = {
135
+ small: '.systemSmall',
136
+ medium: '.systemMedium',
137
+ large: '.systemLarge',
138
+ extraLarge: '.systemExtraLarge',
139
+ accessory: '.accessoryCircular',
140
+ accessoryStandBy: '.accessoryCorner',
141
+ };
142
+ /** Maps a WidgetSize string to its Swift WidgetFamily case */
143
+ function swiftWidgetFamily(size) {
144
+ var _a;
145
+ return (_a = WIDGET_SIZE_MAP[size]) !== null && _a !== void 0 ? _a : '.systemSmall';
146
+ }
117
147
  function generateSwiftIntents(intents) {
118
148
  const structs = intents.map(generateIntentStruct).join('\n\n');
119
149
  const provider = generateShortcutsProvider(intents);
@@ -1 +1 @@
1
- {"version":3,"file":"generateSwiftIntents.js","sourceRoot":"","sources":["../../../plugin/codegen/generateSwiftIntents.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generateSwiftIntents.js","sourceRoot":"","sources":["../../../plugin/codegen/generateSwiftIntents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ export interface WidgetCodegenOptions {
2
+ /** Display name shown in the widget picker */
3
+ widgetTitle: string;
4
+ /** Description shown in the widget picker */
5
+ widgetDescription: string;
6
+ /** UserDefaults key the app writes widget data to via setWidgetData() */
7
+ widgetDataKey: string;
8
+ /** Hex accent colour, e.g. "#267AD9" */
9
+ widgetAccentColor: string;
10
+ /** URL scheme deep-link opened when widget is tapped, e.g. "myapp://home" */
11
+ widgetDeepLink: string;
12
+ /** iOS App Group identifier shared between app and widget */
13
+ appGroupId: string;
14
+ /** Widget sizes to support */
15
+ widgetSizes: ('small' | 'medium' | 'large')[];
16
+ }
17
+ /**
18
+ * Generates a self-contained SwiftUI Widget Extension source file.
19
+ *
20
+ * The widget reads its display data from a JSON string in the shared App Group's
21
+ * UserDefaults under the key `widgetDataKey`.
22
+ *
23
+ * Expected JSON shape (written by the host app via setWidgetData()):
24
+ * {
25
+ * "count": number, // badge count shown prominently
26
+ * "badgeLabel": string, // label under the count, e.g. "Active Errands"
27
+ * "title": string | null, // main item title
28
+ * "subtitle": string | null, // status / secondary text
29
+ * "detail": string | null, // extra detail line (carrier name, assignee, etc.)
30
+ * "deepLink": string | null, // optional per-item URL override
31
+ * }
32
+ */
33
+ export declare function generateSwiftWidget(opts: WidgetCodegenOptions): string;
34
+ export declare function generateWidgetInfoPlist(): string;
35
+ export declare function generateWidgetEntitlements(appGroupId: string): string;
@@ -0,0 +1,379 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateSwiftWidget = generateSwiftWidget;
4
+ exports.generateWidgetInfoPlist = generateWidgetInfoPlist;
5
+ exports.generateWidgetEntitlements = generateWidgetEntitlements;
6
+ function escapeSwift(s) {
7
+ return s
8
+ .replace(/\\/g, '\\\\')
9
+ .replace(/"/g, '\\"')
10
+ .replace(/\n/g, '\\n')
11
+ .replace(/\r/g, '\\r');
12
+ }
13
+ function hexToSwiftColor(hex) {
14
+ const clean = hex.replace('#', '');
15
+ const r = parseInt(clean.substring(0, 2), 16) / 255;
16
+ const g = parseInt(clean.substring(2, 4), 16) / 255;
17
+ const b = parseInt(clean.substring(4, 6), 16) / 255;
18
+ return `Color(red: ${r.toFixed(3)}, green: ${g.toFixed(3)}, blue: ${b.toFixed(3)})`;
19
+ }
20
+ function familiesClause(sizes) {
21
+ const map = {
22
+ small: '.systemSmall',
23
+ medium: '.systemMedium',
24
+ large: '.systemLarge',
25
+ };
26
+ return sizes.map((s) => { var _a; return (_a = map[s]) !== null && _a !== void 0 ? _a : `.systemSmall`; }).join(', ');
27
+ }
28
+ /**
29
+ * Generates a self-contained SwiftUI Widget Extension source file.
30
+ *
31
+ * The widget reads its display data from a JSON string in the shared App Group's
32
+ * UserDefaults under the key `widgetDataKey`.
33
+ *
34
+ * Expected JSON shape (written by the host app via setWidgetData()):
35
+ * {
36
+ * "count": number, // badge count shown prominently
37
+ * "badgeLabel": string, // label under the count, e.g. "Active Errands"
38
+ * "title": string | null, // main item title
39
+ * "subtitle": string | null, // status / secondary text
40
+ * "detail": string | null, // extra detail line (carrier name, assignee, etc.)
41
+ * "deepLink": string | null, // optional per-item URL override
42
+ * }
43
+ */
44
+ function generateSwiftWidget(opts) {
45
+ const { widgetTitle, widgetDescription, widgetDataKey, widgetAccentColor, widgetDeepLink, appGroupId, widgetSizes, } = opts;
46
+ const accentColor = hexToSwiftColor(widgetAccentColor);
47
+ const bgColor = `Color(red: 0.90, green: 0.96, blue: 1.00)`;
48
+ const families = familiesClause(widgetSizes);
49
+ const hasSmall = widgetSizes.includes('small');
50
+ const hasMedium = widgetSizes.includes('medium');
51
+ const hasLarge = widgetSizes.includes('large');
52
+ const smallCase = hasSmall ? 'case .systemSmall:\n SmallInvokeView(entry: entry)' : '';
53
+ const mediumCase = hasMedium ? 'case .systemMedium:\n MediumInvokeView(entry: entry)' : '';
54
+ const largeCase = hasLarge ? 'case .systemLarge:\n LargeInvokeView(entry: entry)' : '';
55
+ return `// AUTO-GENERATED by expo-invoke — do not edit manually.
56
+ import WidgetKit
57
+ import SwiftUI
58
+
59
+ // MARK: - Data
60
+
61
+ private struct InvokeWidgetData {
62
+ var count: Int
63
+ var badgeLabel: String
64
+ var title: String?
65
+ var subtitle: String?
66
+ var detail: String?
67
+ var deepLink: String?
68
+
69
+ static let empty = InvokeWidgetData(count: 0, badgeLabel: "")
70
+ static let placeholder = InvokeWidgetData(
71
+ count: 2,
72
+ badgeLabel: "${escapeSwift(widgetTitle)}",
73
+ title: "Example Item",
74
+ subtitle: "In Progress",
75
+ detail: "John D.",
76
+ deepLink: nil
77
+ )
78
+ }
79
+
80
+ // MARK: - Timeline Entry
81
+
82
+ struct InvokeWidgetEntry: TimelineEntry {
83
+ let date: Date
84
+ let data: InvokeWidgetData
85
+ }
86
+
87
+ // MARK: - Provider
88
+
89
+ struct InvokeWidgetProvider: TimelineProvider {
90
+ private let appGroup = "${escapeSwift(appGroupId)}"
91
+ private let dataKey = "${escapeSwift(widgetDataKey)}"
92
+
93
+ func placeholder(in context: Context) -> InvokeWidgetEntry {
94
+ InvokeWidgetEntry(date: Date(), data: .placeholder)
95
+ }
96
+
97
+ func getSnapshot(in context: Context, completion: @escaping (InvokeWidgetEntry) -> Void) {
98
+ completion(InvokeWidgetEntry(date: Date(), data: load()))
99
+ }
100
+
101
+ func getTimeline(in context: Context, completion: @escaping (Timeline<InvokeWidgetEntry>) -> Void) {
102
+ let entry = InvokeWidgetEntry(date: Date(), data: load())
103
+ let refresh = Calendar.current.date(byAdding: .minute, value: 15, to: Date()) ?? Date()
104
+ completion(Timeline(entries: [entry], policy: .after(refresh)))
105
+ }
106
+
107
+ private func load() -> InvokeWidgetData {
108
+ guard
109
+ let defaults = UserDefaults(suiteName: appGroup),
110
+ let raw = defaults.string(forKey: dataKey),
111
+ let blob = raw.data(using: .utf8),
112
+ let json = try? JSONSerialization.jsonObject(with: blob) as? [String: Any]
113
+ else { return .empty }
114
+
115
+ return InvokeWidgetData(
116
+ count: json["count"] as? Int ?? 0,
117
+ badgeLabel: json["badgeLabel"] as? String ?? "",
118
+ title: json["title"] as? String,
119
+ subtitle: json["subtitle"] as? String,
120
+ detail: json["detail"] as? String,
121
+ deepLink: json["deepLink"] as? String
122
+ )
123
+ }
124
+ }
125
+
126
+ // MARK: - Shared Helpers
127
+
128
+ private let accentColor = ${accentColor}
129
+ private let bgColor = ${bgColor}
130
+
131
+ private func resolvedURL(entry: InvokeWidgetEntry) -> URL {
132
+ let raw = entry.data.deepLink ?? "${escapeSwift(widgetDeepLink)}"
133
+ return URL(string: raw) ?? URL(string: "${escapeSwift(widgetDeepLink)}")!
134
+ }
135
+
136
+ // MARK: - Small View
137
+
138
+ ${hasSmall ? `struct SmallInvokeView: View {
139
+ let entry: InvokeWidgetEntry
140
+ var body: some View {
141
+ ZStack {
142
+ bgColor.ignoresSafeArea()
143
+ VStack(alignment: .leading, spacing: 6) {
144
+ HStack {
145
+ Image(systemName: "square.grid.2x2.fill")
146
+ .font(.system(size: 16, weight: .semibold))
147
+ .foregroundColor(accentColor)
148
+ Spacer()
149
+ Text("\\(entry.data.count)")
150
+ .font(.system(size: 30, weight: .bold))
151
+ .foregroundColor(accentColor)
152
+ }
153
+ if !entry.data.badgeLabel.isEmpty {
154
+ Text(entry.data.badgeLabel)
155
+ .font(.system(size: 11, weight: .medium))
156
+ .foregroundColor(.secondary)
157
+ }
158
+ Spacer()
159
+ if let title = entry.data.title {
160
+ Text(title)
161
+ .font(.system(size: 12, weight: .semibold))
162
+ .lineLimit(2)
163
+ .foregroundColor(.primary)
164
+ }
165
+ if let sub = entry.data.subtitle {
166
+ Text(sub)
167
+ .font(.system(size: 10))
168
+ .foregroundColor(.secondary)
169
+ }
170
+ }
171
+ .padding(14)
172
+ }
173
+ }
174
+ }` : '// Small size not enabled'}
175
+
176
+ // MARK: - Medium View
177
+
178
+ ${hasMedium ? `struct MediumInvokeView: View {
179
+ let entry: InvokeWidgetEntry
180
+ var body: some View {
181
+ ZStack {
182
+ bgColor.ignoresSafeArea()
183
+ HStack(spacing: 0) {
184
+ VStack(alignment: .leading, spacing: 8) {
185
+ Image(systemName: "square.grid.2x2.fill")
186
+ .font(.system(size: 20, weight: .semibold))
187
+ .foregroundColor(accentColor)
188
+ Text("\\(entry.data.count)")
189
+ .font(.system(size: 36, weight: .bold))
190
+ .foregroundColor(accentColor)
191
+ if !entry.data.badgeLabel.isEmpty {
192
+ Text(entry.data.badgeLabel)
193
+ .font(.system(size: 11, weight: .medium))
194
+ .foregroundColor(.secondary)
195
+ .lineLimit(2)
196
+ }
197
+ }
198
+ .frame(maxHeight: .infinity, alignment: .topLeading)
199
+ .padding(16)
200
+ .frame(minWidth: 100)
201
+
202
+ Rectangle()
203
+ .fill(Color.secondary.opacity(0.18))
204
+ .frame(width: 1)
205
+ .padding(.vertical, 12)
206
+
207
+ VStack(alignment: .leading, spacing: 6) {
208
+ Text("${escapeSwift(widgetTitle)}")
209
+ .font(.system(size: 10, weight: .semibold))
210
+ .foregroundColor(.secondary)
211
+ if let title = entry.data.title {
212
+ Text(title)
213
+ .font(.system(size: 13, weight: .semibold))
214
+ .lineLimit(2)
215
+ .foregroundColor(.primary)
216
+ }
217
+ if let sub = entry.data.subtitle {
218
+ Text(sub)
219
+ .font(.system(size: 11))
220
+ .foregroundColor(.secondary)
221
+ }
222
+ if let detail = entry.data.detail {
223
+ HStack(spacing: 4) {
224
+ Image(systemName: "person.fill")
225
+ .font(.system(size: 9))
226
+ .foregroundColor(.secondary)
227
+ Text(detail)
228
+ .font(.system(size: 11))
229
+ .foregroundColor(.secondary)
230
+ }
231
+ }
232
+ }
233
+ .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
234
+ .padding(16)
235
+ }
236
+ }
237
+ }
238
+ }` : '// Medium size not enabled'}
239
+
240
+ // MARK: - Large View
241
+
242
+ ${hasLarge ? `struct LargeInvokeView: View {
243
+ let entry: InvokeWidgetEntry
244
+ var body: some View {
245
+ ZStack {
246
+ bgColor.ignoresSafeArea()
247
+ VStack(alignment: .leading, spacing: 14) {
248
+ HStack {
249
+ Image(systemName: "square.grid.2x2.fill")
250
+ .font(.system(size: 18, weight: .semibold))
251
+ .foregroundColor(accentColor)
252
+ Text("${escapeSwift(widgetTitle)}")
253
+ .font(.system(size: 17, weight: .bold))
254
+ .foregroundColor(.primary)
255
+ Spacer()
256
+ if entry.data.count > 0 {
257
+ Text("\\(entry.data.count) \\(entry.data.badgeLabel)")
258
+ .font(.system(size: 12, weight: .semibold))
259
+ .foregroundColor(accentColor)
260
+ .padding(.horizontal, 10)
261
+ .padding(.vertical, 4)
262
+ .background(accentColor.opacity(0.12))
263
+ .clipShape(Capsule())
264
+ }
265
+ }
266
+ Divider()
267
+ if let title = entry.data.title {
268
+ VStack(alignment: .leading, spacing: 8) {
269
+ Text(title)
270
+ .font(.system(size: 15, weight: .semibold))
271
+ .foregroundColor(.primary)
272
+ if let sub = entry.data.subtitle {
273
+ Text(sub)
274
+ .font(.system(size: 12))
275
+ .foregroundColor(.secondary)
276
+ }
277
+ if let detail = entry.data.detail {
278
+ HStack(spacing: 6) {
279
+ Image(systemName: "person.circle.fill")
280
+ .font(.system(size: 13))
281
+ .foregroundColor(accentColor)
282
+ Text(detail)
283
+ .font(.system(size: 12))
284
+ .foregroundColor(.secondary)
285
+ }
286
+ }
287
+ }
288
+ .padding(14)
289
+ .frame(maxWidth: .infinity, alignment: .leading)
290
+ .background(Color.white.opacity(0.6))
291
+ .clipShape(RoundedRectangle(cornerRadius: 12))
292
+ } else {
293
+ VStack(spacing: 10) {
294
+ Image(systemName: "square.grid.2x2")
295
+ .font(.system(size: 34))
296
+ .foregroundColor(accentColor.opacity(0.4))
297
+ Text("Nothing here yet")
298
+ .font(.system(size: 13))
299
+ .foregroundColor(.secondary)
300
+ }
301
+ .frame(maxWidth: .infinity)
302
+ .padding(24)
303
+ }
304
+ Spacer()
305
+ }
306
+ .padding(16)
307
+ }
308
+ }
309
+ }` : '// Large size not enabled'}
310
+
311
+ // MARK: - Entry View Router
312
+
313
+ struct InvokeWidgetEntryView: View {
314
+ var entry: InvokeWidgetEntry
315
+ @Environment(\\.widgetFamily) var family
316
+
317
+ var body: some View {
318
+ Group {
319
+ switch family {
320
+ ${[smallCase, mediumCase, largeCase].filter(Boolean).join('\n ')}
321
+ default:
322
+ ${hasSmall ? 'SmallInvokeView(entry: entry)' : hasMedium ? 'MediumInvokeView(entry: entry)' : 'LargeInvokeView(entry: entry)'}
323
+ }
324
+ }
325
+ }
326
+ }
327
+
328
+ // MARK: - Widget Configuration
329
+
330
+ struct InvokeWidget: Widget {
331
+ let kind: String = "InvokeWidget"
332
+
333
+ var body: some WidgetConfiguration {
334
+ StaticConfiguration(kind: kind, provider: InvokeWidgetProvider()) { entry in
335
+ InvokeWidgetEntryView(entry: entry)
336
+ .widgetURL(resolvedURL(entry: entry))
337
+ }
338
+ .configurationDisplayName("${escapeSwift(widgetTitle)}")
339
+ .description("${escapeSwift(widgetDescription)}")
340
+ .supportedFamilies([${families}])
341
+ }
342
+ }
343
+
344
+ // MARK: - Widget Bundle
345
+
346
+ @main
347
+ struct InvokeWidgetBundle: WidgetBundle {
348
+ var body: some Widget {
349
+ InvokeWidget()
350
+ }
351
+ }
352
+ `;
353
+ }
354
+ function generateWidgetInfoPlist() {
355
+ return `<?xml version="1.0" encoding="UTF-8"?>
356
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
357
+ <plist version="1.0">
358
+ <dict>
359
+ <key>NSExtension</key>
360
+ <dict>
361
+ <key>NSExtensionPointIdentifier</key>
362
+ <string>com.apple.widgetkit-extension</string>
363
+ </dict>
364
+ </dict>
365
+ </plist>`;
366
+ }
367
+ function generateWidgetEntitlements(appGroupId) {
368
+ return `<?xml version="1.0" encoding="UTF-8"?>
369
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
370
+ <plist version="1.0">
371
+ <dict>
372
+ <key>com.apple.security.application-groups</key>
373
+ <array>
374
+ <string>${appGroupId}</string>
375
+ </array>
376
+ </dict>
377
+ </plist>`;
378
+ }
379
+ //# sourceMappingURL=generateSwiftWidget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateSwiftWidget.js","sourceRoot":"","sources":["../../../plugin/codegen/generateSwiftWidget.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,33 @@
1
1
  import { type ConfigPlugin } from '@expo/config-plugins';
2
- import type { IntentDefinition } from '../../src/types';
2
+ import type { IntentDefinition, AppEntityDefinition, FocusFilterDefinition, AppClipDefinition } from '../../src/types';
3
3
  interface IOSInvokeOptions {
4
4
  intents: IntentDefinition[];
5
5
  voiceUsageDescription?: string;
6
6
  appGroupId?: string;
7
+ entities?: AppEntityDefinition[];
8
+ focusFilters?: FocusFilterDefinition[];
9
+ appClips?: AppClipDefinition[];
10
+ enablePushToTalk?: boolean;
11
+ pttUsageDescription?: string;
12
+ enableLiveActivities?: boolean;
13
+ liveActivityTypes?: string[];
14
+ /** Enable the built-in WidgetKit extension. Requires appGroupId. */
15
+ enableWidget?: boolean;
16
+ /** Display name shown in the widget picker (defaults to app name) */
17
+ widgetTitle?: string;
18
+ /** Description shown in the widget picker */
19
+ widgetDescription?: string;
20
+ /**
21
+ * UserDefaults key the app writes widget data to via setWidgetData().
22
+ * Defaults to "invokeWidgetData".
23
+ */
24
+ widgetDataKey?: string;
25
+ /** Hex accent colour for the widget UI (defaults to "#267AD9") */
26
+ widgetAccentColor?: string;
27
+ /** URL scheme deep-link opened when widget is tapped */
28
+ widgetDeepLink?: string;
29
+ /** Widget sizes to support (defaults to ["small","medium"]) */
30
+ widgetSizes?: ('small' | 'medium' | 'large')[];
7
31
  }
8
32
  export declare const withIOSInvoke: ConfigPlugin<IOSInvokeOptions>;
9
33
  export {};