@teardown/cli 1.2.39 → 2.0.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/teardown.js +11 -1
- package/package.json +77 -57
- package/src/cli/commands/init.ts +254 -0
- package/src/cli/commands/plugins.ts +93 -0
- package/src/cli/commands/prebuild.ts +168 -0
- package/src/cli/commands/run.ts +727 -0
- package/src/cli/commands/start.ts +87 -0
- package/src/cli/commands/validate.ts +62 -0
- package/src/cli/index.ts +59 -0
- package/src/config/index.ts +45 -0
- package/src/config/loader.ts +366 -0
- package/src/config/schema.ts +235 -0
- package/src/config/types.ts +322 -0
- package/src/index.ts +177 -0
- package/src/pipeline/cache.ts +179 -0
- package/src/pipeline/index.ts +10 -0
- package/src/pipeline/stages.ts +692 -0
- package/src/plugins/base.ts +370 -0
- package/src/plugins/capabilities/biometrics.ts +64 -0
- package/src/plugins/capabilities/bluetooth.ts +86 -0
- package/src/plugins/capabilities/calendar.ts +57 -0
- package/src/plugins/capabilities/camera.ts +77 -0
- package/src/plugins/capabilities/contacts.ts +57 -0
- package/src/plugins/capabilities/deep-linking.ts +124 -0
- package/src/plugins/capabilities/firebase.ts +138 -0
- package/src/plugins/capabilities/index.ts +96 -0
- package/src/plugins/capabilities/location.ts +87 -0
- package/src/plugins/capabilities/photo-library.ts +80 -0
- package/src/plugins/capabilities/push-notifications.ts +98 -0
- package/src/plugins/capabilities/sign-in-with-apple.ts +53 -0
- package/src/plugins/context.ts +220 -0
- package/src/plugins/index.ts +26 -0
- package/src/plugins/resolver.ts +321 -0
- package/src/templates/generator.ts +507 -0
- package/src/templates/index.ts +9 -0
- package/src/templates/paths.ts +25 -0
- package/src/transformers/android/gradle.ts +400 -0
- package/src/transformers/android/index.ts +19 -0
- package/src/transformers/android/manifest.ts +506 -0
- package/src/transformers/index.ts +39 -0
- package/src/transformers/ios/entitlements.ts +283 -0
- package/src/transformers/ios/index.ts +10 -0
- package/src/transformers/ios/pbxproj.ts +267 -0
- package/src/transformers/ios/plist.ts +198 -0
- package/src/utils/fs.ts +429 -0
- package/src/utils/index.ts +21 -0
- package/src/utils/logger.ts +203 -0
- package/templates/.gitignore +63 -0
- package/templates/Gemfile +3 -0
- package/templates/android/app/build.gradle.kts +97 -0
- package/templates/android/app/proguard-rules.pro +10 -0
- package/templates/android/app/src/main/AndroidManifest.xml +26 -0
- package/templates/android/app/src/main/java/com/appname/MainActivity.kt +22 -0
- package/templates/android/app/src/main/java/com/appname/MainApplication.kt +44 -0
- package/templates/android/app/src/main/res/values/strings.xml +3 -0
- package/templates/android/app/src/main/res/values/styles.xml +7 -0
- package/templates/android/build.gradle.kts +44 -0
- package/templates/android/gradle.properties +39 -0
- package/templates/android/settings.gradle.kts +12 -0
- package/templates/babel.config.js +15 -0
- package/templates/index.js +7 -0
- package/templates/ios/.xcode.env +11 -0
- package/templates/ios/AppName/AppDelegate.swift +25 -0
- package/templates/ios/AppName/AppName-Bridging-Header.h +4 -0
- package/templates/ios/AppName/AppName.entitlements +6 -0
- package/templates/ios/AppName/Images.xcassets/AppIcon.appiconset/Contents.json +35 -0
- package/templates/ios/AppName/Images.xcassets/Contents.json +6 -0
- package/templates/ios/AppName/Info.plist +49 -0
- package/templates/ios/AppName/LaunchScreen.storyboard +38 -0
- package/templates/ios/AppName.xcodeproj/project.pbxproj +402 -0
- package/templates/ios/AppName.xcodeproj/xcshareddata/xcschemes/AppName.xcscheme +78 -0
- package/templates/ios/Podfile +35 -0
- package/templates/metro.config.js +41 -0
- package/templates/package.json +57 -0
- package/templates/react-native.config.js +8 -0
- package/templates/src/app/index.tsx +34 -0
- package/templates/src/assets/fonts/.gitkeep +1 -0
- package/templates/src/assets/images/.gitkeep +1 -0
- package/templates/src/components/ui/accordion.tsx +114 -0
- package/templates/src/components/ui/avatar.tsx +75 -0
- package/templates/src/components/ui/button.tsx +93 -0
- package/templates/src/components/ui/card.tsx +120 -0
- package/templates/src/components/ui/checkbox.tsx +133 -0
- package/templates/src/components/ui/chip.tsx +95 -0
- package/templates/src/components/ui/dialog.tsx +134 -0
- package/templates/src/components/ui/divider.tsx +67 -0
- package/templates/src/components/ui/error-view.tsx +82 -0
- package/templates/src/components/ui/form-field.tsx +101 -0
- package/templates/src/components/ui/index.ts +100 -0
- package/templates/src/components/ui/popover.tsx +92 -0
- package/templates/src/components/ui/pressable-feedback.tsx +88 -0
- package/templates/src/components/ui/radio-group.tsx +153 -0
- package/templates/src/components/ui/scroll-shadow.tsx +108 -0
- package/templates/src/components/ui/select.tsx +165 -0
- package/templates/src/components/ui/skeleton-group.tsx +97 -0
- package/templates/src/components/ui/skeleton.tsx +87 -0
- package/templates/src/components/ui/spinner.tsx +87 -0
- package/templates/src/components/ui/surface.tsx +95 -0
- package/templates/src/components/ui/switch.tsx +124 -0
- package/templates/src/components/ui/tabs.tsx +154 -0
- package/templates/src/components/ui/text-field.tsx +106 -0
- package/templates/src/components/ui/toast.tsx +129 -0
- package/templates/src/contexts/.gitkeep +2 -0
- package/templates/src/core/clients/api/api.client.ts +113 -0
- package/templates/src/core/clients/api/index.ts +1 -0
- package/templates/src/core/clients/storage/index.ts +1 -0
- package/templates/src/core/clients/storage/storage.client.ts +121 -0
- package/templates/src/core/constants/index.ts +19 -0
- package/templates/src/core/core.ts +40 -0
- package/templates/src/core/index.ts +10 -0
- package/templates/src/global.css +87 -0
- package/templates/src/hooks/index.ts +6 -0
- package/templates/src/hooks/use-debounce.ts +23 -0
- package/templates/src/hooks/use-mounted.ts +21 -0
- package/templates/src/index.ts +28 -0
- package/templates/src/lib/index.ts +5 -0
- package/templates/src/lib/utils.ts +115 -0
- package/templates/src/modules/.gitkeep +6 -0
- package/templates/src/navigation/index.ts +8 -0
- package/templates/src/navigation/navigation-provider.tsx +36 -0
- package/templates/src/navigation/router.tsx +137 -0
- package/templates/src/providers/app.provider.tsx +29 -0
- package/templates/src/providers/index.ts +5 -0
- package/templates/src/routes/(tabs)/_layout.tsx +42 -0
- package/templates/src/routes/(tabs)/explore.tsx +161 -0
- package/templates/src/routes/(tabs)/home.tsx +138 -0
- package/templates/src/routes/(tabs)/profile.tsx +151 -0
- package/templates/src/routes/_layout.tsx +18 -0
- package/templates/src/routes/settings.tsx +194 -0
- package/templates/src/screens/auth/index.ts +6 -0
- package/templates/src/screens/auth/login.tsx +165 -0
- package/templates/src/screens/auth/register.tsx +203 -0
- package/templates/src/screens/home.tsx +204 -0
- package/templates/src/screens/index.ts +17 -0
- package/templates/src/screens/profile.tsx +210 -0
- package/templates/src/screens/settings.tsx +216 -0
- package/templates/src/screens/welcome.tsx +101 -0
- package/templates/src/styles/index.ts +103 -0
- package/templates/src/types/common.ts +71 -0
- package/templates/src/types/index.ts +5 -0
- package/templates/tsconfig.json +14 -0
- package/README.md +0 -15
- package/assets/favicon.ico +0 -0
- package/dist/commands/dev/dev.d.ts +0 -22
- package/dist/commands/dev/dev.js +0 -56
- package/dist/commands/dev/dev.js.map +0 -1
- package/dist/commands/init/init-teardown.d.ts +0 -9
- package/dist/commands/init/init-teardown.js +0 -27
- package/dist/commands/init/init-teardown.js.map +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -21
- package/dist/index.js.map +0 -1
- package/dist/modules/dev/dev-menu/keyboard-handler.d.ts +0 -21
- package/dist/modules/dev/dev-menu/keyboard-handler.js +0 -139
- package/dist/modules/dev/dev-menu/keyboard-handler.js.map +0 -1
- package/dist/modules/dev/dev-menu/open-debugger-keyboard-handler.d.ts +0 -18
- package/dist/modules/dev/dev-menu/open-debugger-keyboard-handler.js +0 -106
- package/dist/modules/dev/dev-menu/open-debugger-keyboard-handler.js.map +0 -1
- package/dist/modules/dev/dev-server/cdp/cdp.adapter.d.ts +0 -6
- package/dist/modules/dev/dev-server/cdp/cdp.adapter.js +0 -13
- package/dist/modules/dev/dev-server/cdp/cdp.adapter.js.map +0 -1
- package/dist/modules/dev/dev-server/cdp/index.d.ts +0 -2
- package/dist/modules/dev/dev-server/cdp/index.js +0 -19
- package/dist/modules/dev/dev-server/cdp/index.js.map +0 -1
- package/dist/modules/dev/dev-server/cdp/types.d.ts +0 -107
- package/dist/modules/dev/dev-server/cdp/types.js +0 -3
- package/dist/modules/dev/dev-server/cdp/types.js.map +0 -1
- package/dist/modules/dev/dev-server/dev-server-checker.d.ts +0 -22
- package/dist/modules/dev/dev-server/dev-server-checker.js +0 -73
- package/dist/modules/dev/dev-server/dev-server-checker.js.map +0 -1
- package/dist/modules/dev/dev-server/dev-server.d.ts +0 -74
- package/dist/modules/dev/dev-server/dev-server.js +0 -272
- package/dist/modules/dev/dev-server/dev-server.js.map +0 -1
- package/dist/modules/dev/dev-server/inspector/device.d.ts +0 -46
- package/dist/modules/dev/dev-server/inspector/device.event-reporter.d.ts +0 -37
- package/dist/modules/dev/dev-server/inspector/device.event-reporter.js +0 -166
- package/dist/modules/dev/dev-server/inspector/device.event-reporter.js.map +0 -1
- package/dist/modules/dev/dev-server/inspector/device.js +0 -578
- package/dist/modules/dev/dev-server/inspector/device.js.map +0 -1
- package/dist/modules/dev/dev-server/inspector/inspector.d.ts +0 -27
- package/dist/modules/dev/dev-server/inspector/inspector.js +0 -225
- package/dist/modules/dev/dev-server/inspector/inspector.js.map +0 -1
- package/dist/modules/dev/dev-server/inspector/types.d.ts +0 -156
- package/dist/modules/dev/dev-server/inspector/types.js +0 -3
- package/dist/modules/dev/dev-server/inspector/types.js.map +0 -1
- package/dist/modules/dev/dev-server/inspector/wss/servers/debugger-connection.server.d.ts +0 -14
- package/dist/modules/dev/dev-server/inspector/wss/servers/debugger-connection.server.js +0 -63
- package/dist/modules/dev/dev-server/inspector/wss/servers/debugger-connection.server.js.map +0 -1
- package/dist/modules/dev/dev-server/inspector/wss/servers/device-connection.server.d.ts +0 -19
- package/dist/modules/dev/dev-server/inspector/wss/servers/device-connection.server.js +0 -66
- package/dist/modules/dev/dev-server/inspector/wss/servers/device-connection.server.js.map +0 -1
- package/dist/modules/dev/dev-server/plugins/devtools.plugin.d.ts +0 -1
- package/dist/modules/dev/dev-server/plugins/devtools.plugin.js +0 -51
- package/dist/modules/dev/dev-server/plugins/devtools.plugin.js.map +0 -1
- package/dist/modules/dev/dev-server/plugins/favicon.plugin.d.ts +0 -1
- package/dist/modules/dev/dev-server/plugins/favicon.plugin.js +0 -19
- package/dist/modules/dev/dev-server/plugins/favicon.plugin.js.map +0 -1
- package/dist/modules/dev/dev-server/plugins/multipart.plugin.d.ts +0 -1
- package/dist/modules/dev/dev-server/plugins/multipart.plugin.js +0 -63
- package/dist/modules/dev/dev-server/plugins/multipart.plugin.js.map +0 -1
- package/dist/modules/dev/dev-server/plugins/systrace.plugin.d.ts +0 -1
- package/dist/modules/dev/dev-server/plugins/systrace.plugin.js +0 -29
- package/dist/modules/dev/dev-server/plugins/systrace.plugin.js.map +0 -1
- package/dist/modules/dev/dev-server/plugins/types.d.ts +0 -11
- package/dist/modules/dev/dev-server/plugins/types.js +0 -3
- package/dist/modules/dev/dev-server/plugins/types.js.map +0 -1
- package/dist/modules/dev/dev-server/plugins/wss/index.d.ts +0 -3
- package/dist/modules/dev/dev-server/plugins/wss/index.js +0 -20
- package/dist/modules/dev/dev-server/plugins/wss/index.js.map +0 -1
- package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-api.server.d.ts +0 -37
- package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-api.server.js +0 -67
- package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-api.server.js.map +0 -1
- package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-debugger.server.d.ts +0 -63
- package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-debugger.server.js +0 -129
- package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-debugger.server.js.map +0 -1
- package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-dev-client.server.d.ts +0 -32
- package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-dev-client.server.js +0 -76
- package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-dev-client.server.js.map +0 -1
- package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-events.server.d.ts +0 -75
- package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-events.server.js +0 -199
- package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-events.server.js.map +0 -1
- package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-hmr.server.d.ts +0 -44
- package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-hmr.server.js +0 -121
- package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-hmr.server.js.map +0 -1
- package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-message.server.d.ts +0 -135
- package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-message.server.js +0 -364
- package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-message.server.js.map +0 -1
- package/dist/modules/dev/dev-server/plugins/wss/types.d.ts +0 -6
- package/dist/modules/dev/dev-server/plugins/wss/types.js +0 -3
- package/dist/modules/dev/dev-server/plugins/wss/types.js.map +0 -1
- package/dist/modules/dev/dev-server/plugins/wss/web-socket-router.d.ts +0 -32
- package/dist/modules/dev/dev-server/plugins/wss/web-socket-router.js +0 -58
- package/dist/modules/dev/dev-server/plugins/wss/web-socket-router.js.map +0 -1
- package/dist/modules/dev/dev-server/plugins/wss/web-socket-server-adapter.d.ts +0 -13
- package/dist/modules/dev/dev-server/plugins/wss/web-socket-server-adapter.js +0 -27
- package/dist/modules/dev/dev-server/plugins/wss/web-socket-server-adapter.js.map +0 -1
- package/dist/modules/dev/dev-server/plugins/wss/web-socket-server.d.ts +0 -39
- package/dist/modules/dev/dev-server/plugins/wss/web-socket-server.js +0 -47
- package/dist/modules/dev/dev-server/plugins/wss/web-socket-server.js.map +0 -1
- package/dist/modules/dev/dev-server/plugins/wss/wss.plugin.d.ts +0 -24
- package/dist/modules/dev/dev-server/plugins/wss/wss.plugin.js +0 -56
- package/dist/modules/dev/dev-server/plugins/wss/wss.plugin.js.map +0 -1
- package/dist/modules/dev/dev-server/sybmolicate/sybmolicate.plugin.d.ts +0 -7
- package/dist/modules/dev/dev-server/sybmolicate/sybmolicate.plugin.js +0 -41
- package/dist/modules/dev/dev-server/sybmolicate/sybmolicate.plugin.js.map +0 -1
- package/dist/modules/dev/dev-server/sybmolicate/types.d.ts +0 -64
- package/dist/modules/dev/dev-server/sybmolicate/types.js +0 -3
- package/dist/modules/dev/dev-server/sybmolicate/types.js.map +0 -1
- package/dist/modules/dev/terminal/base.terminal.reporter.d.ts +0 -25
- package/dist/modules/dev/terminal/base.terminal.reporter.js +0 -79
- package/dist/modules/dev/terminal/base.terminal.reporter.js.map +0 -1
- package/dist/modules/dev/terminal/terminal.reporter.d.ts +0 -13
- package/dist/modules/dev/terminal/terminal.reporter.js +0 -83
- package/dist/modules/dev/terminal/terminal.reporter.js.map +0 -1
- package/dist/modules/dev/types.d.ts +0 -20
- package/dist/modules/dev/types.js +0 -3
- package/dist/modules/dev/types.js.map +0 -1
- package/dist/modules/dev/utils/log.d.ts +0 -23
- package/dist/modules/dev/utils/log.js +0 -74
- package/dist/modules/dev/utils/log.js.map +0 -1
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { AndroidIntentFilter, ProcessedAppConfig } from "../../config/types";
|
|
3
|
+
import { BasePlugin } from "../base";
|
|
4
|
+
import type { PluginContext } from "../context";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Deep linking plugin configuration schema
|
|
8
|
+
*/
|
|
9
|
+
export const DeepLinkingPluginConfigSchema = z.object({
|
|
10
|
+
/** Custom URL scheme */
|
|
11
|
+
scheme: z.string().min(1, "URL scheme is required"),
|
|
12
|
+
|
|
13
|
+
/** Universal Links configuration (iOS) / App Links (Android) */
|
|
14
|
+
universalLinks: z
|
|
15
|
+
.object({
|
|
16
|
+
/** Associated domains */
|
|
17
|
+
domains: z.array(z.string()).min(1),
|
|
18
|
+
/** URL path patterns */
|
|
19
|
+
paths: z.array(z.string()).optional().default(["/*"]),
|
|
20
|
+
})
|
|
21
|
+
.optional(),
|
|
22
|
+
|
|
23
|
+
/** Android App Links configuration */
|
|
24
|
+
androidAppLinks: z
|
|
25
|
+
.object({
|
|
26
|
+
/** App Links host domains */
|
|
27
|
+
hosts: z.array(z.string()).min(1),
|
|
28
|
+
/** URL path patterns */
|
|
29
|
+
paths: z.array(z.string()).optional().default(["/*"]),
|
|
30
|
+
})
|
|
31
|
+
.optional(),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
export type DeepLinkingPluginConfig = z.infer<typeof DeepLinkingPluginConfigSchema>;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Deep linking capability plugin
|
|
38
|
+
*
|
|
39
|
+
* Configures deep linking support including custom URL schemes,
|
|
40
|
+
* Universal Links (iOS), and App Links (Android).
|
|
41
|
+
*/
|
|
42
|
+
export class DeepLinkingPlugin extends BasePlugin<DeepLinkingPluginConfig> {
|
|
43
|
+
readonly name = "deep-linking";
|
|
44
|
+
readonly version = "1.0.0";
|
|
45
|
+
readonly description = "Configure deep linking with custom schemes and Universal/App Links";
|
|
46
|
+
readonly configSchema = DeepLinkingPluginConfigSchema;
|
|
47
|
+
|
|
48
|
+
override provides = ["deep-linking", "universal-links", "app-links"];
|
|
49
|
+
override platforms: ("ios" | "android")[] = ["ios", "android"];
|
|
50
|
+
|
|
51
|
+
transform(
|
|
52
|
+
config: ProcessedAppConfig,
|
|
53
|
+
pluginConfig: DeepLinkingPluginConfig,
|
|
54
|
+
context: PluginContext
|
|
55
|
+
): ProcessedAppConfig {
|
|
56
|
+
const { log } = context;
|
|
57
|
+
log.debug("Applying deep linking configuration...");
|
|
58
|
+
|
|
59
|
+
let result = config;
|
|
60
|
+
|
|
61
|
+
// Add custom URL scheme
|
|
62
|
+
result = this.addUrlScheme(result, pluginConfig.scheme);
|
|
63
|
+
|
|
64
|
+
// iOS: Configure Universal Links
|
|
65
|
+
if (pluginConfig.universalLinks) {
|
|
66
|
+
for (const domain of pluginConfig.universalLinks.domains) {
|
|
67
|
+
// Add associated domain entitlement
|
|
68
|
+
result = this.addAssociatedDomain(result, domain, "applinks");
|
|
69
|
+
// Also add webcredentials for password autofill
|
|
70
|
+
result = this.addAssociatedDomain(result, domain, "webcredentials");
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Android: Add intent filter for custom scheme
|
|
75
|
+
const schemeFilter: AndroidIntentFilter = {
|
|
76
|
+
actions: ["android.intent.action.VIEW"],
|
|
77
|
+
categories: ["android.intent.category.DEFAULT", "android.intent.category.BROWSABLE"],
|
|
78
|
+
data: [{ scheme: pluginConfig.scheme }],
|
|
79
|
+
};
|
|
80
|
+
result = this.addIntentFilter(result, schemeFilter);
|
|
81
|
+
|
|
82
|
+
// Android: Configure App Links
|
|
83
|
+
if (pluginConfig.androidAppLinks || pluginConfig.universalLinks) {
|
|
84
|
+
const hosts = pluginConfig.androidAppLinks?.hosts ?? pluginConfig.universalLinks?.domains ?? [];
|
|
85
|
+
const paths = pluginConfig.androidAppLinks?.paths ?? pluginConfig.universalLinks?.paths ?? ["/*"];
|
|
86
|
+
|
|
87
|
+
for (const host of hosts) {
|
|
88
|
+
const appLinkFilter: AndroidIntentFilter = {
|
|
89
|
+
actions: ["android.intent.action.VIEW"],
|
|
90
|
+
categories: ["android.intent.category.DEFAULT", "android.intent.category.BROWSABLE"],
|
|
91
|
+
data: paths.map((pathPrefix) => ({
|
|
92
|
+
scheme: "https",
|
|
93
|
+
host,
|
|
94
|
+
pathPrefix: pathPrefix.replace("*", ""),
|
|
95
|
+
})),
|
|
96
|
+
autoVerify: true,
|
|
97
|
+
};
|
|
98
|
+
result = this.addIntentFilter(result, appLinkFilter);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return result;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Helper to add associated domain entitlement
|
|
107
|
+
*/
|
|
108
|
+
private addAssociatedDomain(
|
|
109
|
+
config: ProcessedAppConfig,
|
|
110
|
+
domain: string,
|
|
111
|
+
type: "applinks" | "webcredentials" | "activitycontinuation"
|
|
112
|
+
): ProcessedAppConfig {
|
|
113
|
+
const key = "com.apple.developer.associated-domains";
|
|
114
|
+
const domainEntry = `${type}:${domain}`;
|
|
115
|
+
|
|
116
|
+
const existingDomains = (config.resolvedEntitlements[key] as string[]) || [];
|
|
117
|
+
|
|
118
|
+
if (!existingDomains.includes(domainEntry)) {
|
|
119
|
+
return this.addEntitlement(config, key, [...existingDomains, domainEntry]);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return config;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { ProcessedAppConfig } from "../../config/types";
|
|
3
|
+
import { BasePlugin } from "../base";
|
|
4
|
+
import type { PluginContext } from "../context";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Firebase plugin configuration schema
|
|
8
|
+
*/
|
|
9
|
+
export const FirebasePluginConfigSchema = z.object({
|
|
10
|
+
/** Enable Firebase Analytics */
|
|
11
|
+
analytics: z.boolean().optional().default(true),
|
|
12
|
+
|
|
13
|
+
/** Enable Firebase Crashlytics */
|
|
14
|
+
crashlytics: z.boolean().optional().default(true),
|
|
15
|
+
|
|
16
|
+
/** Enable Firebase Cloud Messaging */
|
|
17
|
+
messaging: z.boolean().optional().default(false),
|
|
18
|
+
|
|
19
|
+
/** Enable Firebase Remote Config */
|
|
20
|
+
remoteConfig: z.boolean().optional().default(false),
|
|
21
|
+
|
|
22
|
+
/** Enable Firebase Performance Monitoring */
|
|
23
|
+
performance: z.boolean().optional().default(false),
|
|
24
|
+
|
|
25
|
+
/** Path to GoogleService-Info.plist (iOS) */
|
|
26
|
+
iosGoogleServicesFile: z.string().optional(),
|
|
27
|
+
|
|
28
|
+
/** Path to google-services.json (Android) */
|
|
29
|
+
androidGoogleServicesFile: z.string().optional(),
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
export type FirebasePluginConfig = z.infer<typeof FirebasePluginConfigSchema>;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Firebase capability plugin
|
|
36
|
+
*
|
|
37
|
+
* Configures Firebase SDK integration including Analytics,
|
|
38
|
+
* Crashlytics, Cloud Messaging, Remote Config, and Performance.
|
|
39
|
+
*/
|
|
40
|
+
export class FirebasePlugin extends BasePlugin<FirebasePluginConfig> {
|
|
41
|
+
readonly name = "firebase";
|
|
42
|
+
readonly version = "1.0.0";
|
|
43
|
+
readonly description = "Configure Firebase SDK integration (Analytics, Crashlytics, FCM, etc.)";
|
|
44
|
+
readonly configSchema = FirebasePluginConfigSchema;
|
|
45
|
+
|
|
46
|
+
override provides = ["firebase", "analytics", "crashlytics"];
|
|
47
|
+
override platforms: ("ios" | "android")[] = ["ios", "android"];
|
|
48
|
+
|
|
49
|
+
transform(
|
|
50
|
+
config: ProcessedAppConfig,
|
|
51
|
+
pluginConfig: FirebasePluginConfig,
|
|
52
|
+
context: PluginContext
|
|
53
|
+
): ProcessedAppConfig {
|
|
54
|
+
const { log } = context;
|
|
55
|
+
log.debug("Applying Firebase configuration...");
|
|
56
|
+
|
|
57
|
+
let result = config;
|
|
58
|
+
|
|
59
|
+
// iOS: Add Firebase CocoaPods
|
|
60
|
+
result = this.addPodDependency(result, { name: "Firebase/Core" });
|
|
61
|
+
|
|
62
|
+
if (pluginConfig.analytics) {
|
|
63
|
+
result = this.addPodDependency(result, { name: "Firebase/Analytics" });
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (pluginConfig.crashlytics) {
|
|
67
|
+
result = this.addPodDependency(result, { name: "Firebase/Crashlytics" });
|
|
68
|
+
|
|
69
|
+
// Enable Crashlytics collection
|
|
70
|
+
result = {
|
|
71
|
+
...result,
|
|
72
|
+
resolvedInfoPlist: {
|
|
73
|
+
...result.resolvedInfoPlist,
|
|
74
|
+
FirebaseCrashlyticsCollectionEnabled: true,
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (pluginConfig.messaging) {
|
|
80
|
+
result = this.addPodDependency(result, { name: "Firebase/Messaging" });
|
|
81
|
+
|
|
82
|
+
// Add push notification background mode
|
|
83
|
+
result = this.addBackgroundMode(result, "remote-notification");
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (pluginConfig.remoteConfig) {
|
|
87
|
+
result = this.addPodDependency(result, { name: "Firebase/RemoteConfig" });
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (pluginConfig.performance) {
|
|
91
|
+
result = this.addPodDependency(result, { name: "Firebase/Performance" });
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Android: Add Firebase dependencies
|
|
95
|
+
result = this.addGradleDependency(result, "com.google.firebase:firebase-bom:33.0.0");
|
|
96
|
+
|
|
97
|
+
if (pluginConfig.analytics) {
|
|
98
|
+
result = this.addGradleDependency(result, "com.google.firebase:firebase-analytics");
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (pluginConfig.crashlytics) {
|
|
102
|
+
result = this.addGradleDependency(result, "com.google.firebase:firebase-crashlytics");
|
|
103
|
+
|
|
104
|
+
// Add Crashlytics metadata
|
|
105
|
+
result = this.addAndroidMetadata(result, "firebase_crashlytics_collection_enabled", "true");
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (pluginConfig.messaging) {
|
|
109
|
+
result = this.addGradleDependency(result, "com.google.firebase:firebase-messaging");
|
|
110
|
+
|
|
111
|
+
// Add required permissions
|
|
112
|
+
result = this.addAndroidPermission(result, "android.permission.POST_NOTIFICATIONS");
|
|
113
|
+
result = this.addAndroidPermission(result, "android.permission.WAKE_LOCK");
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (pluginConfig.remoteConfig) {
|
|
117
|
+
result = this.addGradleDependency(result, "com.google.firebase:firebase-config");
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (pluginConfig.performance) {
|
|
121
|
+
result = this.addGradleDependency(result, "com.google.firebase:firebase-perf");
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Android: Add internet permission
|
|
125
|
+
result = this.addAndroidPermission(result, "android.permission.INTERNET");
|
|
126
|
+
result = this.addAndroidPermission(result, "android.permission.ACCESS_NETWORK_STATE");
|
|
127
|
+
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
override async postProcess(context: PluginContext): Promise<void> {
|
|
132
|
+
const { log, isDryRun } = context;
|
|
133
|
+
|
|
134
|
+
if (!isDryRun) {
|
|
135
|
+
log.debug("Firebase post-processing: Ensure GoogleService-Info.plist and google-services.json are present");
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capability plugins for Teardown Launchpad
|
|
3
|
+
*
|
|
4
|
+
* These plugins configure native capabilities for iOS and Android,
|
|
5
|
+
* including permissions, entitlements, frameworks, and dependencies.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { BiometricsPlugin, BiometricsPluginConfigSchema } from "./biometrics";
|
|
9
|
+
import { BluetoothPlugin, BluetoothPluginConfigSchema } from "./bluetooth";
|
|
10
|
+
import { CalendarPlugin, CalendarPluginConfigSchema } from "./calendar";
|
|
11
|
+
// Import all plugins for re-export and use in objects
|
|
12
|
+
import { CameraPlugin, CameraPluginConfigSchema } from "./camera";
|
|
13
|
+
import { ContactsPlugin, ContactsPluginConfigSchema } from "./contacts";
|
|
14
|
+
import { DeepLinkingPlugin, DeepLinkingPluginConfigSchema } from "./deep-linking";
|
|
15
|
+
import { FirebasePlugin, FirebasePluginConfigSchema } from "./firebase";
|
|
16
|
+
import { LocationPlugin, LocationPluginConfigSchema } from "./location";
|
|
17
|
+
import { PhotoLibraryPlugin, PhotoLibraryPluginConfigSchema } from "./photo-library";
|
|
18
|
+
import { PushNotificationsPlugin, PushNotificationsPluginConfigSchema } from "./push-notifications";
|
|
19
|
+
import { SignInWithApplePlugin, SignInWithApplePluginConfigSchema } from "./sign-in-with-apple";
|
|
20
|
+
|
|
21
|
+
// Re-export plugins
|
|
22
|
+
export {
|
|
23
|
+
CameraPlugin,
|
|
24
|
+
CameraPluginConfigSchema,
|
|
25
|
+
LocationPlugin,
|
|
26
|
+
LocationPluginConfigSchema,
|
|
27
|
+
PushNotificationsPlugin,
|
|
28
|
+
PushNotificationsPluginConfigSchema,
|
|
29
|
+
BiometricsPlugin,
|
|
30
|
+
BiometricsPluginConfigSchema,
|
|
31
|
+
DeepLinkingPlugin,
|
|
32
|
+
DeepLinkingPluginConfigSchema,
|
|
33
|
+
FirebasePlugin,
|
|
34
|
+
FirebasePluginConfigSchema,
|
|
35
|
+
ContactsPlugin,
|
|
36
|
+
ContactsPluginConfigSchema,
|
|
37
|
+
CalendarPlugin,
|
|
38
|
+
CalendarPluginConfigSchema,
|
|
39
|
+
PhotoLibraryPlugin,
|
|
40
|
+
PhotoLibraryPluginConfigSchema,
|
|
41
|
+
BluetoothPlugin,
|
|
42
|
+
BluetoothPluginConfigSchema,
|
|
43
|
+
SignInWithApplePlugin,
|
|
44
|
+
SignInWithApplePluginConfigSchema,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export type { BiometricsPluginConfig } from "./biometrics";
|
|
48
|
+
export type { BluetoothPluginConfig } from "./bluetooth";
|
|
49
|
+
export type { CalendarPluginConfig } from "./calendar";
|
|
50
|
+
// Re-export types
|
|
51
|
+
export type { CameraPluginConfig } from "./camera";
|
|
52
|
+
export type { ContactsPluginConfig } from "./contacts";
|
|
53
|
+
export type { DeepLinkingPluginConfig } from "./deep-linking";
|
|
54
|
+
export type { FirebasePluginConfig } from "./firebase";
|
|
55
|
+
export type { LocationPluginConfig } from "./location";
|
|
56
|
+
export type { PhotoLibraryPluginConfig } from "./photo-library";
|
|
57
|
+
export type { PushNotificationsPluginConfig } from "./push-notifications";
|
|
58
|
+
export type { SignInWithApplePluginConfig } from "./sign-in-with-apple";
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* All available capability plugins
|
|
62
|
+
*/
|
|
63
|
+
export const CapabilityPlugins = {
|
|
64
|
+
CameraPlugin,
|
|
65
|
+
LocationPlugin,
|
|
66
|
+
PushNotificationsPlugin,
|
|
67
|
+
BiometricsPlugin,
|
|
68
|
+
DeepLinkingPlugin,
|
|
69
|
+
FirebasePlugin,
|
|
70
|
+
ContactsPlugin,
|
|
71
|
+
CalendarPlugin,
|
|
72
|
+
PhotoLibraryPlugin,
|
|
73
|
+
BluetoothPlugin,
|
|
74
|
+
SignInWithApplePlugin,
|
|
75
|
+
} as const;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Get a plugin by name
|
|
79
|
+
*/
|
|
80
|
+
export function getPluginByName(name: string) {
|
|
81
|
+
const plugins: Record<string, unknown> = {
|
|
82
|
+
camera: CameraPlugin,
|
|
83
|
+
location: LocationPlugin,
|
|
84
|
+
"push-notifications": PushNotificationsPlugin,
|
|
85
|
+
biometrics: BiometricsPlugin,
|
|
86
|
+
"deep-linking": DeepLinkingPlugin,
|
|
87
|
+
firebase: FirebasePlugin,
|
|
88
|
+
contacts: ContactsPlugin,
|
|
89
|
+
calendar: CalendarPlugin,
|
|
90
|
+
"photo-library": PhotoLibraryPlugin,
|
|
91
|
+
bluetooth: BluetoothPlugin,
|
|
92
|
+
"sign-in-with-apple": SignInWithApplePlugin,
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
return plugins[name];
|
|
96
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { ProcessedAppConfig } from "../../config/types";
|
|
3
|
+
import { BasePlugin } from "../base";
|
|
4
|
+
import type { PluginContext } from "../context";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Location plugin configuration schema
|
|
8
|
+
*/
|
|
9
|
+
export const LocationPluginConfigSchema = z.object({
|
|
10
|
+
/** iOS when-in-use location usage description */
|
|
11
|
+
whenInUsePermission: z.string().min(1, "When-in-use permission description is required"),
|
|
12
|
+
|
|
13
|
+
/** iOS always-on location usage description */
|
|
14
|
+
alwaysPermission: z.string().optional(),
|
|
15
|
+
|
|
16
|
+
/** Show background location indicator */
|
|
17
|
+
backgroundIndicator: z.boolean().optional().default(true),
|
|
18
|
+
|
|
19
|
+
/** Enable high accuracy GPS */
|
|
20
|
+
highAccuracy: z.boolean().optional().default(true),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export type LocationPluginConfig = z.infer<typeof LocationPluginConfigSchema>;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Location capability plugin
|
|
27
|
+
*
|
|
28
|
+
* Configures location access for iOS and Android including
|
|
29
|
+
* foreground, background, and always-on location permissions.
|
|
30
|
+
*/
|
|
31
|
+
export class LocationPlugin extends BasePlugin<LocationPluginConfig> {
|
|
32
|
+
readonly name = "location";
|
|
33
|
+
readonly version = "1.0.0";
|
|
34
|
+
readonly description = "Configure location services for geolocation features";
|
|
35
|
+
readonly configSchema = LocationPluginConfigSchema;
|
|
36
|
+
|
|
37
|
+
override provides = ["location"];
|
|
38
|
+
override platforms: ("ios" | "android")[] = ["ios", "android"];
|
|
39
|
+
|
|
40
|
+
transform(
|
|
41
|
+
config: ProcessedAppConfig,
|
|
42
|
+
pluginConfig: LocationPluginConfig,
|
|
43
|
+
context: PluginContext
|
|
44
|
+
): ProcessedAppConfig {
|
|
45
|
+
const { log } = context;
|
|
46
|
+
log.debug("Applying location configuration...");
|
|
47
|
+
|
|
48
|
+
let result = config;
|
|
49
|
+
|
|
50
|
+
// iOS: Add usage descriptions
|
|
51
|
+
result = this.addUsageDescription(result, "NSLocationWhenInUseUsageDescription", pluginConfig.whenInUsePermission);
|
|
52
|
+
|
|
53
|
+
if (pluginConfig.alwaysPermission) {
|
|
54
|
+
result = this.addUsageDescription(
|
|
55
|
+
result,
|
|
56
|
+
"NSLocationAlwaysAndWhenInUseUsageDescription",
|
|
57
|
+
pluginConfig.alwaysPermission
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
// Also add legacy key for older iOS versions
|
|
61
|
+
result = this.addUsageDescription(result, "NSLocationAlwaysUsageDescription", pluginConfig.alwaysPermission);
|
|
62
|
+
|
|
63
|
+
// Add background mode
|
|
64
|
+
result = this.addBackgroundMode(result, "location");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// iOS: Add framework
|
|
68
|
+
result = this.addFramework(result, "CoreLocation");
|
|
69
|
+
|
|
70
|
+
// Android: Add permissions
|
|
71
|
+
result = this.addAndroidPermission(result, "android.permission.ACCESS_FINE_LOCATION");
|
|
72
|
+
result = this.addAndroidPermission(result, "android.permission.ACCESS_COARSE_LOCATION");
|
|
73
|
+
|
|
74
|
+
if (pluginConfig.alwaysPermission) {
|
|
75
|
+
result = this.addAndroidPermission(result, "android.permission.ACCESS_BACKGROUND_LOCATION");
|
|
76
|
+
result = this.addAndroidPermission(result, "android.permission.FOREGROUND_SERVICE");
|
|
77
|
+
result = this.addAndroidPermission(result, "android.permission.FOREGROUND_SERVICE_LOCATION");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Android: Add GPS feature
|
|
81
|
+
if (pluginConfig.highAccuracy) {
|
|
82
|
+
result = this.addAndroidFeature(result, "android.hardware.location.gps");
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return result;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { ProcessedAppConfig } from "../../config/types";
|
|
3
|
+
import { BasePlugin } from "../base";
|
|
4
|
+
import type { PluginContext } from "../context";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Photo library plugin configuration schema
|
|
8
|
+
*/
|
|
9
|
+
export const PhotoLibraryPluginConfigSchema = z.object({
|
|
10
|
+
/** iOS photo library read permission description */
|
|
11
|
+
readPermission: z.string().min(1, "Photo library read permission description is required"),
|
|
12
|
+
|
|
13
|
+
/** iOS photo library write permission description */
|
|
14
|
+
writePermission: z.string().optional(),
|
|
15
|
+
|
|
16
|
+
/** Behavior for iOS 14+ limited photo access */
|
|
17
|
+
limitedAccessBehavior: z.enum(["prompt", "silent"]).optional().default("prompt"),
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export type PhotoLibraryPluginConfig = z.infer<typeof PhotoLibraryPluginConfigSchema>;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Photo library capability plugin
|
|
24
|
+
*/
|
|
25
|
+
export class PhotoLibraryPlugin extends BasePlugin<PhotoLibraryPluginConfig> {
|
|
26
|
+
readonly name = "photo-library";
|
|
27
|
+
readonly version = "1.0.0";
|
|
28
|
+
readonly description = "Configure photo library access for reading and writing photos/videos";
|
|
29
|
+
readonly configSchema = PhotoLibraryPluginConfigSchema;
|
|
30
|
+
|
|
31
|
+
override provides = ["photo-library", "photos"];
|
|
32
|
+
override platforms: ("ios" | "android")[] = ["ios", "android"];
|
|
33
|
+
|
|
34
|
+
transform(
|
|
35
|
+
config: ProcessedAppConfig,
|
|
36
|
+
pluginConfig: PhotoLibraryPluginConfig,
|
|
37
|
+
context: PluginContext
|
|
38
|
+
): ProcessedAppConfig {
|
|
39
|
+
const { log } = context;
|
|
40
|
+
log.debug("Applying photo library configuration...");
|
|
41
|
+
|
|
42
|
+
let result = config;
|
|
43
|
+
|
|
44
|
+
// iOS: Add read usage description
|
|
45
|
+
result = this.addUsageDescription(result, "NSPhotoLibraryUsageDescription", pluginConfig.readPermission);
|
|
46
|
+
|
|
47
|
+
// iOS: Add write usage description
|
|
48
|
+
if (pluginConfig.writePermission) {
|
|
49
|
+
result = this.addUsageDescription(result, "NSPhotoLibraryAddUsageDescription", pluginConfig.writePermission);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// iOS: Configure limited photo access behavior
|
|
53
|
+
if (pluginConfig.limitedAccessBehavior === "silent") {
|
|
54
|
+
result = {
|
|
55
|
+
...result,
|
|
56
|
+
resolvedInfoPlist: {
|
|
57
|
+
...result.resolvedInfoPlist,
|
|
58
|
+
PHPhotoLibraryPreventAutomaticLimitedAccessAlert: true,
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// iOS: Add Photos framework
|
|
64
|
+
result = this.addFramework(result, "Photos");
|
|
65
|
+
result = this.addFramework(result, "PhotosUI");
|
|
66
|
+
|
|
67
|
+
// Android: Add media permissions (Android 13+)
|
|
68
|
+
result = this.addAndroidPermission(result, "android.permission.READ_MEDIA_IMAGES");
|
|
69
|
+
result = this.addAndroidPermission(result, "android.permission.READ_MEDIA_VIDEO");
|
|
70
|
+
|
|
71
|
+
// Android: Legacy storage permission for older versions
|
|
72
|
+
result = this.addAndroidPermission(result, "android.permission.READ_EXTERNAL_STORAGE");
|
|
73
|
+
|
|
74
|
+
if (pluginConfig.writePermission) {
|
|
75
|
+
result = this.addAndroidPermission(result, "android.permission.WRITE_EXTERNAL_STORAGE");
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { ProcessedAppConfig } from "../../config/types";
|
|
3
|
+
import { BasePlugin } from "../base";
|
|
4
|
+
import type { PluginContext } from "../context";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Push notifications plugin configuration schema
|
|
8
|
+
*/
|
|
9
|
+
export const PushNotificationsPluginConfigSchema = z.object({
|
|
10
|
+
/** Push notification environment */
|
|
11
|
+
environment: z.enum(["development", "production"]).default("development"),
|
|
12
|
+
|
|
13
|
+
/** Default notification channel ID (Android) */
|
|
14
|
+
defaultChannelId: z.string().optional().default("default"),
|
|
15
|
+
|
|
16
|
+
/** Default notification icon resource (Android) */
|
|
17
|
+
defaultIcon: z.string().optional(),
|
|
18
|
+
|
|
19
|
+
/** Enable remote notification background mode (iOS) */
|
|
20
|
+
backgroundModes: z.boolean().optional().default(true),
|
|
21
|
+
|
|
22
|
+
/** Enable silent push notifications */
|
|
23
|
+
silentNotifications: z.boolean().optional().default(true),
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export type PushNotificationsPluginConfig = z.infer<typeof PushNotificationsPluginConfigSchema>;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Push notifications capability plugin
|
|
30
|
+
*
|
|
31
|
+
* Configures push notification support for iOS (APNs) and Android (FCM)
|
|
32
|
+
* including entitlements, background modes, and notification settings.
|
|
33
|
+
*/
|
|
34
|
+
export class PushNotificationsPlugin extends BasePlugin<PushNotificationsPluginConfig> {
|
|
35
|
+
readonly name = "push-notifications";
|
|
36
|
+
readonly version = "1.0.0";
|
|
37
|
+
readonly description = "Configure push notifications for iOS (APNs) and Android (FCM)";
|
|
38
|
+
readonly configSchema = PushNotificationsPluginConfigSchema;
|
|
39
|
+
|
|
40
|
+
override provides = ["push-notifications", "notifications"];
|
|
41
|
+
override platforms: ("ios" | "android")[] = ["ios", "android"];
|
|
42
|
+
|
|
43
|
+
transform(
|
|
44
|
+
config: ProcessedAppConfig,
|
|
45
|
+
pluginConfig: PushNotificationsPluginConfig,
|
|
46
|
+
context: PluginContext
|
|
47
|
+
): ProcessedAppConfig {
|
|
48
|
+
const { log } = context;
|
|
49
|
+
log.debug("Applying push notifications configuration...");
|
|
50
|
+
|
|
51
|
+
let result = config;
|
|
52
|
+
|
|
53
|
+
// iOS: Add APS entitlement
|
|
54
|
+
result = this.addEntitlement(result, "aps-environment", pluginConfig.environment);
|
|
55
|
+
|
|
56
|
+
// iOS: Add background modes
|
|
57
|
+
if (pluginConfig.backgroundModes) {
|
|
58
|
+
result = this.addBackgroundMode(result, "remote-notification");
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (pluginConfig.silentNotifications) {
|
|
62
|
+
result = this.addBackgroundMode(result, "fetch");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// iOS: Add UserNotifications framework
|
|
66
|
+
result = this.addFramework(result, "UserNotifications");
|
|
67
|
+
|
|
68
|
+
// Android: Add POST_NOTIFICATIONS permission (Android 13+)
|
|
69
|
+
result = this.addAndroidPermission(result, "android.permission.POST_NOTIFICATIONS");
|
|
70
|
+
|
|
71
|
+
// Android: Add RECEIVE_BOOT_COMPLETED for scheduling
|
|
72
|
+
result = this.addAndroidPermission(result, "android.permission.RECEIVE_BOOT_COMPLETED");
|
|
73
|
+
|
|
74
|
+
// Android: Add VIBRATE permission
|
|
75
|
+
result = this.addAndroidPermission(result, "android.permission.VIBRATE");
|
|
76
|
+
|
|
77
|
+
// Android: Add wake lock for background processing
|
|
78
|
+
result = this.addAndroidPermission(result, "android.permission.WAKE_LOCK");
|
|
79
|
+
|
|
80
|
+
// Android: Add default notification icon metadata
|
|
81
|
+
if (pluginConfig.defaultIcon) {
|
|
82
|
+
result = this.addAndroidMetadata(
|
|
83
|
+
result,
|
|
84
|
+
"com.google.firebase.messaging.default_notification_icon",
|
|
85
|
+
pluginConfig.defaultIcon
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Android: Add default notification channel
|
|
90
|
+
result = this.addAndroidMetadata(
|
|
91
|
+
result,
|
|
92
|
+
"com.google.firebase.messaging.default_notification_channel_id",
|
|
93
|
+
pluginConfig.defaultChannelId ?? "default"
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { ProcessedAppConfig } from "../../config/types";
|
|
3
|
+
import { BasePlugin } from "../base";
|
|
4
|
+
import type { PluginContext } from "../context";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Sign in with Apple plugin configuration schema
|
|
8
|
+
*/
|
|
9
|
+
export const SignInWithApplePluginConfigSchema = z.object({
|
|
10
|
+
/** Enable Sign in with Apple */
|
|
11
|
+
enabled: z.boolean().optional().default(true),
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export type SignInWithApplePluginConfig = z.infer<typeof SignInWithApplePluginConfigSchema>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Sign in with Apple capability plugin
|
|
18
|
+
*/
|
|
19
|
+
export class SignInWithApplePlugin extends BasePlugin<SignInWithApplePluginConfig> {
|
|
20
|
+
readonly name = "sign-in-with-apple";
|
|
21
|
+
readonly version = "1.0.0";
|
|
22
|
+
readonly description = "Configure Sign in with Apple authentication";
|
|
23
|
+
readonly configSchema = SignInWithApplePluginConfigSchema;
|
|
24
|
+
|
|
25
|
+
override provides = ["sign-in-with-apple", "apple-auth"];
|
|
26
|
+
override platforms: ("ios" | "android")[] = ["ios", "android"];
|
|
27
|
+
|
|
28
|
+
transform(
|
|
29
|
+
config: ProcessedAppConfig,
|
|
30
|
+
pluginConfig: SignInWithApplePluginConfig,
|
|
31
|
+
context: PluginContext
|
|
32
|
+
): ProcessedAppConfig {
|
|
33
|
+
const { log } = context;
|
|
34
|
+
|
|
35
|
+
if (!pluginConfig.enabled) {
|
|
36
|
+
return config;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
log.debug("Applying Sign in with Apple configuration...");
|
|
40
|
+
|
|
41
|
+
let result = config;
|
|
42
|
+
|
|
43
|
+
// iOS: Add entitlement
|
|
44
|
+
result = this.addEntitlement(result, "com.apple.developer.applesignin", ["Default"]);
|
|
45
|
+
|
|
46
|
+
// iOS: Add AuthenticationServices framework
|
|
47
|
+
result = this.addFramework(result, "AuthenticationServices");
|
|
48
|
+
|
|
49
|
+
// Android: No native configuration required (uses web-based OAuth)
|
|
50
|
+
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
}
|