expo-invoke 1.0.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 (144) hide show
  1. package/MIGRATION.md +125 -0
  2. package/README.md +942 -0
  3. package/SECURITY.md +35 -0
  4. package/android/build.gradle +42 -0
  5. package/android/src/main/java/expo/modules/invoke/AppActionsHandler.kt +74 -0
  6. package/android/src/main/java/expo/modules/invoke/ExpoInvokeModule.kt +135 -0
  7. package/android/src/main/java/expo/modules/invoke/QuickTileService.kt +63 -0
  8. package/android/src/main/java/expo/modules/invoke/ShortcutsHelper.kt +72 -0
  9. package/build/cli/commands/generate.d.ts +1 -0
  10. package/build/cli/commands/generate.js +119 -0
  11. package/build/cli/commands/generate.js.map +1 -0
  12. package/build/cli/commands/test.d.ts +1 -0
  13. package/build/cli/commands/test.js +53 -0
  14. package/build/cli/commands/test.js.map +1 -0
  15. package/build/cli/commands/validate.d.ts +1 -0
  16. package/build/cli/commands/validate.js +116 -0
  17. package/build/cli/commands/validate.js.map +1 -0
  18. package/build/cli/index.d.ts +2 -0
  19. package/build/cli/index.js +37 -0
  20. package/build/cli/index.js.map +1 -0
  21. package/build/plugin/android/withAndroidInvoke.d.ts +8 -0
  22. package/build/plugin/android/withAndroidInvoke.js +106 -0
  23. package/build/plugin/android/withAndroidInvoke.js.map +1 -0
  24. package/build/plugin/codegen/generateActionsXml.d.ts +2 -0
  25. package/build/plugin/codegen/generateActionsXml.js +69 -0
  26. package/build/plugin/codegen/generateActionsXml.js.map +1 -0
  27. package/build/plugin/codegen/generateShortcutsXml.d.ts +2 -0
  28. package/build/plugin/codegen/generateShortcutsXml.js +45 -0
  29. package/build/plugin/codegen/generateShortcutsXml.js.map +1 -0
  30. package/build/plugin/codegen/generateSwiftIntents.d.ts +2 -0
  31. package/build/plugin/codegen/generateSwiftIntents.js +129 -0
  32. package/build/plugin/codegen/generateSwiftIntents.js.map +1 -0
  33. package/build/plugin/ios/withIOSInvoke.d.ts +9 -0
  34. package/build/plugin/ios/withIOSInvoke.js +83 -0
  35. package/build/plugin/ios/withIOSInvoke.js.map +1 -0
  36. package/build/plugin/src/withInvoke.d.ts +16 -0
  37. package/build/plugin/src/withInvoke.js +13 -0
  38. package/build/plugin/src/withInvoke.js.map +1 -0
  39. package/build/src/components/AddToSiriButton.d.ts +18 -0
  40. package/build/src/components/AddToSiriButton.d.ts.map +1 -0
  41. package/build/src/components/AddToSiriButton.js +35 -0
  42. package/build/src/components/AddToSiriButton.js.map +1 -0
  43. package/build/src/components/InvokeDebugger.d.ts +12 -0
  44. package/build/src/components/InvokeDebugger.d.ts.map +1 -0
  45. package/build/src/components/InvokeDebugger.js +122 -0
  46. package/build/src/components/InvokeDebugger.js.map +1 -0
  47. package/build/src/components/ShortcutChip.d.ts +20 -0
  48. package/build/src/components/ShortcutChip.d.ts.map +1 -0
  49. package/build/src/components/ShortcutChip.js +44 -0
  50. package/build/src/components/ShortcutChip.js.map +1 -0
  51. package/build/src/hooks/useAddToSiri.d.ts +9 -0
  52. package/build/src/hooks/useAddToSiri.d.ts.map +1 -0
  53. package/build/src/hooks/useAddToSiri.js +15 -0
  54. package/build/src/hooks/useAddToSiri.js.map +1 -0
  55. package/build/src/hooks/useDonation.d.ts +26 -0
  56. package/build/src/hooks/useDonation.d.ts.map +1 -0
  57. package/build/src/hooks/useDonation.js +21 -0
  58. package/build/src/hooks/useDonation.js.map +1 -0
  59. package/build/src/hooks/useFocusFilter.d.ts +11 -0
  60. package/build/src/hooks/useFocusFilter.d.ts.map +1 -0
  61. package/build/src/hooks/useFocusFilter.js +24 -0
  62. package/build/src/hooks/useFocusFilter.js.map +1 -0
  63. package/build/src/hooks/useHandoff.d.ts +29 -0
  64. package/build/src/hooks/useHandoff.d.ts.map +1 -0
  65. package/build/src/hooks/useHandoff.js +27 -0
  66. package/build/src/hooks/useHandoff.js.map +1 -0
  67. package/build/src/hooks/useInvoke.d.ts +43 -0
  68. package/build/src/hooks/useInvoke.d.ts.map +1 -0
  69. package/build/src/hooks/useInvoke.js +70 -0
  70. package/build/src/hooks/useInvoke.js.map +1 -0
  71. package/build/src/hooks/useInvokeAnalytics.d.ts +23 -0
  72. package/build/src/hooks/useInvokeAnalytics.d.ts.map +1 -0
  73. package/build/src/hooks/useInvokeAnalytics.js +27 -0
  74. package/build/src/hooks/useInvokeAnalytics.js.map +1 -0
  75. package/build/src/hooks/useInvokeHistory.d.ts +11 -0
  76. package/build/src/hooks/useInvokeHistory.d.ts.map +1 -0
  77. package/build/src/hooks/useInvokeHistory.js +26 -0
  78. package/build/src/hooks/useInvokeHistory.js.map +1 -0
  79. package/build/src/hooks/useInvokeInit.d.ts +16 -0
  80. package/build/src/hooks/useInvokeInit.d.ts.map +1 -0
  81. package/build/src/hooks/useInvokeInit.js +32 -0
  82. package/build/src/hooks/useInvokeInit.js.map +1 -0
  83. package/build/src/hooks/useLiveActivityIntent.d.ts +21 -0
  84. package/build/src/hooks/useLiveActivityIntent.d.ts.map +1 -0
  85. package/build/src/hooks/useLiveActivityIntent.js +9 -0
  86. package/build/src/hooks/useLiveActivityIntent.js.map +1 -0
  87. package/build/src/hooks/useQuickTile.d.ts +23 -0
  88. package/build/src/hooks/useQuickTile.d.ts.map +1 -0
  89. package/build/src/hooks/useQuickTile.js +15 -0
  90. package/build/src/hooks/useQuickTile.js.map +1 -0
  91. package/build/src/hooks/useShortcuts.d.ts +25 -0
  92. package/build/src/hooks/useShortcuts.d.ts.map +1 -0
  93. package/build/src/hooks/useShortcuts.js +23 -0
  94. package/build/src/hooks/useShortcuts.js.map +1 -0
  95. package/build/src/hooks/useSpotlight.d.ts +23 -0
  96. package/build/src/hooks/useSpotlight.d.ts.map +1 -0
  97. package/build/src/hooks/useSpotlight.js +13 -0
  98. package/build/src/hooks/useSpotlight.js.map +1 -0
  99. package/build/src/hooks/useWidgetData.d.ts +20 -0
  100. package/build/src/hooks/useWidgetData.d.ts.map +1 -0
  101. package/build/src/hooks/useWidgetData.js +12 -0
  102. package/build/src/hooks/useWidgetData.js.map +1 -0
  103. package/build/src/index.d.ts +32 -0
  104. package/build/src/index.d.ts.map +1 -0
  105. package/build/src/index.js +27 -0
  106. package/build/src/index.js.map +1 -0
  107. package/build/src/module.d.ts +25 -0
  108. package/build/src/module.d.ts.map +1 -0
  109. package/build/src/module.js +102 -0
  110. package/build/src/module.js.map +1 -0
  111. package/build/src/types/index.d.ts +156 -0
  112. package/build/src/types/index.d.ts.map +1 -0
  113. package/build/src/types/index.js +4 -0
  114. package/build/src/types/index.js.map +1 -0
  115. package/build/src/utils/actionStore.d.ts +6 -0
  116. package/build/src/utils/actionStore.d.ts.map +1 -0
  117. package/build/src/utils/actionStore.js +32 -0
  118. package/build/src/utils/actionStore.js.map +1 -0
  119. package/build/src/utils/analytics.d.ts +12 -0
  120. package/build/src/utils/analytics.d.ts.map +1 -0
  121. package/build/src/utils/analytics.js +29 -0
  122. package/build/src/utils/analytics.js.map +1 -0
  123. package/build/src/utils/testing.d.ts +39 -0
  124. package/build/src/utils/testing.d.ts.map +1 -0
  125. package/build/src/utils/testing.js +58 -0
  126. package/build/src/utils/testing.js.map +1 -0
  127. package/build/src/utils/validation.d.ts +11 -0
  128. package/build/src/utils/validation.d.ts.map +1 -0
  129. package/build/src/utils/validation.js +128 -0
  130. package/build/src/utils/validation.js.map +1 -0
  131. package/expo-module.config.json +9 -0
  132. package/ios/Focus/FocusFilterManager.swift +19 -0
  133. package/ios/Intents/BaseInvokeIntent.swift +42 -0
  134. package/ios/Intents/HandoffManager.swift +49 -0
  135. package/ios/Intents/InvokeActionStore.swift +21 -0
  136. package/ios/Intents/InvokeParameterTypes.swift +142 -0
  137. package/ios/LiveActivity/LiveActivityIntentBridge.swift +44 -0
  138. package/ios/Module/ExpoInvokeModule.swift +170 -0
  139. package/ios/Notifications/NotificationActionHandler.swift +80 -0
  140. package/ios/Shortcuts/DonationManager.swift +44 -0
  141. package/ios/Shortcuts/ShortcutsManager.swift +32 -0
  142. package/ios/Shortcuts/SpotlightManager.swift +48 -0
  143. package/ios/Widget/WidgetManager.swift +19 -0
  144. package/package.json +111 -0
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.runValidate = runValidate;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const validation_1 = require("../../src/utils/validation");
40
+ function loadConfig(cwd) {
41
+ var _a, _b, _c;
42
+ // Try app.json first, then app.config.js
43
+ const appJsonPath = path.join(cwd, 'app.json');
44
+ const appConfigPath = path.join(cwd, 'app.config.js');
45
+ let raw;
46
+ if (fs.existsSync(appJsonPath)) {
47
+ try {
48
+ raw = JSON.parse(fs.readFileSync(appJsonPath, 'utf8'));
49
+ }
50
+ catch {
51
+ console.error('❌ Failed to parse app.json');
52
+ return null;
53
+ }
54
+ }
55
+ else if (fs.existsSync(appConfigPath)) {
56
+ try {
57
+ raw = require(appConfigPath);
58
+ if (typeof raw === 'function')
59
+ raw = raw({});
60
+ }
61
+ catch {
62
+ console.error('❌ Failed to load app.config.js');
63
+ return null;
64
+ }
65
+ }
66
+ else {
67
+ console.error('❌ No app.json or app.config.js found in', cwd);
68
+ return null;
69
+ }
70
+ // Navigate to expo-invoke plugin options
71
+ const plugins = (_c = (_b = (_a = raw === null || raw === void 0 ? void 0 : raw.expo) === null || _a === void 0 ? void 0 : _a.plugins) !== null && _b !== void 0 ? _b : raw === null || raw === void 0 ? void 0 : raw.plugins) !== null && _c !== void 0 ? _c : [];
72
+ for (const plugin of plugins) {
73
+ if (Array.isArray(plugin) && plugin[0] === 'expo-invoke') {
74
+ return plugin[1];
75
+ }
76
+ if (plugin === 'expo-invoke') {
77
+ console.error('❌ expo-invoke plugin found but no options provided.');
78
+ return null;
79
+ }
80
+ }
81
+ console.error('❌ expo-invoke plugin not found in app.json plugins array.');
82
+ return null;
83
+ }
84
+ function printResult(result) {
85
+ if (result.warnings.length > 0) {
86
+ console.log(`\n⚠️ ${result.warnings.length} warning(s):`);
87
+ for (const w of result.warnings) {
88
+ console.log(` • [${w.field}] ${w.message}`);
89
+ }
90
+ }
91
+ if (result.errors.length > 0) {
92
+ console.log(`\n❌ ${result.errors.length} error(s):`);
93
+ for (const e of result.errors) {
94
+ console.log(` • [${e.field}] ${e.message}`);
95
+ }
96
+ console.log('\nValidation failed.');
97
+ }
98
+ else {
99
+ console.log('\n✅ Configuration is valid.');
100
+ }
101
+ }
102
+ function runValidate(args) {
103
+ var _a;
104
+ const cwd = (_a = args[0]) !== null && _a !== void 0 ? _a : process.cwd();
105
+ console.log('Validating expo-invoke config in', cwd, '...');
106
+ const config = loadConfig(cwd);
107
+ if (!config) {
108
+ process.exit(1);
109
+ return;
110
+ }
111
+ const result = (0, validation_1.validateConfig)(config);
112
+ printResult(result);
113
+ if (!result.valid)
114
+ process.exit(1);
115
+ }
116
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../cli/commands/validate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const validate_1 = require("./commands/validate");
5
+ const generate_1 = require("./commands/generate");
6
+ const test_1 = require("./commands/test");
7
+ const [, , command, ...rest] = process.argv;
8
+ const USAGE = `
9
+ Usage: npx expo-invoke <command> [options]
10
+
11
+ Commands:
12
+ validate [dir] Validate expo-invoke config in app.json (default: cwd)
13
+ generate [dir] Generate TypeScript types from config (invoke-types.d.ts)
14
+ test [dir] Run expo-invoke test suite
15
+
16
+ Examples:
17
+ npx expo-invoke validate
18
+ npx expo-invoke generate ./my-app
19
+ `.trim();
20
+ switch (command) {
21
+ case 'validate':
22
+ (0, validate_1.runValidate)(rest);
23
+ break;
24
+ case 'generate':
25
+ (0, generate_1.runGenerate)(rest);
26
+ break;
27
+ case 'test':
28
+ (0, test_1.runTest)(rest);
29
+ break;
30
+ default:
31
+ console.log(USAGE);
32
+ if (command) {
33
+ console.error(`\nUnknown command: "${command}"`);
34
+ process.exit(1);
35
+ }
36
+ }
37
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../cli/index.ts"],"names":[],"mappings":";;;AACA,kDAAkD;AAClD,kDAAkD;AAClD,0CAA0C;AAE1C,MAAM,CAAC,EAAE,AAAD,EAAG,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;AAE5C,MAAM,KAAK,GAAG;;;;;;;;;;;CAWb,CAAC,IAAI,EAAE,CAAC;AAET,QAAQ,OAAO,EAAE,CAAC;IAChB,KAAK,UAAU;QACb,IAAA,sBAAW,EAAC,IAAI,CAAC,CAAC;QAClB,MAAM;IACR,KAAK,UAAU;QACb,IAAA,sBAAW,EAAC,IAAI,CAAC,CAAC;QAClB,MAAM;IACR,KAAK,MAAM;QACT,IAAA,cAAO,EAAC,IAAI,CAAC,CAAC;QACd,MAAM;IACR;QACE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,KAAK,CAAC,uBAAuB,OAAO,GAAG,CAAC,CAAC;YACjD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;AACL,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { type ConfigPlugin } from '@expo/config-plugins';
2
+ import type { IntentDefinition, NotificationCategoryDefinition } from '../../src/types';
3
+ interface AndroidInvokeOptions {
4
+ intents: IntentDefinition[];
5
+ notificationActions?: NotificationCategoryDefinition[];
6
+ }
7
+ export declare const withAndroidInvoke: ConfigPlugin<AndroidInvokeOptions>;
8
+ export {};
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.withAndroidInvoke = void 0;
37
+ const config_plugins_1 = require("@expo/config-plugins");
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ const generateActionsXml_1 = require("../codegen/generateActionsXml");
41
+ const generateShortcutsXml_1 = require("../codegen/generateShortcutsXml");
42
+ const withAndroidInvoke = (config, options) => {
43
+ const { intents } = options;
44
+ // 1. AndroidManifest.xml — add QuickTileService + intent filter for App Actions
45
+ config = (0, config_plugins_1.withAndroidManifest)(config, (cfg) => {
46
+ var _a, _b, _c, _d, _e;
47
+ const app = (_a = cfg.modResults.manifest.application) === null || _a === void 0 ? void 0 : _a[0];
48
+ if (!app)
49
+ return cfg;
50
+ app.service = (_b = app.service) !== null && _b !== void 0 ? _b : [];
51
+ app.receiver = (_c = app.receiver) !== null && _c !== void 0 ? _c : [];
52
+ // QuickTileService — use `as any` because @expo/config-plugins types don't model
53
+ // all valid Android manifest service attributes (android:icon, android:permission, etc.)
54
+ const hasQts = app.service.some((s) => { var _a; return ((_a = s.$) === null || _a === void 0 ? void 0 : _a['android:name']) === 'expo.modules.invoke.QuickTileService'; });
55
+ if (!hasQts) {
56
+ app.service.push({
57
+ $: {
58
+ 'android:name': 'expo.modules.invoke.QuickTileService',
59
+ 'android:icon': '@drawable/ic_launcher_foreground',
60
+ 'android:label': '@string/app_name',
61
+ 'android:permission': 'android.permission.BIND_QUICK_SETTINGS_TILE',
62
+ 'android:exported': 'true',
63
+ },
64
+ 'intent-filter': [
65
+ {
66
+ action: [{ $: { 'android:name': 'android.service.quicksettings.action.QS_TILE' } }],
67
+ },
68
+ ],
69
+ });
70
+ }
71
+ // App Actions meta-data on MainActivity — ManifestActivity doesn't type 'meta-data', use `as any`
72
+ const mainActivity = ((_d = app.activity) !== null && _d !== void 0 ? _d : []).find((a) => { var _a, _b; return (_b = (_a = a.$) === null || _a === void 0 ? void 0 : _a['android:name']) === null || _b === void 0 ? void 0 : _b.endsWith('.MainActivity'); });
73
+ if (mainActivity) {
74
+ mainActivity['meta-data'] = (_e = mainActivity['meta-data']) !== null && _e !== void 0 ? _e : [];
75
+ const hasMeta = mainActivity['meta-data'].some((m) => { var _a; return ((_a = m.$) === null || _a === void 0 ? void 0 : _a['android:name']) === 'android.app.shortcuts'; });
76
+ if (!hasMeta) {
77
+ mainActivity['meta-data'].push({
78
+ $: { 'android:name': 'android.app.shortcuts', 'android:resource': '@xml/shortcuts' },
79
+ });
80
+ }
81
+ const hasActions = mainActivity['meta-data'].some((m) => { var _a; return ((_a = m.$) === null || _a === void 0 ? void 0 : _a['android:name']) === 'com.google.android.actions'; });
82
+ if (!hasActions) {
83
+ mainActivity['meta-data'].push({
84
+ $: { 'android:name': 'com.google.android.actions', 'android:resource': '@xml/actions' },
85
+ });
86
+ }
87
+ }
88
+ return cfg;
89
+ });
90
+ // 2. Generate res/xml/actions.xml and shortcuts.xml
91
+ config = (0, config_plugins_1.withDangerousMod)(config, [
92
+ 'android',
93
+ async (cfg) => {
94
+ var _a, _b;
95
+ const packageName = (_b = (_a = cfg.android) === null || _a === void 0 ? void 0 : _a.package) !== null && _b !== void 0 ? _b : 'com.example.app';
96
+ const resXmlDir = path.join(cfg.modRequest.platformProjectRoot, 'app', 'src', 'main', 'res', 'xml');
97
+ fs.mkdirSync(resXmlDir, { recursive: true });
98
+ fs.writeFileSync(path.join(resXmlDir, 'actions.xml'), (0, generateActionsXml_1.generateActionsXml)(intents, packageName), 'utf8');
99
+ fs.writeFileSync(path.join(resXmlDir, 'shortcuts.xml'), (0, generateShortcutsXml_1.generateShortcutsXml)(intents, packageName), 'utf8');
100
+ return cfg;
101
+ },
102
+ ]);
103
+ return config;
104
+ };
105
+ exports.withAndroidInvoke = withAndroidInvoke;
106
+ //# sourceMappingURL=withAndroidInvoke.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"withAndroidInvoke.js","sourceRoot":"","sources":["../../../plugin/android/withAndroidInvoke.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { IntentDefinition } from '../../src/types';
2
+ export declare function generateActionsXml(intents: IntentDefinition[], packageName: string): string;
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateActionsXml = generateActionsXml;
4
+ function escapeXml(s) {
5
+ return s
6
+ .replace(/&/g, '&amp;')
7
+ .replace(/</g, '&lt;')
8
+ .replace(/>/g, '&gt;')
9
+ .replace(/"/g, '&quot;');
10
+ }
11
+ function toBiiName(paramName) {
12
+ var _a;
13
+ // Map common parameter names to standard BII field names
14
+ const map = {
15
+ pickup: 'location',
16
+ destination: 'location',
17
+ location: 'location',
18
+ query: 'query',
19
+ text: 'query',
20
+ name: 'name',
21
+ person: 'person.name',
22
+ contact: 'person.name',
23
+ number: 'number',
24
+ amount: 'number',
25
+ quantity: 'number',
26
+ type: 'category',
27
+ category: 'category',
28
+ };
29
+ return (_a = map[paramName.toLowerCase()]) !== null && _a !== void 0 ? _a : paramName;
30
+ }
31
+ function parameterXml(param, indent = ' ') {
32
+ const biiName = toBiiName(param.name);
33
+ if (param.type === 'enum' && param.options.length > 0) {
34
+ const values = param.options
35
+ .map((o) => `${indent} <value alias="${escapeXml(o.id)}">${escapeXml(o.title)}</value>`)
36
+ .join('\n');
37
+ return `${indent}<parameter name="${param.name}" key="${biiName}" required="${!param.optional}">
38
+ ${values}
39
+ ${indent}</parameter>`;
40
+ }
41
+ return `${indent}<parameter name="${param.name}" key="${biiName}" required="${!param.optional}" />`;
42
+ }
43
+ function intentXml(intent, packageName) {
44
+ var _a;
45
+ const params = (_a = intent.parameters) !== null && _a !== void 0 ? _a : [];
46
+ const paramLines = params.map((p) => parameterXml(p)).join('\n');
47
+ const phraseLines = intent.phrases
48
+ .map((ph) => ` <query-pattern>${escapeXml(ph)}</query-pattern>`)
49
+ .join('\n');
50
+ return ` <action intentName="actions.intent.${intent.id}"
51
+ intentAction="${packageName}.${intent.id}">
52
+ <fulfillment urlTemplate="${packageName}://invoke/${intent.id}{?${params.map((p) => p.name).join(',')}}">
53
+ ${phraseLines}
54
+ ${paramLines}
55
+ </fulfillment>
56
+ </action>`;
57
+ }
58
+ function generateActionsXml(intents, packageName) {
59
+ const actions = intents.map((i) => intentXml(i, packageName)).join('\n\n');
60
+ return `<?xml version="1.0" encoding="utf-8"?>
61
+ <!-- AUTO-GENERATED by expo-invoke config plugin. Do not edit manually. -->
62
+ <actions>
63
+
64
+ ${actions}
65
+
66
+ </actions>
67
+ `;
68
+ }
69
+ //# sourceMappingURL=generateActionsXml.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateActionsXml.js","sourceRoot":"","sources":["../../../plugin/codegen/generateActionsXml.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { IntentDefinition } from '../../src/types';
2
+ export declare function generateShortcutsXml(intents: IntentDefinition[], packageName: string): string;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateShortcutsXml = generateShortcutsXml;
4
+ function escapeXml(s) {
5
+ return s
6
+ .replace(/&/g, '&amp;')
7
+ .replace(/</g, '&lt;')
8
+ .replace(/>/g, '&gt;')
9
+ .replace(/"/g, '&quot;');
10
+ }
11
+ function generateShortcutsXml(intents, packageName) {
12
+ const shortcutIntents = intents.filter((i) => i.shortTitle);
13
+ if (shortcutIntents.length === 0) {
14
+ return `<?xml version="1.0" encoding="utf-8"?>
15
+ <!-- AUTO-GENERATED by expo-invoke config plugin. No static shortcuts defined. -->
16
+ <shortcuts xmlns:android="http://schemas.android.com/apk/res/android" />
17
+ `;
18
+ }
19
+ const items = shortcutIntents.slice(0, 5).map((intent, idx) => {
20
+ var _a;
21
+ const rank = idx + 1;
22
+ return ` <shortcut
23
+ android:shortcutId="${escapeXml(intent.id)}"
24
+ android:enabled="true"
25
+ android:shortcutShortLabel="${escapeXml(((_a = intent.shortTitle) !== null && _a !== void 0 ? _a : intent.title).slice(0, 10))}"
26
+ android:shortcutLongLabel="${escapeXml((intent.title).slice(0, 25))}"
27
+ android:rank="${rank}">
28
+ <intent
29
+ android:action="${escapeXml(packageName)}.SHORTCUT"
30
+ android:targetPackage="${escapeXml(packageName)}"
31
+ android:targetClass="${escapeXml(packageName)}.MainActivity"
32
+ android:data="${escapeXml(packageName)}://invoke/${escapeXml(intent.id)}" />
33
+ <categories android:name="android.shortcut.conversation" />
34
+ </shortcut>`;
35
+ }).join('\n\n');
36
+ return `<?xml version="1.0" encoding="utf-8"?>
37
+ <!-- AUTO-GENERATED by expo-invoke config plugin. Do not edit manually. -->
38
+ <shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
39
+
40
+ ${items}
41
+
42
+ </shortcuts>
43
+ `;
44
+ }
45
+ //# sourceMappingURL=generateShortcutsXml.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateShortcutsXml.js","sourceRoot":"","sources":["../../../plugin/codegen/generateShortcutsXml.ts"],"names":[],"mappings":";;AAUA,oDAsCC;AA9CD,SAAS,SAAS,CAAC,CAAS;IAC1B,OAAO,CAAC;SACL,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7B,CAAC;AAED,SAAgB,oBAAoB,CAClC,OAA2B,EAC3B,WAAmB;IAEnB,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IAE5D,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO;;;CAGV,CAAC;IACA,CAAC;IAED,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;;QAC5D,MAAM,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC;QACrB,OAAO;0BACe,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;;kCAEZ,SAAS,CAAC,CAAC,MAAA,MAAM,CAAC,UAAU,mCAAI,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;iCAC5D,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBACnD,IAAI;;wBAEA,SAAS,CAAC,WAAW,CAAC;+BACf,SAAS,CAAC,WAAW,CAAC;6BACxB,SAAS,CAAC,WAAW,CAAC;sBAC7B,SAAS,CAAC,WAAW,CAAC,aAAa,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;;cAE/D,CAAC;IACb,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEhB,OAAO;;;;EAIP,KAAK;;;CAGN,CAAC;AACF,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { IntentDefinition } from '../../src/types';
2
+ export declare function generateSwiftIntents(intents: IntentDefinition[]): string;
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateSwiftIntents = generateSwiftIntents;
4
+ function toPascalCase(id) {
5
+ return id.split(/[_\s-]+/).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join('');
6
+ }
7
+ function toCamelCase(id) {
8
+ const pascal = toPascalCase(id);
9
+ return pascal.charAt(0).toLowerCase() + pascal.slice(1);
10
+ }
11
+ function swiftParamType(param) {
12
+ switch (param.type) {
13
+ case 'text': return 'String';
14
+ case 'number': return 'Double';
15
+ case 'boolean': return 'Bool';
16
+ case 'date': return 'Date';
17
+ case 'location': return 'LocationEntity';
18
+ case 'enum': return 'EnumEntity';
19
+ case 'person': return 'PersonEntity';
20
+ case 'array':
21
+ switch (param.itemType) {
22
+ case 'text': return '[String]';
23
+ case 'number': return '[Double]';
24
+ case 'location': return '[LocationEntity]';
25
+ default: return '[String]';
26
+ }
27
+ default: return 'String';
28
+ }
29
+ }
30
+ function paramToJSON(param) {
31
+ const name = param.name;
32
+ switch (param.type) {
33
+ case 'location':
34
+ return `if let v = ${name} { params["${name}"] = v.toJSON() }`;
35
+ case 'person':
36
+ return `if let v = ${name} { params["${name}"] = v.toJSON() }`;
37
+ case 'enum':
38
+ return `if let v = ${name} { params["${name}"] = v.id }`;
39
+ case 'date':
40
+ return `if let v = ${name} { params["${name}"] = v.timeIntervalSince1970 * 1000 }`;
41
+ case 'boolean':
42
+ return `params["${name}"] = ${name}`;
43
+ case 'number':
44
+ return `if let v = ${name} { params["${name}"] = v }`;
45
+ case 'array':
46
+ return `if let v = ${name} { params["${name}"] = v }`;
47
+ default:
48
+ return `if let v = ${name} { params["${name}"] = v }`;
49
+ }
50
+ }
51
+ function generateIntentStruct(intent) {
52
+ var _a, _b;
53
+ const structName = `${toPascalCase(intent.id)}Intent`;
54
+ const params = (_a = intent.parameters) !== null && _a !== void 0 ? _a : [];
55
+ const openApp = intent.openAppWhenRun !== false ? 'true' : 'false';
56
+ const paramDecls = params.map((p) => {
57
+ const swiftType = swiftParamType(p);
58
+ const optional = p.optional !== false ? '?' : '';
59
+ const swiftName = toCamelCase(p.name);
60
+ return ` @Parameter(title: "${p.title}")
61
+ var ${swiftName}: ${swiftType}${optional}`;
62
+ }).join('\n\n');
63
+ const paramExtraction = params.map((p) => {
64
+ const swiftName = toCamelCase(p.name);
65
+ const orig = { ...p, name: swiftName };
66
+ return ` ${paramToJSON(orig)}`;
67
+ }).join('\n');
68
+ const spokenResult = intent.spokenResponse
69
+ ? `
70
+ let spoken = "${intent.spokenResponse}"
71
+ return .result(dialog: IntentDialog(full: .init(stringLiteral: spoken)))`
72
+ : `
73
+ return .result()`;
74
+ return `@available(iOS 16.0, *)
75
+ struct ${structName}: AppIntent {
76
+ static var title: LocalizedStringResource = "${intent.title}"
77
+ static var openAppWhenRun: Bool = ${openApp}
78
+ static var description = IntentDescription("${(_b = intent.description) !== null && _b !== void 0 ? _b : intent.title}")
79
+
80
+ ${paramDecls || ' // No parameters'}
81
+
82
+ func perform() async throws -> some IntentResult {
83
+ var params: [String: Any] = [:]
84
+ ${paramExtraction}
85
+ ExpoInvokeModule.writePendingIntent(
86
+ intentId: "${intent.id}",
87
+ source: "siri",
88
+ parameters: params,
89
+ spokenResponse: ${intent.spokenResponse ? `"${intent.spokenResponse}"` : 'nil'}
90
+ )${spokenResult}
91
+ }
92
+ }`;
93
+ }
94
+ function generateShortcutsProvider(intents) {
95
+ const intentRefs = intents.map((i) => {
96
+ const structName = `${toPascalCase(i.id)}Intent`;
97
+ const phrases = i.phrases.map((p) => {
98
+ var _a, _b;
99
+ return ` AppShortcut(
100
+ 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'}"
104
+ )`;
105
+ }).join(',\n');
106
+ return phrases;
107
+ }).join(',\n');
108
+ return `@available(iOS 16.0, *)
109
+ struct InvokeShortcutsProvider: AppShortcutsProvider {
110
+ static var appShortcuts: [AppShortcut] {
111
+ [
112
+ ${intentRefs}
113
+ ]
114
+ }
115
+ }`;
116
+ }
117
+ function generateSwiftIntents(intents) {
118
+ const structs = intents.map(generateIntentStruct).join('\n\n');
119
+ const provider = generateShortcutsProvider(intents);
120
+ return `// AUTO-GENERATED by expo-invoke config plugin. Do not edit manually.
121
+ import AppIntents
122
+ import Foundation
123
+
124
+ ${structs}
125
+
126
+ ${provider}
127
+ `;
128
+ }
129
+ //# sourceMappingURL=generateSwiftIntents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateSwiftIntents.js","sourceRoot":"","sources":["../../../plugin/codegen/generateSwiftIntents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { type ConfigPlugin } from '@expo/config-plugins';
2
+ import type { IntentDefinition } from '../../src/types';
3
+ interface IOSInvokeOptions {
4
+ intents: IntentDefinition[];
5
+ voiceUsageDescription?: string;
6
+ appGroupId?: string;
7
+ }
8
+ export declare const withIOSInvoke: ConfigPlugin<IOSInvokeOptions>;
9
+ export {};