@teardown/cli 1.2.38 → 2.0.41
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.js +0 -55
- package/dist/commands/init/init-teardown.js +0 -26
- package/dist/index.js +0 -20
- package/dist/modules/dev/dev-menu/keyboard-handler.js +0 -138
- package/dist/modules/dev/dev-menu/open-debugger-keyboard-handler.js +0 -105
- package/dist/modules/dev/dev-server/cdp/cdp.adapter.js +0 -12
- package/dist/modules/dev/dev-server/cdp/index.js +0 -18
- package/dist/modules/dev/dev-server/cdp/types.js +0 -2
- package/dist/modules/dev/dev-server/dev-server-checker.js +0 -72
- package/dist/modules/dev/dev-server/dev-server.js +0 -269
- package/dist/modules/dev/dev-server/inspector/device.event-reporter.js +0 -165
- package/dist/modules/dev/dev-server/inspector/device.js +0 -577
- package/dist/modules/dev/dev-server/inspector/inspector.js +0 -204
- package/dist/modules/dev/dev-server/inspector/types.js +0 -2
- package/dist/modules/dev/dev-server/inspector/wss/servers/debugger-connection.server.js +0 -61
- package/dist/modules/dev/dev-server/inspector/wss/servers/device-connection.server.js +0 -64
- package/dist/modules/dev/dev-server/plugins/devtools.plugin.js +0 -50
- package/dist/modules/dev/dev-server/plugins/favicon.plugin.js +0 -19
- package/dist/modules/dev/dev-server/plugins/multipart.plugin.js +0 -62
- package/dist/modules/dev/dev-server/plugins/systrace.plugin.js +0 -28
- package/dist/modules/dev/dev-server/plugins/types.js +0 -2
- package/dist/modules/dev/dev-server/plugins/wss/index.js +0 -19
- package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-api.server.js +0 -66
- package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-debugger.server.js +0 -128
- package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-dev-client.server.js +0 -75
- package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-events.server.js +0 -198
- package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-hmr.server.js +0 -120
- package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-message.server.js +0 -357
- package/dist/modules/dev/dev-server/plugins/wss/types.js +0 -2
- package/dist/modules/dev/dev-server/plugins/wss/web-socket-router.js +0 -57
- package/dist/modules/dev/dev-server/plugins/wss/web-socket-server-adapter.js +0 -26
- package/dist/modules/dev/dev-server/plugins/wss/web-socket-server.js +0 -46
- package/dist/modules/dev/dev-server/plugins/wss/wss.plugin.js +0 -55
- package/dist/modules/dev/dev-server/sybmolicate/sybmolicate.plugin.js +0 -36
- package/dist/modules/dev/dev-server/sybmolicate/types.js +0 -2
- package/dist/modules/dev/terminal/base.terminal.reporter.js +0 -78
- package/dist/modules/dev/terminal/terminal.reporter.js +0 -76
- package/dist/modules/dev/types.js +0 -2
- package/dist/modules/dev/utils/log.js +0 -73
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
import type { ProcessedAppConfig } from "../config/types";
|
|
3
|
+
import type { PluginContext } from "./context";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Info.plist entries type
|
|
7
|
+
*/
|
|
8
|
+
export type InfoPlist = Record<string, unknown>;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Entitlements type
|
|
12
|
+
*/
|
|
13
|
+
export type Entitlements = Record<string, unknown>;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Android Manifest type (simplified)
|
|
17
|
+
*/
|
|
18
|
+
export interface AndroidManifest {
|
|
19
|
+
permissions: string[];
|
|
20
|
+
features: string[];
|
|
21
|
+
metadata: Record<string, string>;
|
|
22
|
+
activities: AndroidActivity[];
|
|
23
|
+
services: AndroidService[];
|
|
24
|
+
receivers: AndroidReceiver[];
|
|
25
|
+
providers: AndroidProvider[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface AndroidActivity {
|
|
29
|
+
name: string;
|
|
30
|
+
intentFilters?: AndroidIntentFilter[];
|
|
31
|
+
exported?: boolean;
|
|
32
|
+
launchMode?: string;
|
|
33
|
+
screenOrientation?: string;
|
|
34
|
+
configChanges?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface AndroidIntentFilter {
|
|
38
|
+
actions: string[];
|
|
39
|
+
categories: string[];
|
|
40
|
+
data?: AndroidIntentData[];
|
|
41
|
+
autoVerify?: boolean;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface AndroidIntentData {
|
|
45
|
+
scheme?: string;
|
|
46
|
+
host?: string;
|
|
47
|
+
pathPrefix?: string;
|
|
48
|
+
path?: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface AndroidService {
|
|
52
|
+
name: string;
|
|
53
|
+
exported?: boolean;
|
|
54
|
+
permission?: string;
|
|
55
|
+
intentFilters?: AndroidIntentFilter[];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface AndroidReceiver {
|
|
59
|
+
name: string;
|
|
60
|
+
exported?: boolean;
|
|
61
|
+
intentFilters?: AndroidIntentFilter[];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface AndroidProvider {
|
|
65
|
+
name: string;
|
|
66
|
+
authorities: string;
|
|
67
|
+
exported?: boolean;
|
|
68
|
+
grantUriPermissions?: boolean;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Abstract base class for all Teardown plugins
|
|
73
|
+
*
|
|
74
|
+
* Plugins extend this class to implement native configuration
|
|
75
|
+
* for specific capabilities (camera, location, push notifications, etc.)
|
|
76
|
+
*/
|
|
77
|
+
export abstract class BasePlugin<TConfig = unknown> {
|
|
78
|
+
/**
|
|
79
|
+
* Unique plugin identifier
|
|
80
|
+
*/
|
|
81
|
+
abstract readonly name: string;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Plugin version (semver)
|
|
85
|
+
*/
|
|
86
|
+
abstract readonly version: string;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Zod schema for validating plugin configuration
|
|
90
|
+
*/
|
|
91
|
+
abstract readonly configSchema: z.ZodSchema<TConfig>;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Human-readable description of what this plugin does
|
|
95
|
+
*/
|
|
96
|
+
abstract readonly description: string;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Plugin names that this plugin depends on (must run first)
|
|
100
|
+
*/
|
|
101
|
+
dependencies: string[] = [];
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Capabilities that this plugin provides
|
|
105
|
+
*/
|
|
106
|
+
provides: string[] = [];
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Platforms this plugin supports
|
|
110
|
+
*/
|
|
111
|
+
platforms: ("ios" | "android")[] = ["ios", "android"];
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Validate and parse plugin configuration
|
|
115
|
+
*/
|
|
116
|
+
validateConfig(config: unknown): TConfig {
|
|
117
|
+
return this.configSchema.parse(config);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Check if plugin supports the target platform
|
|
122
|
+
*/
|
|
123
|
+
supportsPlatform(platform: "ios" | "android"): boolean {
|
|
124
|
+
return this.platforms.includes(platform);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Pre-process hook - runs before transform
|
|
129
|
+
* Use for validation, setup, or reading existing files
|
|
130
|
+
*/
|
|
131
|
+
async preProcess(_context: PluginContext): Promise<void> {
|
|
132
|
+
// Default implementation does nothing
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Main transformation method - modifies the app configuration
|
|
137
|
+
* This is the core method that plugins must implement
|
|
138
|
+
*/
|
|
139
|
+
abstract transform(config: ProcessedAppConfig, pluginConfig: TConfig, context: PluginContext): ProcessedAppConfig;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Post-process hook - runs after transform
|
|
143
|
+
* Use for cleanup, file generation, or additional modifications
|
|
144
|
+
*/
|
|
145
|
+
async postProcess(_context: PluginContext): Promise<void> {
|
|
146
|
+
// Default implementation does nothing
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Modify iOS Info.plist entries
|
|
151
|
+
* Override in subclass to add plist modifications
|
|
152
|
+
*/
|
|
153
|
+
protected modifyInfoPlist(plist: InfoPlist, _config: TConfig, _context: PluginContext): InfoPlist {
|
|
154
|
+
return plist;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Modify iOS entitlements
|
|
159
|
+
* Override in subclass to add entitlement modifications
|
|
160
|
+
*/
|
|
161
|
+
protected modifyEntitlements(entitlements: Entitlements, _config: TConfig, _context: PluginContext): Entitlements {
|
|
162
|
+
return entitlements;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Modify Android manifest
|
|
167
|
+
* Override in subclass to add manifest modifications
|
|
168
|
+
*/
|
|
169
|
+
protected modifyAndroidManifest(
|
|
170
|
+
manifest: AndroidManifest,
|
|
171
|
+
_config: TConfig,
|
|
172
|
+
_context: PluginContext
|
|
173
|
+
): AndroidManifest {
|
|
174
|
+
return manifest;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Modify Android build.gradle content
|
|
179
|
+
* Override in subclass to add Gradle modifications
|
|
180
|
+
*/
|
|
181
|
+
protected modifyBuildGradle(content: string, _config: TConfig, _context: PluginContext): string {
|
|
182
|
+
return content;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Get iOS frameworks required by this plugin
|
|
187
|
+
*/
|
|
188
|
+
protected getRequiredFrameworks(_config: TConfig): string[] {
|
|
189
|
+
return [];
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Get CocoaPods dependencies required by this plugin
|
|
194
|
+
*/
|
|
195
|
+
protected getPodDependencies(
|
|
196
|
+
_config: TConfig
|
|
197
|
+
): Array<{ name: string; version?: string; options?: Record<string, unknown> }> {
|
|
198
|
+
return [];
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Get Gradle dependencies required by this plugin
|
|
203
|
+
*/
|
|
204
|
+
protected getGradleDependencies(_config: TConfig): string[] {
|
|
205
|
+
return [];
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Get Android permissions required by this plugin
|
|
210
|
+
*/
|
|
211
|
+
protected getAndroidPermissions(_config: TConfig): string[] {
|
|
212
|
+
return [];
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Get iOS background modes required by this plugin
|
|
217
|
+
*/
|
|
218
|
+
protected getBackgroundModes(_config: TConfig): string[] {
|
|
219
|
+
return [];
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Helper to add Info.plist usage description
|
|
224
|
+
*/
|
|
225
|
+
protected addUsageDescription(config: ProcessedAppConfig, key: string, description: string): ProcessedAppConfig {
|
|
226
|
+
return {
|
|
227
|
+
...config,
|
|
228
|
+
resolvedInfoPlist: {
|
|
229
|
+
...config.resolvedInfoPlist,
|
|
230
|
+
[key]: description,
|
|
231
|
+
},
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Helper to add iOS entitlement
|
|
237
|
+
*/
|
|
238
|
+
protected addEntitlement(config: ProcessedAppConfig, key: string, value: unknown): ProcessedAppConfig {
|
|
239
|
+
return {
|
|
240
|
+
...config,
|
|
241
|
+
resolvedEntitlements: {
|
|
242
|
+
...config.resolvedEntitlements,
|
|
243
|
+
[key]: value,
|
|
244
|
+
},
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Helper to add Android permission
|
|
250
|
+
*/
|
|
251
|
+
protected addAndroidPermission(config: ProcessedAppConfig, permission: string): ProcessedAppConfig {
|
|
252
|
+
if (config.resolvedAndroidPermissions.includes(permission)) {
|
|
253
|
+
return config;
|
|
254
|
+
}
|
|
255
|
+
return {
|
|
256
|
+
...config,
|
|
257
|
+
resolvedAndroidPermissions: [...config.resolvedAndroidPermissions, permission],
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Helper to add Android feature
|
|
263
|
+
*/
|
|
264
|
+
protected addAndroidFeature(config: ProcessedAppConfig, feature: string): ProcessedAppConfig {
|
|
265
|
+
if (config.resolvedAndroidFeatures.includes(feature)) {
|
|
266
|
+
return config;
|
|
267
|
+
}
|
|
268
|
+
return {
|
|
269
|
+
...config,
|
|
270
|
+
resolvedAndroidFeatures: [...config.resolvedAndroidFeatures, feature],
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Helper to add iOS background mode
|
|
276
|
+
*/
|
|
277
|
+
protected addBackgroundMode(config: ProcessedAppConfig, mode: string): ProcessedAppConfig {
|
|
278
|
+
if (config.resolvedBackgroundModes.includes(mode)) {
|
|
279
|
+
return config;
|
|
280
|
+
}
|
|
281
|
+
return {
|
|
282
|
+
...config,
|
|
283
|
+
resolvedBackgroundModes: [...config.resolvedBackgroundModes, mode],
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Helper to add iOS framework
|
|
289
|
+
*/
|
|
290
|
+
protected addFramework(config: ProcessedAppConfig, framework: string): ProcessedAppConfig {
|
|
291
|
+
if (config.resolvedFrameworks.includes(framework)) {
|
|
292
|
+
return config;
|
|
293
|
+
}
|
|
294
|
+
return {
|
|
295
|
+
...config,
|
|
296
|
+
resolvedFrameworks: [...config.resolvedFrameworks, framework],
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Helper to add Gradle dependency
|
|
302
|
+
*/
|
|
303
|
+
protected addGradleDependency(config: ProcessedAppConfig, dependency: string): ProcessedAppConfig {
|
|
304
|
+
if (config.resolvedGradleDependencies.includes(dependency)) {
|
|
305
|
+
return config;
|
|
306
|
+
}
|
|
307
|
+
return {
|
|
308
|
+
...config,
|
|
309
|
+
resolvedGradleDependencies: [...config.resolvedGradleDependencies, dependency],
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Helper to add CocoaPods dependency
|
|
315
|
+
*/
|
|
316
|
+
protected addPodDependency(
|
|
317
|
+
config: ProcessedAppConfig,
|
|
318
|
+
pod: { name: string; version?: string; options?: Record<string, unknown> }
|
|
319
|
+
): ProcessedAppConfig {
|
|
320
|
+
const existing = config.resolvedPodDependencies.find((p) => p.name === pod.name);
|
|
321
|
+
if (existing) {
|
|
322
|
+
return config;
|
|
323
|
+
}
|
|
324
|
+
return {
|
|
325
|
+
...config,
|
|
326
|
+
resolvedPodDependencies: [...config.resolvedPodDependencies, pod],
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Helper to add URL scheme
|
|
332
|
+
*/
|
|
333
|
+
protected addUrlScheme(config: ProcessedAppConfig, scheme: string): ProcessedAppConfig {
|
|
334
|
+
if (config.resolvedUrlSchemes.includes(scheme)) {
|
|
335
|
+
return config;
|
|
336
|
+
}
|
|
337
|
+
return {
|
|
338
|
+
...config,
|
|
339
|
+
resolvedUrlSchemes: [...config.resolvedUrlSchemes, scheme],
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Helper to add Android intent filter
|
|
345
|
+
*/
|
|
346
|
+
protected addIntentFilter(config: ProcessedAppConfig, intentFilter: AndroidIntentFilter): ProcessedAppConfig {
|
|
347
|
+
return {
|
|
348
|
+
...config,
|
|
349
|
+
resolvedIntentFilters: [...config.resolvedIntentFilters, intentFilter],
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Helper to add Android metadata
|
|
355
|
+
*/
|
|
356
|
+
protected addAndroidMetadata(config: ProcessedAppConfig, key: string, value: string): ProcessedAppConfig {
|
|
357
|
+
return {
|
|
358
|
+
...config,
|
|
359
|
+
resolvedAndroidMetadata: {
|
|
360
|
+
...config.resolvedAndroidMetadata,
|
|
361
|
+
[key]: value,
|
|
362
|
+
},
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Plugin constructor type for registration
|
|
369
|
+
*/
|
|
370
|
+
export type PluginConstructor<TConfig = unknown> = new () => BasePlugin<TConfig>;
|
|
@@ -0,0 +1,64 @@
|
|
|
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
|
+
* Biometrics plugin configuration schema
|
|
8
|
+
*/
|
|
9
|
+
export const BiometricsPluginConfigSchema = z.object({
|
|
10
|
+
/** iOS Face ID usage description */
|
|
11
|
+
faceIdPermission: z.string().min(1, "Face ID permission description is required"),
|
|
12
|
+
|
|
13
|
+
/** Allow device credential (PIN/password) as fallback */
|
|
14
|
+
allowDeviceCredentialFallback: z.boolean().optional().default(true),
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export type BiometricsPluginConfig = z.infer<typeof BiometricsPluginConfigSchema>;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Biometrics capability plugin
|
|
21
|
+
*
|
|
22
|
+
* Configures biometric authentication (Face ID, Touch ID, fingerprint)
|
|
23
|
+
* for iOS and Android.
|
|
24
|
+
*/
|
|
25
|
+
export class BiometricsPlugin extends BasePlugin<BiometricsPluginConfig> {
|
|
26
|
+
readonly name = "biometrics";
|
|
27
|
+
readonly version = "1.0.0";
|
|
28
|
+
readonly description = "Configure biometric authentication (Face ID, Touch ID, fingerprint)";
|
|
29
|
+
readonly configSchema = BiometricsPluginConfigSchema;
|
|
30
|
+
|
|
31
|
+
override provides = ["biometrics", "authentication"];
|
|
32
|
+
override platforms: ("ios" | "android")[] = ["ios", "android"];
|
|
33
|
+
|
|
34
|
+
transform(
|
|
35
|
+
config: ProcessedAppConfig,
|
|
36
|
+
pluginConfig: BiometricsPluginConfig,
|
|
37
|
+
context: PluginContext
|
|
38
|
+
): ProcessedAppConfig {
|
|
39
|
+
const { log } = context;
|
|
40
|
+
log.debug("Applying biometrics configuration...");
|
|
41
|
+
|
|
42
|
+
let result = config;
|
|
43
|
+
|
|
44
|
+
// iOS: Add Face ID usage description
|
|
45
|
+
result = this.addUsageDescription(result, "NSFaceIDUsageDescription", pluginConfig.faceIdPermission);
|
|
46
|
+
|
|
47
|
+
// iOS: Add LocalAuthentication framework
|
|
48
|
+
result = this.addFramework(result, "LocalAuthentication");
|
|
49
|
+
|
|
50
|
+
// Android: Add biometric permission
|
|
51
|
+
result = this.addAndroidPermission(result, "android.permission.USE_BIOMETRIC");
|
|
52
|
+
|
|
53
|
+
// Android: Add fingerprint permission (for older devices)
|
|
54
|
+
result = this.addAndroidPermission(result, "android.permission.USE_FINGERPRINT");
|
|
55
|
+
|
|
56
|
+
// Android: Add biometric feature (optional)
|
|
57
|
+
result = this.addAndroidFeature(result, "android.hardware.fingerprint");
|
|
58
|
+
|
|
59
|
+
// Android: Add androidx.biometric dependency
|
|
60
|
+
result = this.addGradleDependency(result, "androidx.biometric:biometric:1.2.0-alpha05");
|
|
61
|
+
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
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
|
+
* Bluetooth plugin configuration schema
|
|
8
|
+
*/
|
|
9
|
+
export const BluetoothPluginConfigSchema = z.object({
|
|
10
|
+
/** iOS Bluetooth always-on permission description */
|
|
11
|
+
alwaysPermission: z.string().min(1, "Bluetooth permission description is required"),
|
|
12
|
+
|
|
13
|
+
/** Enable BLE central mode (connecting to devices) */
|
|
14
|
+
centralMode: z.boolean().optional().default(true),
|
|
15
|
+
|
|
16
|
+
/** Enable BLE peripheral mode (advertising) */
|
|
17
|
+
peripheralMode: z.boolean().optional().default(false),
|
|
18
|
+
|
|
19
|
+
/** Enable background Bluetooth */
|
|
20
|
+
backgroundMode: z.boolean().optional().default(false),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export type BluetoothPluginConfig = z.infer<typeof BluetoothPluginConfigSchema>;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Bluetooth capability plugin
|
|
27
|
+
*/
|
|
28
|
+
export class BluetoothPlugin extends BasePlugin<BluetoothPluginConfig> {
|
|
29
|
+
readonly name = "bluetooth";
|
|
30
|
+
readonly version = "1.0.0";
|
|
31
|
+
readonly description = "Configure Bluetooth Low Energy (BLE) access";
|
|
32
|
+
readonly configSchema = BluetoothPluginConfigSchema;
|
|
33
|
+
|
|
34
|
+
override provides = ["bluetooth", "ble"];
|
|
35
|
+
override platforms: ("ios" | "android")[] = ["ios", "android"];
|
|
36
|
+
|
|
37
|
+
transform(
|
|
38
|
+
config: ProcessedAppConfig,
|
|
39
|
+
pluginConfig: BluetoothPluginConfig,
|
|
40
|
+
context: PluginContext
|
|
41
|
+
): ProcessedAppConfig {
|
|
42
|
+
const { log } = context;
|
|
43
|
+
log.debug("Applying Bluetooth configuration...");
|
|
44
|
+
|
|
45
|
+
let result = config;
|
|
46
|
+
|
|
47
|
+
// iOS: Add Bluetooth usage description
|
|
48
|
+
result = this.addUsageDescription(result, "NSBluetoothAlwaysUsageDescription", pluginConfig.alwaysPermission);
|
|
49
|
+
|
|
50
|
+
// iOS: Legacy Bluetooth peripheral description
|
|
51
|
+
result = this.addUsageDescription(result, "NSBluetoothPeripheralUsageDescription", pluginConfig.alwaysPermission);
|
|
52
|
+
|
|
53
|
+
// iOS: Add CoreBluetooth framework
|
|
54
|
+
result = this.addFramework(result, "CoreBluetooth");
|
|
55
|
+
|
|
56
|
+
// iOS: Add background modes
|
|
57
|
+
if (pluginConfig.backgroundMode) {
|
|
58
|
+
if (pluginConfig.centralMode) {
|
|
59
|
+
result = this.addBackgroundMode(result, "bluetooth-central");
|
|
60
|
+
}
|
|
61
|
+
if (pluginConfig.peripheralMode) {
|
|
62
|
+
result = this.addBackgroundMode(result, "bluetooth-peripheral");
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Android: Add Bluetooth permissions (API 31+)
|
|
67
|
+
result = this.addAndroidPermission(result, "android.permission.BLUETOOTH_SCAN");
|
|
68
|
+
result = this.addAndroidPermission(result, "android.permission.BLUETOOTH_CONNECT");
|
|
69
|
+
|
|
70
|
+
if (pluginConfig.peripheralMode) {
|
|
71
|
+
result = this.addAndroidPermission(result, "android.permission.BLUETOOTH_ADVERTISE");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Android: Legacy Bluetooth permissions
|
|
75
|
+
result = this.addAndroidPermission(result, "android.permission.BLUETOOTH");
|
|
76
|
+
result = this.addAndroidPermission(result, "android.permission.BLUETOOTH_ADMIN");
|
|
77
|
+
|
|
78
|
+
// Android: Location permission (required for BLE scanning on older versions)
|
|
79
|
+
result = this.addAndroidPermission(result, "android.permission.ACCESS_FINE_LOCATION");
|
|
80
|
+
|
|
81
|
+
// Android: Add Bluetooth LE feature
|
|
82
|
+
result = this.addAndroidFeature(result, "android.hardware.bluetooth_le");
|
|
83
|
+
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
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
|
+
* Calendar plugin configuration schema
|
|
8
|
+
*/
|
|
9
|
+
export const CalendarPluginConfigSchema = z.object({
|
|
10
|
+
/** iOS calendar usage description */
|
|
11
|
+
permission: z.string().min(1, "Calendar permission description is required"),
|
|
12
|
+
|
|
13
|
+
/** Enable write access to calendar */
|
|
14
|
+
writeAccess: z.boolean().optional().default(false),
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export type CalendarPluginConfig = z.infer<typeof CalendarPluginConfigSchema>;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Calendar capability plugin
|
|
21
|
+
*/
|
|
22
|
+
export class CalendarPlugin extends BasePlugin<CalendarPluginConfig> {
|
|
23
|
+
readonly name = "calendar";
|
|
24
|
+
readonly version = "1.0.0";
|
|
25
|
+
readonly description = "Configure calendar access for reading and writing events";
|
|
26
|
+
readonly configSchema = CalendarPluginConfigSchema;
|
|
27
|
+
|
|
28
|
+
override provides = ["calendar"];
|
|
29
|
+
override platforms: ("ios" | "android")[] = ["ios", "android"];
|
|
30
|
+
|
|
31
|
+
transform(
|
|
32
|
+
config: ProcessedAppConfig,
|
|
33
|
+
pluginConfig: CalendarPluginConfig,
|
|
34
|
+
context: PluginContext
|
|
35
|
+
): ProcessedAppConfig {
|
|
36
|
+
const { log } = context;
|
|
37
|
+
log.debug("Applying calendar configuration...");
|
|
38
|
+
|
|
39
|
+
let result = config;
|
|
40
|
+
|
|
41
|
+
// iOS: Add usage description
|
|
42
|
+
result = this.addUsageDescription(result, "NSCalendarsUsageDescription", pluginConfig.permission);
|
|
43
|
+
|
|
44
|
+
// iOS: Add EventKit framework
|
|
45
|
+
result = this.addFramework(result, "EventKit");
|
|
46
|
+
|
|
47
|
+
// Android: Add read permission
|
|
48
|
+
result = this.addAndroidPermission(result, "android.permission.READ_CALENDAR");
|
|
49
|
+
|
|
50
|
+
// Android: Add write permission if needed
|
|
51
|
+
if (pluginConfig.writeAccess) {
|
|
52
|
+
result = this.addAndroidPermission(result, "android.permission.WRITE_CALENDAR");
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
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
|
+
* Camera plugin configuration schema
|
|
8
|
+
*/
|
|
9
|
+
export const CameraPluginConfigSchema = z.object({
|
|
10
|
+
/** iOS camera usage description */
|
|
11
|
+
cameraPermission: z.string().min(1, "Camera permission description is required"),
|
|
12
|
+
|
|
13
|
+
/** iOS microphone usage description (for video recording) */
|
|
14
|
+
microphonePermission: z.string().optional(),
|
|
15
|
+
|
|
16
|
+
/** iOS photo library usage description */
|
|
17
|
+
photosPermission: z.string().optional(),
|
|
18
|
+
|
|
19
|
+
/** Enable barcode scanning support */
|
|
20
|
+
enableBarcodeScan: z.boolean().optional().default(false),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export type CameraPluginConfig = z.infer<typeof CameraPluginConfigSchema>;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Camera capability plugin
|
|
27
|
+
*
|
|
28
|
+
* Configures camera access for iOS and Android including
|
|
29
|
+
* permissions, frameworks, and optional barcode scanning.
|
|
30
|
+
*/
|
|
31
|
+
export class CameraPlugin extends BasePlugin<CameraPluginConfig> {
|
|
32
|
+
readonly name = "camera";
|
|
33
|
+
readonly version = "1.0.0";
|
|
34
|
+
readonly description = "Configure camera access for capturing photos and videos";
|
|
35
|
+
readonly configSchema = CameraPluginConfigSchema;
|
|
36
|
+
|
|
37
|
+
override provides = ["camera"];
|
|
38
|
+
override platforms: ("ios" | "android")[] = ["ios", "android"];
|
|
39
|
+
|
|
40
|
+
transform(config: ProcessedAppConfig, pluginConfig: CameraPluginConfig, context: PluginContext): ProcessedAppConfig {
|
|
41
|
+
const { log } = context;
|
|
42
|
+
log.debug("Applying camera configuration...");
|
|
43
|
+
|
|
44
|
+
let result = config;
|
|
45
|
+
|
|
46
|
+
// iOS: Add usage descriptions
|
|
47
|
+
result = this.addUsageDescription(result, "NSCameraUsageDescription", pluginConfig.cameraPermission);
|
|
48
|
+
|
|
49
|
+
if (pluginConfig.microphonePermission) {
|
|
50
|
+
result = this.addUsageDescription(result, "NSMicrophoneUsageDescription", pluginConfig.microphonePermission);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (pluginConfig.photosPermission) {
|
|
54
|
+
result = this.addUsageDescription(result, "NSPhotoLibraryUsageDescription", pluginConfig.photosPermission);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// iOS: Add frameworks
|
|
58
|
+
result = this.addFramework(result, "AVFoundation");
|
|
59
|
+
|
|
60
|
+
if (pluginConfig.enableBarcodeScan) {
|
|
61
|
+
result = this.addFramework(result, "Vision");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Android: Add permissions
|
|
65
|
+
result = this.addAndroidPermission(result, "android.permission.CAMERA");
|
|
66
|
+
|
|
67
|
+
if (pluginConfig.microphonePermission) {
|
|
68
|
+
result = this.addAndroidPermission(result, "android.permission.RECORD_AUDIO");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Android: Add camera feature
|
|
72
|
+
result = this.addAndroidFeature(result, "android.hardware.camera");
|
|
73
|
+
result = this.addAndroidFeature(result, "android.hardware.camera.autofocus");
|
|
74
|
+
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
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
|
+
* Contacts plugin configuration schema
|
|
8
|
+
*/
|
|
9
|
+
export const ContactsPluginConfigSchema = z.object({
|
|
10
|
+
/** iOS contacts usage description */
|
|
11
|
+
permission: z.string().min(1, "Contacts permission description is required"),
|
|
12
|
+
|
|
13
|
+
/** Enable write access to contacts */
|
|
14
|
+
writeAccess: z.boolean().optional().default(false),
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export type ContactsPluginConfig = z.infer<typeof ContactsPluginConfigSchema>;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Contacts capability plugin
|
|
21
|
+
*/
|
|
22
|
+
export class ContactsPlugin extends BasePlugin<ContactsPluginConfig> {
|
|
23
|
+
readonly name = "contacts";
|
|
24
|
+
readonly version = "1.0.0";
|
|
25
|
+
readonly description = "Configure contacts access for reading and writing contacts";
|
|
26
|
+
readonly configSchema = ContactsPluginConfigSchema;
|
|
27
|
+
|
|
28
|
+
override provides = ["contacts"];
|
|
29
|
+
override platforms: ("ios" | "android")[] = ["ios", "android"];
|
|
30
|
+
|
|
31
|
+
transform(
|
|
32
|
+
config: ProcessedAppConfig,
|
|
33
|
+
pluginConfig: ContactsPluginConfig,
|
|
34
|
+
context: PluginContext
|
|
35
|
+
): ProcessedAppConfig {
|
|
36
|
+
const { log } = context;
|
|
37
|
+
log.debug("Applying contacts configuration...");
|
|
38
|
+
|
|
39
|
+
let result = config;
|
|
40
|
+
|
|
41
|
+
// iOS: Add usage description
|
|
42
|
+
result = this.addUsageDescription(result, "NSContactsUsageDescription", pluginConfig.permission);
|
|
43
|
+
|
|
44
|
+
// iOS: Add Contacts framework
|
|
45
|
+
result = this.addFramework(result, "Contacts");
|
|
46
|
+
|
|
47
|
+
// Android: Add read permission
|
|
48
|
+
result = this.addAndroidPermission(result, "android.permission.READ_CONTACTS");
|
|
49
|
+
|
|
50
|
+
// Android: Add write permission if needed
|
|
51
|
+
if (pluginConfig.writeAccess) {
|
|
52
|
+
result = this.addAndroidPermission(result, "android.permission.WRITE_CONTACTS");
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
}
|