@symbiote-native/cli 0.0.1
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/LICENSE +21 -0
- package/README.md +492 -0
- package/bundle.js +2833 -0
- package/package.json +49 -0
- package/src/index.ts +70 -0
- package/templates/README.md +93 -0
- package/templates/js/angular/.prettierrc.js +5 -0
- package/templates/js/angular/.watchmanconfig +1 -0
- package/templates/js/angular/README.md +117 -0
- package/templates/js/angular/app.json +4 -0
- package/templates/js/angular/babel.config.js +34 -0
- package/templates/js/angular/index.js +12 -0
- package/templates/js/angular/metro.config.js +38 -0
- package/templates/js/angular/package.json.fragment.json +29 -0
- package/templates/js/angular/src/App.css +89 -0
- package/templates/js/angular/src/App.ts +40 -0
- package/templates/js/angular/src/assets/angular-logo.png +0 -0
- package/templates/js/angular/src/assets/angular-logo@2x.png +0 -0
- package/templates/js/angular/src/assets/angular-logo@3x.png +0 -0
- package/templates/js/angular/src/assets/plus-icon.png +0 -0
- package/templates/js/angular/src/assets/plus-icon@2x.png +0 -0
- package/templates/js/angular/src/assets/plus-icon@3x.png +0 -0
- package/templates/js/angular/src/assets/react-native-logo.png +0 -0
- package/templates/js/angular/src/assets/react-native-logo@2x.png +0 -0
- package/templates/js/angular/src/assets/react-native-logo@3x.png +0 -0
- package/templates/js/angular/src/css.d.ts +23 -0
- package/templates/js/angular/tsconfig.angular.json +42 -0
- package/templates/js/angular/tsconfig.json +17 -0
- package/templates/js/react/.prettierrc.js +5 -0
- package/templates/js/react/.watchmanconfig +1 -0
- package/templates/js/react/App.css +69 -0
- package/templates/js/react/App.jsx +27 -0
- package/templates/js/react/App.tsx +27 -0
- package/templates/js/react/README.md +116 -0
- package/templates/js/react/app.json +4 -0
- package/templates/js/react/assets/react-native-logo.png +0 -0
- package/templates/js/react/assets/react-native-logo@2x.png +0 -0
- package/templates/js/react/assets/react-native-logo@3x.png +0 -0
- package/templates/js/react/babel.config.js +24 -0
- package/templates/js/react/css.d.ts +24 -0
- package/templates/js/react/index.js +14 -0
- package/templates/js/react/metro.config.js +29 -0
- package/templates/js/react/package.json.fragment.json +22 -0
- package/templates/js/react/package.json.fragment.typescript.json +11 -0
- package/templates/js/react/tsconfig.json +18 -0
- package/templates/js/solid/.prettierrc.js +5 -0
- package/templates/js/solid/.watchmanconfig +1 -0
- package/templates/js/solid/App.css +89 -0
- package/templates/js/solid/App.jsx +35 -0
- package/templates/js/solid/App.tsx +35 -0
- package/templates/js/solid/README.md +18 -0
- package/templates/js/solid/app.json +4 -0
- package/templates/js/solid/assets/plus-icon.png +0 -0
- package/templates/js/solid/assets/plus-icon@2x.png +0 -0
- package/templates/js/solid/assets/plus-icon@3x.png +0 -0
- package/templates/js/solid/assets/react-native-logo.png +0 -0
- package/templates/js/solid/assets/react-native-logo@2x.png +0 -0
- package/templates/js/solid/assets/react-native-logo@3x.png +0 -0
- package/templates/js/solid/assets/solid-logo.png +0 -0
- package/templates/js/solid/assets/solid-logo@2x.png +0 -0
- package/templates/js/solid/assets/solid-logo@3x.png +0 -0
- package/templates/js/solid/babel.config.js +29 -0
- package/templates/js/solid/css.d.ts +20 -0
- package/templates/js/solid/eslint.config.js +3 -0
- package/templates/js/solid/index.js +13 -0
- package/templates/js/solid/metro.config.js +50 -0
- package/templates/js/solid/package.json.fragment.json +23 -0
- package/templates/js/solid/package.json.fragment.typescript.json +11 -0
- package/templates/js/solid/tsconfig.json +11 -0
- package/templates/js/svelte/.prettierrc.js +15 -0
- package/templates/js/svelte/.watchmanconfig +1 -0
- package/templates/js/svelte/App.svelte +123 -0
- package/templates/js/svelte/App.typescript.svelte +123 -0
- package/templates/js/svelte/README.md +18 -0
- package/templates/js/svelte/app.json +4 -0
- package/templates/js/svelte/babel.config.js +22 -0
- package/templates/js/svelte/css.d.ts +21 -0
- package/templates/js/svelte/eslint.config.js +37 -0
- package/templates/js/svelte/image-uris.js +8 -0
- package/templates/js/svelte/index.js +13 -0
- package/templates/js/svelte/metro.config.js +83 -0
- package/templates/js/svelte/package.json.fragment.json +26 -0
- package/templates/js/svelte/package.json.fragment.typescript.json +12 -0
- package/templates/js/svelte/svelte.config.js +47 -0
- package/templates/js/svelte/tsconfig.json +9 -0
- package/templates/js/svelte/tsconfig.typecheck.json +4 -0
- package/templates/js/vue-sfc/.prettierrc.js +5 -0
- package/templates/js/vue-sfc/.watchmanconfig +1 -0
- package/templates/js/vue-sfc/App.typescript.vue +128 -0
- package/templates/js/vue-sfc/App.vue +128 -0
- package/templates/js/vue-sfc/README.md +124 -0
- package/templates/js/vue-sfc/app.json +4 -0
- package/templates/js/vue-sfc/assets/plus-icon.png +0 -0
- package/templates/js/vue-sfc/assets/plus-icon@2x.png +0 -0
- package/templates/js/vue-sfc/assets/plus-icon@3x.png +0 -0
- package/templates/js/vue-sfc/assets/react-native-logo.png +0 -0
- package/templates/js/vue-sfc/assets/react-native-logo@2x.png +0 -0
- package/templates/js/vue-sfc/assets/react-native-logo@3x.png +0 -0
- package/templates/js/vue-sfc/assets/vue-logo.png +0 -0
- package/templates/js/vue-sfc/assets/vue-logo@2x.png +0 -0
- package/templates/js/vue-sfc/assets/vue-logo@3x.png +0 -0
- package/templates/js/vue-sfc/babel.config.js +24 -0
- package/templates/js/vue-sfc/css.d.ts +24 -0
- package/templates/js/vue-sfc/eslint.config.js +48 -0
- package/templates/js/vue-sfc/index.js +13 -0
- package/templates/js/vue-sfc/metro.config.js +30 -0
- package/templates/js/vue-sfc/package.json.fragment.json +26 -0
- package/templates/js/vue-sfc/package.json.fragment.typescript.json +11 -0
- package/templates/js/vue-sfc/tsconfig.json +18 -0
- package/templates/js/vue-sfc/tsconfig.typecheck.json +8 -0
- package/templates/js/vue-sfc/vue-runtime-core.d.ts +3 -0
- package/templates/js/vue-tsx/.prettierrc.js +5 -0
- package/templates/js/vue-tsx/.watchmanconfig +1 -0
- package/templates/js/vue-tsx/App.css +89 -0
- package/templates/js/vue-tsx/App.jsx +40 -0
- package/templates/js/vue-tsx/App.tsx +40 -0
- package/templates/js/vue-tsx/README.md +110 -0
- package/templates/js/vue-tsx/app.json +4 -0
- package/templates/js/vue-tsx/assets/plus-icon.png +0 -0
- package/templates/js/vue-tsx/assets/plus-icon@2x.png +0 -0
- package/templates/js/vue-tsx/assets/plus-icon@3x.png +0 -0
- package/templates/js/vue-tsx/assets/react-native-logo.png +0 -0
- package/templates/js/vue-tsx/assets/react-native-logo@2x.png +0 -0
- package/templates/js/vue-tsx/assets/react-native-logo@3x.png +0 -0
- package/templates/js/vue-tsx/assets/vue-logo.png +0 -0
- package/templates/js/vue-tsx/assets/vue-logo@2x.png +0 -0
- package/templates/js/vue-tsx/assets/vue-logo@3x.png +0 -0
- package/templates/js/vue-tsx/babel.config.js +67 -0
- package/templates/js/vue-tsx/css.d.ts +24 -0
- package/templates/js/vue-tsx/index.js +14 -0
- package/templates/js/vue-tsx/metro.config.js +42 -0
- package/templates/js/vue-tsx/package.json.fragment.json +26 -0
- package/templates/js/vue-tsx/package.json.fragment.typescript.json +11 -0
- package/templates/js/vue-tsx/tsconfig.json +15 -0
- package/templates/js/vue-tsx/tsconfig.typecheck.json +10 -0
- package/templates/js/vue-tsx/vue-jsx.d.ts +43 -0
- package/templates/js/vue-tsx/vue-runtime-core.d.ts +3 -0
- package/templates/layers/README.md +90 -0
- package/templates/layers/application/package.json.fragment.json +5 -0
- package/templates/layers/battery/package.json.fragment.json +5 -0
- package/templates/layers/brightness/package.json.fragment.json +5 -0
- package/templates/layers/cellular/package.json.fragment.json +5 -0
- package/templates/layers/clipboard/package.json.fragment.json +5 -0
- package/templates/layers/crypto/package.json.fragment.json +5 -0
- package/templates/layers/device/package.json.fragment.json +5 -0
- package/templates/layers/expo-modules/ios/Canary/Info.plist +66 -0
- package/templates/layers/expo-modules/package.json.fragment.json +9 -0
- package/templates/layers/haptics/package.json.fragment.json +5 -0
- package/templates/layers/keep-awake/package.json.fragment.json +5 -0
- package/templates/layers/local-auth/package.json.fragment.json +5 -0
- package/templates/layers/localization/package.json.fragment.json +5 -0
- package/templates/layers/navigation/app/angular/assets/angular-logo.png +0 -0
- package/templates/layers/navigation/app/angular/assets/angular-logo@2x.png +0 -0
- package/templates/layers/navigation/app/angular/assets/angular-logo@3x.png +0 -0
- package/templates/layers/navigation/app/angular/assets/plus-icon.png +0 -0
- package/templates/layers/navigation/app/angular/assets/plus-icon@2x.png +0 -0
- package/templates/layers/navigation/app/angular/assets/plus-icon@3x.png +0 -0
- package/templates/layers/navigation/app/angular/assets/react-native-logo.png +0 -0
- package/templates/layers/navigation/app/angular/assets/react-native-logo@2x.png +0 -0
- package/templates/layers/navigation/app/angular/assets/react-native-logo@3x.png +0 -0
- package/templates/layers/navigation/app/angular/src/App.css +129 -0
- package/templates/layers/navigation/app/angular/src/App.ts +31 -0
- package/templates/layers/navigation/app/angular/src/DetailsScreen.ts +24 -0
- package/templates/layers/navigation/app/angular/src/MenuScreen.ts +43 -0
- package/templates/layers/navigation/app/react/App.css +109 -0
- package/templates/layers/navigation/app/react/App.jsx +77 -0
- package/templates/layers/navigation/app/react/App.tsx +77 -0
- package/templates/layers/navigation/app/react/assets/react-native-logo.png +0 -0
- package/templates/layers/navigation/app/react/assets/react-native-logo@2x.png +0 -0
- package/templates/layers/navigation/app/react/assets/react-native-logo@3x.png +0 -0
- package/templates/layers/navigation/app/solid/App.css +129 -0
- package/templates/layers/navigation/app/solid/App.jsx +85 -0
- package/templates/layers/navigation/app/solid/App.tsx +85 -0
- package/templates/layers/navigation/app/solid/assets/plus-icon.png +0 -0
- package/templates/layers/navigation/app/solid/assets/plus-icon@2x.png +0 -0
- package/templates/layers/navigation/app/solid/assets/plus-icon@3x.png +0 -0
- package/templates/layers/navigation/app/solid/assets/react-native-logo.png +0 -0
- package/templates/layers/navigation/app/solid/assets/react-native-logo@2x.png +0 -0
- package/templates/layers/navigation/app/solid/assets/react-native-logo@3x.png +0 -0
- package/templates/layers/navigation/app/solid/assets/solid-logo.png +0 -0
- package/templates/layers/navigation/app/solid/assets/solid-logo@2x.png +0 -0
- package/templates/layers/navigation/app/solid/assets/solid-logo@3x.png +0 -0
- package/templates/layers/navigation/app/svelte/App.css +129 -0
- package/templates/layers/navigation/app/svelte/App.svelte +19 -0
- package/templates/layers/navigation/app/svelte/App.typescript.svelte +19 -0
- package/templates/layers/navigation/app/svelte/DetailsScreen.svelte +17 -0
- package/templates/layers/navigation/app/svelte/DetailsScreen.typescript.svelte +17 -0
- package/templates/layers/navigation/app/svelte/MenuScreen.svelte +40 -0
- package/templates/layers/navigation/app/svelte/MenuScreen.typescript.svelte +40 -0
- package/templates/layers/navigation/app/svelte/image-uris.js +8 -0
- package/templates/layers/navigation/app/vue-sfc/App.css +129 -0
- package/templates/layers/navigation/app/vue-sfc/App.typescript.vue +36 -0
- package/templates/layers/navigation/app/vue-sfc/App.vue +36 -0
- package/templates/layers/navigation/app/vue-sfc/DetailsScreen.typescript.vue +20 -0
- package/templates/layers/navigation/app/vue-sfc/DetailsScreen.vue +20 -0
- package/templates/layers/navigation/app/vue-sfc/MenuScreen.typescript.vue +52 -0
- package/templates/layers/navigation/app/vue-sfc/MenuScreen.vue +52 -0
- package/templates/layers/navigation/app/vue-sfc/assets/plus-icon.png +0 -0
- package/templates/layers/navigation/app/vue-sfc/assets/plus-icon@2x.png +0 -0
- package/templates/layers/navigation/app/vue-sfc/assets/plus-icon@3x.png +0 -0
- package/templates/layers/navigation/app/vue-sfc/assets/react-native-logo.png +0 -0
- package/templates/layers/navigation/app/vue-sfc/assets/react-native-logo@2x.png +0 -0
- package/templates/layers/navigation/app/vue-sfc/assets/react-native-logo@3x.png +0 -0
- package/templates/layers/navigation/app/vue-sfc/assets/vue-logo.png +0 -0
- package/templates/layers/navigation/app/vue-sfc/assets/vue-logo@2x.png +0 -0
- package/templates/layers/navigation/app/vue-sfc/assets/vue-logo@3x.png +0 -0
- package/templates/layers/navigation/app/vue-tsx/App.css +129 -0
- package/templates/layers/navigation/app/vue-tsx/App.jsx +91 -0
- package/templates/layers/navigation/app/vue-tsx/App.tsx +91 -0
- package/templates/layers/navigation/app/vue-tsx/assets/plus-icon.png +0 -0
- package/templates/layers/navigation/app/vue-tsx/assets/plus-icon@2x.png +0 -0
- package/templates/layers/navigation/app/vue-tsx/assets/plus-icon@3x.png +0 -0
- package/templates/layers/navigation/app/vue-tsx/assets/react-native-logo.png +0 -0
- package/templates/layers/navigation/app/vue-tsx/assets/react-native-logo@2x.png +0 -0
- package/templates/layers/navigation/app/vue-tsx/assets/react-native-logo@3x.png +0 -0
- package/templates/layers/navigation/app/vue-tsx/assets/vue-logo.png +0 -0
- package/templates/layers/navigation/app/vue-tsx/assets/vue-logo@2x.png +0 -0
- package/templates/layers/navigation/app/vue-tsx/assets/vue-logo@3x.png +0 -0
- package/templates/layers/navigation/package.json.fragment.json +5 -0
- package/templates/layers/network/package.json.fragment.json +5 -0
- package/templates/layers/screen-orientation/package.json.fragment.json +5 -0
- package/templates/layers/secure-store/package.json.fragment.json +5 -0
- package/templates/layers/sensors/package.json.fragment.json +5 -0
- package/templates/layers/sharing/package.json.fragment.json +5 -0
- package/templates/layers/slider/package.json.fragment.json +5 -0
- package/templates/layers/sms/package.json.fragment.json +5 -0
- package/templates/layers/splash-screen/native/android/app/src/main/AndroidManifest.xml +28 -0
- package/templates/layers/splash-screen/native/android/app/src/main/java/com/canary/MainActivity.kt +29 -0
- package/templates/layers/splash-screen/native/android/app/src/main/res/values/styles.xml +12 -0
- package/templates/layers/splash-screen/native/ios/Canary/AppDelegate.swift +54 -0
- package/templates/layers/splash-screen/package.json.fragment.json +5 -0
- package/templates/layers/standard-web-crypto/package.json.fragment.json +5 -0
- package/templates/layers/store-review/package.json.fragment.json +5 -0
- package/templates/layers/system-ui/package.json.fragment.json +5 -0
- package/templates/layers/testing/detox.config.js +42 -0
- package/templates/layers/testing/e2e/jest.config.js +21 -0
- package/templates/layers/testing/e2e/setup.ts +3 -0
- package/templates/layers/testing/e2e/smoke.test.ts +17 -0
- package/templates/layers/testing/e2e/tsconfig.json +7 -0
- package/templates/layers/testing/fragment/angular/package.json.fragment.json +18 -0
- package/templates/layers/testing/fragment/base/package.json.fragment.json +18 -0
- package/templates/layers/tracking-transparency/package.json.fragment.json +5 -0
- package/templates/layers/web-browser/package.json.fragment.json +5 -0
- package/templates/native/Gemfile +17 -0
- package/templates/native/README.md +48 -0
- package/templates/native/android/app/build.gradle +130 -0
- package/templates/native/android/app/debug.keystore +0 -0
- package/templates/native/android/app/proguard-rules.pro +10 -0
- package/templates/native/android/app/src/androidTest/java/com/canary/DetoxTest.java +29 -0
- package/templates/native/android/app/src/main/AndroidManifest.xml +28 -0
- package/templates/native/android/app/src/main/java/com/canary/MainActivity.kt +22 -0
- package/templates/native/android/app/src/main/java/com/canary/MainApplication.kt +27 -0
- package/templates/native/android/app/src/main/res/drawable/rn_edit_text_material.xml +37 -0
- package/templates/native/android/app/src/main/res/drawable-hdpi/bootsplash_logo.png +0 -0
- package/templates/native/android/app/src/main/res/drawable-mdpi/bootsplash_logo.png +0 -0
- package/templates/native/android/app/src/main/res/drawable-xhdpi/bootsplash_logo.png +0 -0
- package/templates/native/android/app/src/main/res/drawable-xxhdpi/bootsplash_logo.png +0 -0
- package/templates/native/android/app/src/main/res/drawable-xxxhdpi/bootsplash_logo.png +0 -0
- package/templates/native/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
- package/templates/native/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
- package/templates/native/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
- package/templates/native/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
- package/templates/native/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
- package/templates/native/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
- package/templates/native/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/templates/native/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- package/templates/native/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/templates/native/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
- package/templates/native/android/app/src/main/res/values/colors.xml +3 -0
- package/templates/native/android/app/src/main/res/values/strings.xml +3 -0
- package/templates/native/android/app/src/main/res/values/styles.xml +6 -0
- package/templates/native/android/build.gradle +33 -0
- package/templates/native/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/templates/native/android/gradle/wrapper/gradle-wrapper.properties +7 -0
- package/templates/native/android/gradle.properties +44 -0
- package/templates/native/android/gradlew +248 -0
- package/templates/native/android/gradlew.bat +98 -0
- package/templates/native/android/settings.gradle +10 -0
- package/templates/native/bootsplash-logo/angular/android/app/src/main/res/drawable-hdpi/bootsplash_logo.png +0 -0
- package/templates/native/bootsplash-logo/angular/android/app/src/main/res/drawable-mdpi/bootsplash_logo.png +0 -0
- package/templates/native/bootsplash-logo/angular/android/app/src/main/res/drawable-xhdpi/bootsplash_logo.png +0 -0
- package/templates/native/bootsplash-logo/angular/android/app/src/main/res/drawable-xxhdpi/bootsplash_logo.png +0 -0
- package/templates/native/bootsplash-logo/angular/android/app/src/main/res/drawable-xxxhdpi/bootsplash_logo.png +0 -0
- package/templates/native/bootsplash-logo/angular/ios/Canary/Images.xcassets/BootSplashLogo-498e55.imageset/logo-498e55.png +0 -0
- package/templates/native/bootsplash-logo/angular/ios/Canary/Images.xcassets/BootSplashLogo-498e55.imageset/logo-498e55@2x.png +0 -0
- package/templates/native/bootsplash-logo/angular/ios/Canary/Images.xcassets/BootSplashLogo-498e55.imageset/logo-498e55@3x.png +0 -0
- package/templates/native/bootsplash-logo/solid/android/app/src/main/res/drawable-hdpi/bootsplash_logo.png +0 -0
- package/templates/native/bootsplash-logo/solid/android/app/src/main/res/drawable-mdpi/bootsplash_logo.png +0 -0
- package/templates/native/bootsplash-logo/solid/android/app/src/main/res/drawable-xhdpi/bootsplash_logo.png +0 -0
- package/templates/native/bootsplash-logo/solid/android/app/src/main/res/drawable-xxhdpi/bootsplash_logo.png +0 -0
- package/templates/native/bootsplash-logo/solid/android/app/src/main/res/drawable-xxxhdpi/bootsplash_logo.png +0 -0
- package/templates/native/bootsplash-logo/solid/ios/Canary/Images.xcassets/BootSplashLogo-498e55.imageset/logo-498e55.png +0 -0
- package/templates/native/bootsplash-logo/solid/ios/Canary/Images.xcassets/BootSplashLogo-498e55.imageset/logo-498e55@2x.png +0 -0
- package/templates/native/bootsplash-logo/solid/ios/Canary/Images.xcassets/BootSplashLogo-498e55.imageset/logo-498e55@3x.png +0 -0
- package/templates/native/bootsplash-logo/svelte/android/app/src/main/res/drawable-hdpi/bootsplash_logo.png +0 -0
- package/templates/native/bootsplash-logo/svelte/android/app/src/main/res/drawable-mdpi/bootsplash_logo.png +0 -0
- package/templates/native/bootsplash-logo/svelte/android/app/src/main/res/drawable-xhdpi/bootsplash_logo.png +0 -0
- package/templates/native/bootsplash-logo/svelte/android/app/src/main/res/drawable-xxhdpi/bootsplash_logo.png +0 -0
- package/templates/native/bootsplash-logo/svelte/android/app/src/main/res/drawable-xxxhdpi/bootsplash_logo.png +0 -0
- package/templates/native/bootsplash-logo/svelte/ios/Canary/Images.xcassets/BootSplashLogo-498e55.imageset/logo-498e55.png +0 -0
- package/templates/native/bootsplash-logo/svelte/ios/Canary/Images.xcassets/BootSplashLogo-498e55.imageset/logo-498e55@2x.png +0 -0
- package/templates/native/bootsplash-logo/svelte/ios/Canary/Images.xcassets/BootSplashLogo-498e55.imageset/logo-498e55@3x.png +0 -0
- package/templates/native/bootsplash-logo/vue/android/app/src/main/res/drawable-hdpi/bootsplash_logo.png +0 -0
- package/templates/native/bootsplash-logo/vue/android/app/src/main/res/drawable-mdpi/bootsplash_logo.png +0 -0
- package/templates/native/bootsplash-logo/vue/android/app/src/main/res/drawable-xhdpi/bootsplash_logo.png +0 -0
- package/templates/native/bootsplash-logo/vue/android/app/src/main/res/drawable-xxhdpi/bootsplash_logo.png +0 -0
- package/templates/native/bootsplash-logo/vue/android/app/src/main/res/drawable-xxxhdpi/bootsplash_logo.png +0 -0
- package/templates/native/bootsplash-logo/vue/ios/Canary/Images.xcassets/BootSplashLogo-498e55.imageset/logo-498e55.png +0 -0
- package/templates/native/bootsplash-logo/vue/ios/Canary/Images.xcassets/BootSplashLogo-498e55.imageset/logo-498e55@2x.png +0 -0
- package/templates/native/bootsplash-logo/vue/ios/Canary/Images.xcassets/BootSplashLogo-498e55.imageset/logo-498e55@3x.png +0 -0
- package/templates/native/eslint.config.js +3 -0
- package/templates/native/ios/.xcode.env +11 -0
- package/templates/native/ios/Canary/AppDelegate.swift +48 -0
- package/templates/native/ios/Canary/BootSplash.storyboard +46 -0
- package/templates/native/ios/Canary/Colors.xcassets/BootSplashBackground-498e55.colorset/Contents.json +20 -0
- package/templates/native/ios/Canary/Images.xcassets/AppIcon.appiconset/Contents.json +53 -0
- package/templates/native/ios/Canary/Images.xcassets/BootSplashLogo-498e55.imageset/Contents.json +23 -0
- package/templates/native/ios/Canary/Images.xcassets/BootSplashLogo-498e55.imageset/logo-498e55.png +0 -0
- package/templates/native/ios/Canary/Images.xcassets/BootSplashLogo-498e55.imageset/logo-498e55@2x.png +0 -0
- package/templates/native/ios/Canary/Images.xcassets/BootSplashLogo-498e55.imageset/logo-498e55@3x.png +0 -0
- package/templates/native/ios/Canary/Images.xcassets/Contents.json +6 -0
- package/templates/native/ios/Canary/Info.plist +60 -0
- package/templates/native/ios/Canary/LaunchScreen.storyboard +47 -0
- package/templates/native/ios/Canary/PrivacyInfo.xcprivacy +37 -0
- package/templates/native/ios/Canary.xcodeproj/project.pbxproj +504 -0
- package/templates/native/ios/Canary.xcodeproj/xcshareddata/xcschemes/Canary.xcscheme +88 -0
- package/templates/native/ios/Canary.xcworkspace/contents.xcworkspacedata +10 -0
- package/templates/native/ios/Podfile +34 -0
- package/templates/native/package.json.fragment.json +22 -0
- package/templates/native/package.json.fragment.typescript.json +8 -0
- package/templates/styling/js/angular/css-modules/src/App.ts +25 -0
- package/templates/styling/js/angular/stylesheet/src/App.ts +26 -0
- package/templates/styling/js/react/css-modules/App.jsx +15 -0
- package/templates/styling/js/react/css-modules/App.tsx +15 -0
- package/templates/styling/js/react/stylesheet/App.jsx +19 -0
- package/templates/styling/js/react/stylesheet/App.tsx +19 -0
- package/templates/styling/js/solid/css-modules/App.jsx +15 -0
- package/templates/styling/js/solid/css-modules/App.tsx +15 -0
- package/templates/styling/js/solid/stylesheet/App.jsx +19 -0
- package/templates/styling/js/solid/stylesheet/App.tsx +19 -0
- package/templates/styling/js/svelte/css-modules/App.svelte +12 -0
- package/templates/styling/js/svelte/css-modules/App.typescript.svelte +12 -0
- package/templates/styling/js/svelte/stylesheet/App.svelte +15 -0
- package/templates/styling/js/svelte/stylesheet/App.typescript.svelte +15 -0
- package/templates/styling/js/vue-sfc/css-modules/App.typescript.vue +15 -0
- package/templates/styling/js/vue-sfc/css-modules/App.vue +15 -0
- package/templates/styling/js/vue-sfc/stylesheet/App.typescript.vue +18 -0
- package/templates/styling/js/vue-sfc/stylesheet/App.vue +18 -0
- package/templates/styling/js/vue-tsx/css-modules/App.jsx +16 -0
- package/templates/styling/js/vue-tsx/css-modules/App.tsx +16 -0
- package/templates/styling/js/vue-tsx/stylesheet/App.jsx +20 -0
- package/templates/styling/js/vue-tsx/stylesheet/App.tsx +20 -0
- package/templates/styling/navigation/angular/css-modules/src/DetailsScreen.ts +17 -0
- package/templates/styling/navigation/angular/css-modules/src/MenuScreen.ts +22 -0
- package/templates/styling/navigation/angular/stylesheet/src/DetailsScreen.ts +18 -0
- package/templates/styling/navigation/angular/stylesheet/src/MenuScreen.ts +23 -0
- package/templates/styling/navigation/react/css-modules/App.jsx +32 -0
- package/templates/styling/navigation/react/css-modules/App.tsx +32 -0
- package/templates/styling/navigation/react/stylesheet/App.jsx +36 -0
- package/templates/styling/navigation/react/stylesheet/App.tsx +36 -0
- package/templates/styling/navigation/solid/css-modules/App.jsx +32 -0
- package/templates/styling/navigation/solid/css-modules/App.tsx +32 -0
- package/templates/styling/navigation/solid/stylesheet/App.jsx +36 -0
- package/templates/styling/navigation/solid/stylesheet/App.tsx +36 -0
- package/templates/styling/navigation/svelte/css-modules/DetailsScreen.svelte +7 -0
- package/templates/styling/navigation/svelte/css-modules/DetailsScreen.typescript.svelte +7 -0
- package/templates/styling/navigation/svelte/css-modules/MenuScreen.svelte +13 -0
- package/templates/styling/navigation/svelte/css-modules/MenuScreen.typescript.svelte +13 -0
- package/templates/styling/navigation/svelte/stylesheet/DetailsScreen.svelte +11 -0
- package/templates/styling/navigation/svelte/stylesheet/DetailsScreen.typescript.svelte +11 -0
- package/templates/styling/navigation/svelte/stylesheet/MenuScreen.svelte +16 -0
- package/templates/styling/navigation/svelte/stylesheet/MenuScreen.typescript.svelte +16 -0
- package/templates/styling/navigation/vue-sfc/css-modules/DetailsScreen.typescript.vue +9 -0
- package/templates/styling/navigation/vue-sfc/css-modules/DetailsScreen.vue +9 -0
- package/templates/styling/navigation/vue-sfc/css-modules/MenuScreen.typescript.vue +15 -0
- package/templates/styling/navigation/vue-sfc/css-modules/MenuScreen.vue +15 -0
- package/templates/styling/navigation/vue-sfc/stylesheet/DetailsScreen.typescript.vue +13 -0
- package/templates/styling/navigation/vue-sfc/stylesheet/DetailsScreen.vue +13 -0
- package/templates/styling/navigation/vue-sfc/stylesheet/MenuScreen.typescript.vue +18 -0
- package/templates/styling/navigation/vue-sfc/stylesheet/MenuScreen.vue +18 -0
- package/templates/styling/navigation/vue-tsx/css-modules/App.jsx +34 -0
- package/templates/styling/navigation/vue-tsx/css-modules/App.tsx +34 -0
- package/templates/styling/navigation/vue-tsx/stylesheet/App.jsx +38 -0
- package/templates/styling/navigation/vue-tsx/stylesheet/App.tsx +38 -0
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@symbiote-native/cli",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Scaffold a new SymbioteNative app (React/Vue/Angular/Solid/Svelte, bare React Native, optional Expo-modules autolinking), or wire SymbioteNative into an existing bare RN app — the `@symbiote-native/cli new` companion to the manual steps in the root README's \"Try It In Your Own App\".",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/OneEyed1366/symbiote-native.git",
|
|
9
|
+
"directory": "packages/cli"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/OneEyed1366/symbiote-native/tree/master/packages/cli#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/OneEyed1366/symbiote-native/issues"
|
|
14
|
+
},
|
|
15
|
+
"author": "Andrey Prokopenko <psevdoproger@gmail.com>",
|
|
16
|
+
"type": "module",
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=22.11.0"
|
|
19
|
+
},
|
|
20
|
+
"main": "src/index.ts",
|
|
21
|
+
"module": "src/index.ts",
|
|
22
|
+
"types": "src/index.ts",
|
|
23
|
+
"exports": {
|
|
24
|
+
".": "./src/index.ts"
|
|
25
|
+
},
|
|
26
|
+
"bin": {
|
|
27
|
+
"symbiote-native-cli": "bundle.js"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"bundle.js",
|
|
31
|
+
"templates"
|
|
32
|
+
],
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@clack/prompts": "^1.7.0",
|
|
38
|
+
"@types/node": "^26.0.0",
|
|
39
|
+
"picocolors": "^1.1.1",
|
|
40
|
+
"rolldown": "1.2.0",
|
|
41
|
+
"typescript": "~6.0.0"
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"typecheck": "tsc --build",
|
|
45
|
+
"dev": "tsc --build && node build/index.js",
|
|
46
|
+
"build": "rolldown -c build.config.ts",
|
|
47
|
+
"format": "prettier --write \"src/**/*.ts\""
|
|
48
|
+
}
|
|
49
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import pc from 'picocolors';
|
|
3
|
+
import { parseArgv } from './cli.js';
|
|
4
|
+
import { runAdd } from './commands/add.js';
|
|
5
|
+
import { runNew } from './commands/new.js';
|
|
6
|
+
import { CliUsageError, NotSymbioteAppError } from './errors.js';
|
|
7
|
+
import { EXPO_PACKAGE_LAYERS } from './expo-package-layers.js';
|
|
8
|
+
// A static JSON import, not fs/createRequire: rolldown resolves and inlines it (relative to
|
|
9
|
+
// this SOURCE file) into bundle.js at build time, so the published artifact needs no
|
|
10
|
+
// package.json lookup at runtime at all — unlike a runtime `require('../package.json')`, which
|
|
11
|
+
// breaks the moment the bundle no longer sits one directory level away from it (see git history).
|
|
12
|
+
import pkg from '../package.json' with { type: 'json' };
|
|
13
|
+
|
|
14
|
+
function printHelp(): void {
|
|
15
|
+
const expoPackageFlags = EXPO_PACKAGE_LAYERS.map(
|
|
16
|
+
layer => `--${layer.id}`,
|
|
17
|
+
).join(', ');
|
|
18
|
+
console.log(`@symbiote-native/cli — scaffold a SymbioteNative app, or add it to an existing one.
|
|
19
|
+
|
|
20
|
+
Usage:
|
|
21
|
+
npx @symbiote-native/cli new <app-name> [--framework react|vue|angular|solid|svelte] [--vue-flavor tsx|sfc]
|
|
22
|
+
[--javascript] [--force] [--bundle-id com.example.app]
|
|
23
|
+
[--styling css|css-modules|scss|less|stylus|stylesheet]
|
|
24
|
+
[--navigation] [--expo-modules] [--testing] [--splash-screen] [--slider] [--pm npm|pnpm|yarn]
|
|
25
|
+
[--<expo-package> ...] (one per Expo-backed package, implies --expo-modules)
|
|
26
|
+
npx @symbiote-native/cli add [--navigation] [--expo-modules] [--testing] [--splash-screen] [--slider]
|
|
27
|
+
[--<expo-package> ...] [--force] [--pm npm|pnpm|yarn]
|
|
28
|
+
(run inside an existing @symbiote-native/* app)
|
|
29
|
+
|
|
30
|
+
npx @symbiote-native/cli --version print the CLI version
|
|
31
|
+
npx @symbiote-native/cli --help print this message
|
|
32
|
+
|
|
33
|
+
<expo-package> flags: ${expoPackageFlags}
|
|
34
|
+
|
|
35
|
+
Flags left out of either command are asked for interactively.`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function main(): Promise<void> {
|
|
39
|
+
const parsed = parseArgv(process.argv.slice(2));
|
|
40
|
+
|
|
41
|
+
switch (parsed.kind) {
|
|
42
|
+
case 'new':
|
|
43
|
+
await runNew(parsed);
|
|
44
|
+
return;
|
|
45
|
+
case 'add':
|
|
46
|
+
await runAdd(parsed);
|
|
47
|
+
return;
|
|
48
|
+
case 'help':
|
|
49
|
+
printHelp();
|
|
50
|
+
return;
|
|
51
|
+
case 'version':
|
|
52
|
+
console.log(pkg.version);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
main().catch((error: unknown) => {
|
|
58
|
+
if (error instanceof CliUsageError) {
|
|
59
|
+
console.error(pc.red(`@symbiote-native/cli: ${error.message}`));
|
|
60
|
+
process.exitCode = 1;
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (error instanceof NotSymbioteAppError) {
|
|
64
|
+
console.error(pc.red(`@symbiote-native/cli: ${error.message}`));
|
|
65
|
+
process.exitCode = 1;
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
console.error(pc.red('@symbiote-native/cli: unexpected error'), error);
|
|
69
|
+
process.exitCode = 1;
|
|
70
|
+
});
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
**Status: `new` is wired for the base + `--navigation`/`--expo-modules` layers.** `src/generate.ts`
|
|
2
|
+
copies `native/` + `js/<framework>` + any selected `templates/layers/*` onto the target
|
|
3
|
+
directory via `src/utils/render-template.ts` (ported from create-vue: `package.json` merges,
|
|
4
|
+
`.gitignore` appends, everything else overwrites). `src/utils/apply-app-identity.ts` then substitutes the real app name/bundle id for the
|
|
5
|
+
templates' `"Canary"`/`com.canary` placeholders on the copied tree. `src/commands/add.ts` is
|
|
6
|
+
still stubbed — see `../README.md`'s "Design decisions" section for the full v1 scope and what's
|
|
7
|
+
deferred (`--splash-screen`, `add`).
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
templates/
|
|
11
|
+
native/{ios,android,Gemfile}/ # ONE framework-agnostic Xcode/Gradle project shell + CocoaPods
|
|
12
|
+
# config, shared by every framework — SymbioteNative never
|
|
13
|
+
# touches native/, so the generated app's ios/ and android/
|
|
14
|
+
# folders are identical regardless of --framework (see
|
|
15
|
+
# <native_core_is_untouched> in the root CLAUDE.md).
|
|
16
|
+
js/{react,vue-tsx,vue-sfc,angular,solid,svelte}/ # Per-framework JS-level overlay: index.js
|
|
17
|
+
# (registerRunnable, not registerComponent), metro.config.js,
|
|
18
|
+
# tsconfig, and a package.json.fragment.json dependency
|
|
19
|
+
# fragment (@symbiote-native/<fw> + react-native/react + the
|
|
20
|
+
# framework's own runtime). Vue has two real flavors, TSX and
|
|
21
|
+
# SFC — `npx @symbiote-native/cli new --framework vue` prompts for
|
|
22
|
+
# `--vue-flavor tsx|sfc` (default sfc) to pick between them.
|
|
23
|
+
layers/{expo-modules,navigation,testing}/ # Optional overlays applied after native/ + js/<fw>.
|
|
24
|
+
# expo-modules is package.json.fragment.json only; navigation
|
|
25
|
+
# also carries app/<framework>/App.<ext> — a 2-screen Stack
|
|
26
|
+
# demo overwriting the base App — see templates/layers/README.md.
|
|
27
|
+
styling/{js,navigation}/<framework>/<option>/ # --styling css-modules|stylesheet overrides,
|
|
28
|
+
# applied by src/utils/apply-styling.ts AFTER js/<fw> and the
|
|
29
|
+
# navigation layer. Deliberately NOT nested inside js/<fw> or
|
|
30
|
+
# layers/navigation/app/<fw> — render-template.ts copies a
|
|
31
|
+
# source directory recursively with no exclusion, so nesting an
|
|
32
|
+
# override folder inside a tree that's already copied wholesale
|
|
33
|
+
# ships it into every generated app regardless of --styling
|
|
34
|
+
# (a real bug, fixed 2026-09-17 — see ../README.md).
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Every `js/<framework>` also ships a base `App.<ext>` (a "Welcome to SymbioteNative!" + tap
|
|
38
|
+
counter, no navigation) — the one thing that actually makes a scaffolded app RUN instead of
|
|
39
|
+
crashing on `import App from './App'` resolving to nothing (fixed 2026-09-15, see git history —
|
|
40
|
+
the copy/merge mechanism landed before this file did).
|
|
41
|
+
|
|
42
|
+
**Every App file is TWO independently-maintained variants, never one derived from the other.**
|
|
43
|
+
react/vue-tsx/solid: `App.tsx` + `App.jsx`, picked by filename (`render-template.ts`'s
|
|
44
|
+
`TYPESCRIPT_ONLY_FILENAMES`/`JAVASCRIPT_ONLY_FILENAMES`). vue-sfc/svelte can't do that — their
|
|
45
|
+
language is an internal `<script lang="ts">` attribute, so both variants would collide on the same
|
|
46
|
+
extension (`App.vue`/`App.svelte`) — instead the TypeScript half is a `App.typescript.vue` /
|
|
47
|
+
`App.typescript.svelte` sibling that renders to the plain name only when TypeScript is on (same
|
|
48
|
+
`.typescript.` infix mechanism as `package.json.fragment.typescript.json`, generalized
|
|
49
|
+
2026-09-15). Angular has no JS half at all (AOT requires TypeScript). The two variants read
|
|
50
|
+
identically today because neither has a REAL type annotation yet worth diverging on — a
|
|
51
|
+
copy-with-renamed-extension looked equivalent for the same reason and was rejected: the moment
|
|
52
|
+
one side gains an actual type, that copy would silently ship broken syntax into the other mode.
|
|
53
|
+
|
|
54
|
+
Every `README.md` inside `templates/**` (this file included) documents the template folder for
|
|
55
|
+
maintainers — `renderTemplate` skips copying any file named `README.md` into a generated app.
|
|
56
|
+
|
|
57
|
+
## Why `native/` is our own vendored shell, not `@react-native-community/cli init`
|
|
58
|
+
|
|
59
|
+
Delegating native scaffolding to the upstream RN CLI would make `@symbiote-native/cli new` break
|
|
60
|
+
on every RN-CLI release that changes its generated project shape — outside this repo's
|
|
61
|
+
control. Vendoring our own fork trades that drift risk for an explicit maintenance cost (this
|
|
62
|
+
package owns keeping `native/` current against new RN/Xcode/Gradle versions), which is the
|
|
63
|
+
deliberate choice here.
|
|
64
|
+
|
|
65
|
+
## What's real vs. still missing
|
|
66
|
+
|
|
67
|
+
Real: `new` copies `native/` + `js/<framework>` + selected `layers/*` onto a fresh directory,
|
|
68
|
+
merges `package.json` (`deepMerge` + `sortDependencies`, ported from create-vue), appends
|
|
69
|
+
`.gitignore`, skips every template-folder `README.md`, and substitutes the real app name +
|
|
70
|
+
bundle id for every `"Canary"`/`com.canary` placeholder (folder renames, Xcode project/scheme/
|
|
71
|
+
workspace names, Android package directory + `namespace`/`applicationId`, `app.json`, Info.plist,
|
|
72
|
+
Podfile target — see `src/utils/apply-app-identity.ts`; case-sensitive, so it never touches an
|
|
73
|
+
unrelated lowercase "canary" in prose/comments). Every framework ships a working base App and,
|
|
74
|
+
with `--navigation`, a 2-screen Stack demo — verified end-to-end against real installs, including
|
|
75
|
+
a real `ngc` AOT build for Angular both with and without `--navigation` (2026-09-15; that pass
|
|
76
|
+
also caught and fixed two stale `@symbiote-native/*` version pins that broke `npm install` under
|
|
77
|
+
ERESOLVE — every such pin is now `"latest"`, see `templates/layers/README.md`). Verified against 5
|
|
78
|
+
combinations (react+expo+navigation, vue-sfc+navigation, solid, svelte+expo, angular) — see
|
|
79
|
+
`../README.md`'s "Design decisions" section.
|
|
80
|
+
|
|
81
|
+
Missing, on purpose:
|
|
82
|
+
|
|
83
|
+
- **No `--splash-screen` toggle.** BootSplash is unconditionally baked into `native/` — making
|
|
84
|
+
it optional needs `@expo/config-plugins`-based generation, not hand-edited `.pbxproj`. See
|
|
85
|
+
`../README.md`'s "Design decisions" section for the precedent (`react-native-bootsplash`'s own
|
|
86
|
+
`generate.ts`) and why it's a separate task.
|
|
87
|
+
- **`add` is still stubbed.** `new`'s copy/merge mechanism was the prerequisite; `add`'s
|
|
88
|
+
retrofit-into-existing-project path (merging into a non-empty `package.json`) comes next —
|
|
89
|
+
including re-running `apply-app-identity` against an existing project's current name/bundle id
|
|
90
|
+
rather than the `"Canary"` placeholder.
|
|
91
|
+
- **No general EJS/data-file templating.** `renderTemplate` does a plain copy-or-merge; the one
|
|
92
|
+
parameterized value (app identity) is handled by a dedicated post-pass instead, since it's the
|
|
93
|
+
only thing in `templates/` that varies per scaffold.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# `templates/js/angular`
|
|
2
|
+
|
|
3
|
+
Per-framework JS-level overlay for a generated Angular app, populated from `examples/angular`
|
|
4
|
+
(the real, working Angular canary) — see `../../README.md` for the overall templates layout and
|
|
5
|
+
the `angular-adapter-build` skill for why Angular's build pipeline looks like this.
|
|
6
|
+
|
|
7
|
+
## What was copied, and why
|
|
8
|
+
|
|
9
|
+
| File | Why it belongs in the seam |
|
|
10
|
+
|---|---|
|
|
11
|
+
| `index.js` | The bootstrap entry every Angular app needs verbatim: `bootstrapApplication(AppComponent, { appName })` imported from `@symbiote-native/angular/bootstrap`. It imports `./build/angular/src/App` and `./app.json`'s `name` — both paths hold regardless of what `AppComponent` itself renders, so this file needs zero changes per-app. |
|
|
12
|
+
| `metro.config.js` | Wires the two things every Angular app needs from Metro: `@symbiote-native/angular/metro-css-parser` as the CSS transformer, and `withSymbioteAngularMetroConfig` (the ngc-outDir resolveRequest + sourceExts). Framework-agnostic beyond that — identical regardless of app content. |
|
|
13
|
+
| `babel.config.js` | The two Angular-specific Babel plugins every app needs in this exact order: `@symbiote-native/angular/babel-register-composed` (must run before the linker) then `@symbiote-native/angular/babel-linker` (Stage B of AOT — turns ngc's partial-Ivy output into full Ivy before Hermes sees it), plus the standard `DEBUG` env-flag inliner shared with the other framework templates. |
|
|
14
|
+
| `tsconfig.json` | The editor/tsserver-facing config (DOM lib for `@angular/core`'s ambient types, the `@symbiote-native/css-parser` TS plugin) — mirrors the real AOT build config so IDE diagnostics match `ngc`'s. |
|
|
15
|
+
| `tsconfig.angular.json` | The actual `ngc` build config: `angularCompilerOptions.basePath: "src"` (the EMFILE fix — see `angular-adapter-build` skill §3a, `ngc --watch`'s chokidar recurses `basePath` and would otherwise hit `ios/`/`android/` as watch-root siblings), `outDir: "build/angular"`, and `"files": ["src/App.ts", "src/css.d.ts"]`. This is why the JS source tree below is nested under `src/` rather than flat like the React/Vue templates. |
|
|
16
|
+
| `app.json` | `{ name, displayName }` read by `index.js`. Copied verbatim from the example — see the parameterization note below. |
|
|
17
|
+
| `.watchmanconfig` | Empty `{}`, but Watchman needs the file present to establish a watch root. Identical for every app. |
|
|
18
|
+
| `.gitignore` | Standard bare-RN-app ignore list (Xcode/Gradle build output, CocoaPods, Metro health-check files, coverage, Yarn PnP). Same for every framework — the React template already carries an equivalent copy for the same reason (`native/` itself ships no `.gitignore`). |
|
|
19
|
+
| `src/css.d.ts` | Ambient module declarations for `import './X.css'` and `.module.css` — pure TypeScript scaffolding with no app-specific content (`declare module '*.css'` / the generic `.module.css` fallback typed via `Record<string, string>`). Lives under `src/` (not flat, unlike the React template's `css.d.ts`) because `tsconfig.angular.json`'s `files` array names `src/css.d.ts` explicitly — the nesting is structural, not a style choice. |
|
|
20
|
+
|
|
21
|
+
## What was deliberately excluded, and the `src/` split judgment call
|
|
22
|
+
|
|
23
|
+
Not copied, and why:
|
|
24
|
+
|
|
25
|
+
- **`src/App.ts` + `src/App.css`** — the app's root component: the `Stack`/`ScreenDirective`
|
|
26
|
+
navigator wiring, every screen import, header options per route, splash-screen `hide()` call.
|
|
27
|
+
This is app-authored content a real app replaces entirely with its own root component (the
|
|
28
|
+
`generate.ts` implementation will need to emit a minimal placeholder `App.ts`, not this one).
|
|
29
|
+
- **`src/components/*` and `src/screens/*`** — the canary's demo surface (ActivityIndicator/
|
|
30
|
+
Switch/ScrollView/Animated/ResponderDemo/etc. sections, the menu + tour screens). Entirely
|
|
31
|
+
demo content, zero bootstrap value.
|
|
32
|
+
- **`src/navigation-lines.ts`, `src/navigation-linking.ts`, `src/routes.ts`,
|
|
33
|
+
`src/components/event-utils.ts`** — demo-specific navigation config (route name constants,
|
|
34
|
+
deep-linking config, a color palette for the tour) and a shared event-formatting helper used
|
|
35
|
+
only by the demo screens.
|
|
36
|
+
- **`e2e/`, `assets/`, `package-lock.json`** — per the task brief: Detox e2e specs are
|
|
37
|
+
app-specific test content, `assets/` holds demo images, and a lockfile is never templated
|
|
38
|
+
(the generated app gets a fresh install).
|
|
39
|
+
|
|
40
|
+
**The `src/` judgment call**: `examples/angular`'s root has no `App.ts`-equivalent — unlike
|
|
41
|
+
React/Vue's flat `App.tsx` at the app root, Angular's whole source tree (moved 2026-07-14,
|
|
42
|
+
documented in `angular-adapter-build` skill §3a) lives under `src/` specifically to keep
|
|
43
|
+
`ngc --watch`'s recursive chokidar watch (rooted at `angularCompilerOptions.basePath`) away from
|
|
44
|
+
`ios/`/`android/`'s tens of thousands of files as watch-root siblings. That makes the split
|
|
45
|
+
mechanical rather than a judgment call for most of `src/`: everything in it is either (a) the
|
|
46
|
+
demo screens/components tree (excluded, app-authored) or (b) `css.d.ts`, a file with zero
|
|
47
|
+
app-specific content that happens to sit in `src/` only because the build config's `basePath`
|
|
48
|
+
fix requires the whole compiled tree to live there. `css.d.ts` is the one file that's
|
|
49
|
+
"bootstrap despite being under `src/`," which is why it's called out explicitly in the table
|
|
50
|
+
above rather than assumed excluded along with the rest of the directory.
|
|
51
|
+
|
|
52
|
+
## `package.json.fragment.json`
|
|
53
|
+
|
|
54
|
+
A dependency **fragment** (not a full `package.json` — this directory isn't an npm package
|
|
55
|
+
itself) listing only the SymbioteNative + Angular packages a generated app's `package.json`
|
|
56
|
+
needs, plus the npm scripts `ngc`/Metro wiring requires. Versions pulled verbatim from
|
|
57
|
+
`examples/angular/package.json`'s real, working set:
|
|
58
|
+
|
|
59
|
+
- **`dependencies`**: `@symbiote-native/angular` (the adapter) and `@symbiote-native/engine`
|
|
60
|
+
(its `peerDependencies` require `@symbiote-native/engine >=0.1.7` explicitly, same as
|
|
61
|
+
`react-native >=0.86` — see `<react_native_is_an_explicit_top_level_peer>` in the root
|
|
62
|
+
`CLAUDE.md`: a peer dependency of the adapter must be an explicit top-level dependency of the
|
|
63
|
+
consuming app, not left to transitive resolution), `@angular/core`/`@angular/common`/
|
|
64
|
+
`@angular/compiler` (the example pins all three as direct `dependencies`, not just `core`),
|
|
65
|
+
`react-native`, and `react` (a `react-native` peer requirement regardless of JS framework).
|
|
66
|
+
- **`devDependencies`**: `@angular/compiler-cli` (ships the `ngc` binary the `ng:build` script
|
|
67
|
+
calls — declared explicitly rather than relied on as a transitive dependency of
|
|
68
|
+
`@symbiote-native/angular`, matching what the real example does) and `@babel/core` pinned to
|
|
69
|
+
`^7` (the Angular linker's `assertVersion(7)` hard requirement — see `angular-adapter-build`
|
|
70
|
+
skill §1; Babel 8, ESM-only, is explicitly incompatible).
|
|
71
|
+
- **`scripts`**: `ng:build` (`ngc -p tsconfig.angular.json` — the one-shot AOT compile),
|
|
72
|
+
`dev`/`start` (`symbiote-angular-dev [--reset-cache]` — see the wiring-gap note below), and
|
|
73
|
+
`android`/`ios` (`ng:build` then `react-native run-<platform>`, since the compiled
|
|
74
|
+
`build/angular/` output must exist before Metro can serve it).
|
|
75
|
+
|
|
76
|
+
Left out on purpose: `@symbiote-native/navigation`, `@symbiote-native/slider`,
|
|
77
|
+
`@symbiote-native/splash-screen`, `@symbiote-native/android`, and `@symbiote-native/react` —
|
|
78
|
+
all real dependencies of `examples/angular`'s package.json, but only because the canary *demos*
|
|
79
|
+
navigation, the slider wrapper, and the splash-screen module. None of those are needed to boot
|
|
80
|
+
a bare Angular app against the engine; a generated app adds them itself if/when it needs that
|
|
81
|
+
functionality. Generic bare-RN-app tooling (`@react-native-community/cli`, `@react-native/*`,
|
|
82
|
+
`eslint`, `jest`, `detox`, `prettier`, `typescript`, `@types/*`) is also left out — it isn't
|
|
83
|
+
SymbioteNative/Angular-specific and belongs to whatever base scaffold `templates/native` or a
|
|
84
|
+
shared cross-framework fragment eventually supplies, not this per-framework fragment.
|
|
85
|
+
|
|
86
|
+
## App-name / bundle-id parameterization — not yet done
|
|
87
|
+
|
|
88
|
+
`app.json`'s `name`/`displayName` are still `"Canary"`/`"Canary"`, the literal value from
|
|
89
|
+
`examples/angular`. Per the task brief this is explicitly out of scope for this pass — no
|
|
90
|
+
placeholder/templating scheme was invented here. Parameterizing it (and wiring the app name the
|
|
91
|
+
`new` command's user already provides via its `<app-name>` argument) is real follow-up work for
|
|
92
|
+
`generate.ts`, which today still throws `NotImplementedCommandError` for both `new` and `add`.
|
|
93
|
+
|
|
94
|
+
## The `ngc --watch`-alongside-Metro wiring gap
|
|
95
|
+
|
|
96
|
+
What a generated app needs to reproduce, already captured in the copied files:
|
|
97
|
+
|
|
98
|
+
- `dev`/`start` calling `symbiote-angular-dev` (from `@symbiote-native/angular`'s `bin`, see
|
|
99
|
+
`package.json.fragment.json`'s `scripts`) — this is the shared launcher
|
|
100
|
+
(`adapters/angular/bin/symbiote-angular-dev.cjs`) that runs an initial `ngc` build, then spawns
|
|
101
|
+
`ngc -p tsconfig.angular.json --watch` as a background process and `react-native start` as the
|
|
102
|
+
sole foreground process (so Metro's interactive `r`/`j`/`d` keypresses keep working — see
|
|
103
|
+
`angular-adapter-build` skill §3). Nothing app-specific to wire here: the launcher already
|
|
104
|
+
reads `tsconfig.angular.json` from the app's own directory.
|
|
105
|
+
- `ng:build`/`android`/`ios` running a one-shot `ngc` compile before Metro/the native build ever
|
|
106
|
+
sees the app, since `index.js` imports the *compiled* `./build/angular/src/App`, never the
|
|
107
|
+
`.ts` source directly.
|
|
108
|
+
|
|
109
|
+
**What's genuinely unsolved by this pass**: how `@symbiote-native/cli new`/`add`'s actual generation
|
|
110
|
+
logic wires `package.json.fragment.json`'s `scripts` block into a fresh project's
|
|
111
|
+
`package.json` — i.e. whether `generate.ts` merges this fragment's `scripts` keys directly, how
|
|
112
|
+
a naming collision with a user's existing `add`-target `package.json` scripts would be resolved,
|
|
113
|
+
and whether `symbiote-angular-dev`'s `--pm`-agnostic assumptions (it shells out to `ngc`/
|
|
114
|
+
`react-native` directly, not through a package-manager `run` wrapper) hold for every `--pm`
|
|
115
|
+
value `@symbiote-native/cli` supports (`npm`/`pnpm`/`yarn`). None of that is implemented anywhere yet
|
|
116
|
+
— `commands/new.ts` and `commands/add.ts` still throw `NotImplementedCommandError` before
|
|
117
|
+
reaching a template-copy step at all.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
|
|
2
|
+
// Inline `process.env.DEBUG` at bundle time so @symbiote diagnostic logs can be toggled
|
|
3
|
+
// from the shell:
|
|
4
|
+
// DEBUG=1 pnpm start --reset-cache
|
|
5
|
+
const debugFlag = process.env.DEBUG === '1' ? '1' : '0';
|
|
6
|
+
|
|
7
|
+
function inlineDebugFlag({ types: t }) {
|
|
8
|
+
return {
|
|
9
|
+
name: 'inline-debug-flag',
|
|
10
|
+
visitor: {
|
|
11
|
+
MemberExpression(path) {
|
|
12
|
+
if (path.matchesPattern('process.env.DEBUG')) {
|
|
13
|
+
path.replaceWith(t.stringLiteral(debugFlag));
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
module.exports = {
|
|
22
|
+
presets: ['module:@react-native/babel-preset'],
|
|
23
|
+
plugins: [
|
|
24
|
+
// Must run BEFORE the linker below: reads `selector` off the still-partial
|
|
25
|
+
// ɵɵngDeclareComponent(...) shape and auto-calls registerComposedComponent for every
|
|
26
|
+
// composed component in the bundle — see the angular-adapter-build skill.
|
|
27
|
+
require('@symbiote-native/angular/babel-register-composed'),
|
|
28
|
+
// Stage B of Angular AOT: Metro sees the partial-Ivy JS emitted by `pnpm ng:build`;
|
|
29
|
+
// @symbiote-native/angular's linker turns every ɵɵngDeclareComponent into full Ivy before
|
|
30
|
+
// Hermes sees it.
|
|
31
|
+
require('@symbiote-native/angular/babel-linker'),
|
|
32
|
+
inlineDebugFlag,
|
|
33
|
+
],
|
|
34
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @format
|
|
3
|
+
*
|
|
4
|
+
* Symbiote Angular canary entry. bootstrapApplication wires the native-host seams and RN's own
|
|
5
|
+
* AppRegistry, then registers the root component — same entry point the other canaries use.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { bootstrapApplication } from '@symbiote-native/angular/bootstrap';
|
|
9
|
+
import { AppComponent } from './build/angular/src/App';
|
|
10
|
+
import { name as appName } from './app.json';
|
|
11
|
+
|
|
12
|
+
bootstrapApplication(AppComponent, { appName });
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
|
|
2
|
+
const { withSymbioteAngularMetroConfig } = require('@symbiote-native/angular/metro-config');
|
|
3
|
+
|
|
4
|
+
const projectRoot = __dirname;
|
|
5
|
+
|
|
6
|
+
const defaultConfig = getDefaultConfig(projectRoot);
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Angular is the one adapter that needs a pre-Metro compile step: ngc writes partial-Ivy JS,
|
|
10
|
+
* then Babel's Angular linker plugin (babel.config.js) runs inside Metro and turns that
|
|
11
|
+
* partial output into full Ivy. @symbiote-native/angular and @symbiote-native/slider build this
|
|
12
|
+
* themselves via their own `prepare` script (runs automatically on `npm install`) and point
|
|
13
|
+
* their package.json `exports`'s "react-native" condition straight at it — Metro's own
|
|
14
|
+
* package-exports resolution (on by default: @react-native/metro-config sets
|
|
15
|
+
* unstable_enablePackageExports + conditionNames ['react-native']) picks that up with no
|
|
16
|
+
* custom resolveRequest needed here. @symbiote-native/* resolve as ordinary npm packages from
|
|
17
|
+
* this app's own node_modules (examples/* is a standalone npm install, decoupled from the
|
|
18
|
+
* monorepo's pnpm workspace — see pnpm-workspace.yaml).
|
|
19
|
+
*
|
|
20
|
+
* @type {import('@react-native/metro-config').MetroConfig}
|
|
21
|
+
*/
|
|
22
|
+
const config = {
|
|
23
|
+
// Compile standalone .css/.module.css imports on the way into the bundle —
|
|
24
|
+
// @symbiote-native/angular ships the transformer itself, so no local wiring file is needed
|
|
25
|
+
// (same framework-agnostic path the React and Vue examples use via their own adapter's
|
|
26
|
+
// ./metro-css-parser export). Angular has no compiler-plugin conflict here: the ngc/linker
|
|
27
|
+
// pipeline (see the block comment above) only ever sees .ts files, never .css.
|
|
28
|
+
transformer: {
|
|
29
|
+
babelTransformerPath: require.resolve('@symbiote-native/angular/metro-css-parser'),
|
|
30
|
+
},
|
|
31
|
+
resolver: {
|
|
32
|
+
// sourceExts + the ngc-outDir CSS-redirect resolveRequest — see
|
|
33
|
+
// adapters/angular/metro-config.cjs for the full mechanism.
|
|
34
|
+
...withSymbioteAngularMetroConfig(defaultConfig, projectRoot).resolver,
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
module.exports = mergeConfig(defaultConfig, config);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"dependencies": {
|
|
3
|
+
"@symbiote-native/android": "latest",
|
|
4
|
+
"@symbiote-native/angular": "latest",
|
|
5
|
+
"@symbiote-native/engine": "latest",
|
|
6
|
+
"@angular/core": "^22",
|
|
7
|
+
"@angular/common": "^22",
|
|
8
|
+
"@angular/compiler": "^22",
|
|
9
|
+
"@angular/forms": "^22",
|
|
10
|
+
"rxjs": "^7.8.1",
|
|
11
|
+
"react-native": "0.86.0",
|
|
12
|
+
"react": "19.2.3"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@angular/compiler-cli": "^22",
|
|
16
|
+
"@react-native/babel-preset": "0.86.0",
|
|
17
|
+
"@react-native/metro-config": "0.86.0"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"lint": "eslint .",
|
|
21
|
+
"ng:build": "ngc -p tsconfig.angular.json",
|
|
22
|
+
"dev": "symbiote-angular-dev --reset-cache",
|
|
23
|
+
"start": "symbiote-angular-dev",
|
|
24
|
+
"android": "ngc -p tsconfig.angular.json && react-native run-android",
|
|
25
|
+
"ios": "ngc -p tsconfig.angular.json && react-native run-ios",
|
|
26
|
+
"pretypecheck": "css-dts .",
|
|
27
|
+
"typecheck": "ngc -p tsconfig.angular.json --noEmit"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--ink: #0b1622;
|
|
3
|
+
--paper: #13243a;
|
|
4
|
+
--mist: #41506a;
|
|
5
|
+
--chalk: #cbd5e1;
|
|
6
|
+
--chalk-bright: #ffffff;
|
|
7
|
+
--brand: #dd0031;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.screen {
|
|
11
|
+
flex: 1;
|
|
12
|
+
background-color: var(--ink);
|
|
13
|
+
align-items: center;
|
|
14
|
+
justify-content: center;
|
|
15
|
+
gap: 24px;
|
|
16
|
+
padding: 24px 32px;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.brand-row {
|
|
20
|
+
flex-direction: row;
|
|
21
|
+
align-items: center;
|
|
22
|
+
gap: 28px;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.brand-logo {
|
|
26
|
+
height: 64px;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/* aspect-ratio matches each source PNG's real pixel proportions — a shared square box would
|
|
30
|
+
stretch them off their real shape. */
|
|
31
|
+
.brand-logo-react {
|
|
32
|
+
aspect-ratio: 1.0977;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.brand-logo-angular {
|
|
36
|
+
aspect-ratio: 0.9463;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.plus-icon {
|
|
40
|
+
width: 48px;
|
|
41
|
+
height: 48px;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.title {
|
|
45
|
+
color: var(--chalk-bright);
|
|
46
|
+
font-size: 22px;
|
|
47
|
+
font-weight: bold;
|
|
48
|
+
text-align: center;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.subtitle {
|
|
52
|
+
color: var(--chalk);
|
|
53
|
+
font-size: 14px;
|
|
54
|
+
text-align: center;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.counter-card {
|
|
58
|
+
align-items: center;
|
|
59
|
+
gap: 4px;
|
|
60
|
+
padding: 20px 28px;
|
|
61
|
+
border-radius: 16px;
|
|
62
|
+
background-color: var(--paper);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.counter-label {
|
|
66
|
+
color: var(--mist);
|
|
67
|
+
font-size: 12px;
|
|
68
|
+
letter-spacing: 1px;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.counter-value {
|
|
72
|
+
color: var(--brand);
|
|
73
|
+
font-size: 32px;
|
|
74
|
+
font-weight: bold;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.button-primary {
|
|
78
|
+
align-items: center;
|
|
79
|
+
justify-content: center;
|
|
80
|
+
border-radius: 12px;
|
|
81
|
+
padding: 14px 22px;
|
|
82
|
+
background-color: var(--brand);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.button-primary-text {
|
|
86
|
+
color: var(--chalk-bright);
|
|
87
|
+
font-size: 15px;
|
|
88
|
+
font-weight: bold;
|
|
89
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Component, signal } from '@angular/core';
|
|
2
|
+
import { SYMBIOTE_ELEMENTS } from '@symbiote-native/angular';
|
|
3
|
+
import './App.css';
|
|
4
|
+
|
|
5
|
+
@Component({
|
|
6
|
+
selector: 'symbiote-angular-app',
|
|
7
|
+
standalone: true,
|
|
8
|
+
imports: [SYMBIOTE_ELEMENTS],
|
|
9
|
+
template: `
|
|
10
|
+
<safe-area-view class="screen">
|
|
11
|
+
<view class="brand-row">
|
|
12
|
+
<image class="brand-logo brand-logo-react" resizeMode="contain" [source]="reactNativeLogo"></image>
|
|
13
|
+
<image class="plus-icon" resizeMode="contain" [source]="plusIcon"></image>
|
|
14
|
+
<image class="brand-logo brand-logo-angular" resizeMode="contain" [source]="angularLogo"></image>
|
|
15
|
+
</view>
|
|
16
|
+
|
|
17
|
+
<text class="title">Welcome to SymbioteNative!</text>
|
|
18
|
+
<text class="subtitle">Framework-agnostic React Native, driven by Angular.</text>
|
|
19
|
+
|
|
20
|
+
<view class="counter-card">
|
|
21
|
+
<text class="counter-label">TAPS</text>
|
|
22
|
+
<text class="counter-value">{{ count() }}</text>
|
|
23
|
+
</view>
|
|
24
|
+
|
|
25
|
+
<pressable class="button-primary" (press)="increment()">
|
|
26
|
+
<text class="button-primary-text">Tap me</text>
|
|
27
|
+
</pressable>
|
|
28
|
+
</safe-area-view>
|
|
29
|
+
`,
|
|
30
|
+
})
|
|
31
|
+
export class AppComponent {
|
|
32
|
+
readonly count = signal(0);
|
|
33
|
+
readonly reactNativeLogo = require('./assets/react-native-logo.png');
|
|
34
|
+
readonly plusIcon = require('./assets/plus-icon.png');
|
|
35
|
+
readonly angularLogo = require('./assets/angular-logo.png');
|
|
36
|
+
|
|
37
|
+
increment(): void {
|
|
38
|
+
this.count.set(this.count() + 1);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Ambient module for a plain, side-effect-only `.css` import (`import './App.css'`) —
|
|
2
|
+
// @symbiote-native/css-parser compiles it at build time (Metro's babelTransformerPath, see
|
|
3
|
+
// metro-css-transformer.js) into a registerStyles() call; there's no runtime export to type.
|
|
4
|
+
declare module '*.css';
|
|
5
|
+
|
|
6
|
+
// Same shape for the three optional preprocessor sources — css-parser reduces each to plain CSS
|
|
7
|
+
// before compiling, so a side-effect import of one is indistinguishable downstream from a `.css`
|
|
8
|
+
// one.
|
|
9
|
+
declare module '*.scss';
|
|
10
|
+
declare module '*.sass';
|
|
11
|
+
declare module '*.less';
|
|
12
|
+
declare module '*.styl';
|
|
13
|
+
|
|
14
|
+
// Generic (non-literal) fallback for a `.module.css` import — used by `tsc` outside a file that
|
|
15
|
+
// already has its own generated `Card.module.css.d.ts` (see `css-dts`, wired to `pretypecheck`;
|
|
16
|
+
// a real per-file `.d.ts` takes priority over this wildcard once generated). The
|
|
17
|
+
// `@symbiote-native/angular/typescript-plugin` entry in tsconfig.json's `compilerOptions.plugins` gives
|
|
18
|
+
// the SAME per-file literal-key typing live in the editor — plugins never load for a standalone
|
|
19
|
+
// `tsc`/CI run, which is why both mechanisms exist side by side.
|
|
20
|
+
declare module '*.module.css' {
|
|
21
|
+
const styles: Record<string, string>;
|
|
22
|
+
export default styles;
|
|
23
|
+
}
|