devendra-skill-package 1.0.2
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/.github/skills/boiler-project-generator/SKILL.md +103 -0
- package/.github/skills/boiler-project-generator/assets/templates/android/README.md +3 -0
- package/.github/skills/boiler-project-generator/assets/templates/angular/README.md +3 -0
- package/.github/skills/boiler-project-generator/assets/templates/flutter/README.md +3 -0
- package/.github/skills/boiler-project-generator/assets/templates/ios/README.md +3 -0
- package/.github/skills/boiler-project-generator/assets/templates/react/README.md +3 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/README.md +3 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/api-setup.ts +76 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/component-primary-button.tsx +29 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/env-config.env +4 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/feature-auth-screen.tsx +45 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/feature-dashboard-screen.tsx +45 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/feature-profile-screen.tsx +45 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/hook-use-app-boot.ts +11 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/navigation-setup.tsx +25 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/project-structure.md +24 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/redux-hooks.ts +5 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/redux-session-slice.ts +29 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/redux-store.ts +15 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/theme-index.ts +23 -0
- package/.github/skills/boiler-project-generator/assets/templates/react-native/utils-helpers.ts +7 -0
- package/.github/skills/boiler-project-generator/metadata.yaml +29 -0
- package/.github/skills/boiler-project-generator/references/android.md +19 -0
- package/.github/skills/boiler-project-generator/references/angular.md +14 -0
- package/.github/skills/boiler-project-generator/references/flutter.md +17 -0
- package/.github/skills/boiler-project-generator/references/ios.md +17 -0
- package/.github/skills/boiler-project-generator/references/react-native.md +103 -0
- package/.github/skills/boiler-project-generator/references/react.md +17 -0
- package/.github/skills/boiler-project-generator/scripts/angular.js +43 -0
- package/.github/skills/boiler-project-generator/scripts/generate-project.mjs +107 -0
- package/.github/skills/boiler-project-generator/scripts/init.js +105 -0
- package/.github/skills/boiler-project-generator/scripts/react-native.js +1041 -0
- package/.github/skills/boiler-project-generator/scripts/react.js +32 -0
- package/.github/skills/clean-architecture-generator/SKILL.md +235 -0
- package/.github/skills/clean-architecture-generator/references/architecture-core.md +126 -0
- package/.github/skills/clean-architecture-generator/references/platform-angular.md +374 -0
- package/.github/skills/clean-architecture-generator/references/platform-flutter.md +366 -0
- package/.github/skills/clean-architecture-generator/references/platform-react-native.md +590 -0
- package/.github/skills/clean-architecture-generator/references/platform-react.md +261 -0
- package/.github/skills/code-test-coverage-analyzer/SKILL.md +1358 -0
- package/.github/skills/code-test-coverage-analyzer/assets/config-questionnaire.md +118 -0
- package/.github/skills/code-test-coverage-analyzer/assets/conflict-resolution-protocol.md +99 -0
- package/.github/skills/code-test-coverage-analyzer/assets/coverage-calculation-rules.md +294 -0
- package/.github/skills/code-test-coverage-analyzer/assets/multi-strategy-search.md +145 -0
- package/.github/skills/code-test-coverage-analyzer/assets/output-file-contracts.md +651 -0
- package/.github/skills/code-test-coverage-analyzer/assets/status-definitions.md +273 -0
- package/.github/skills/code-test-coverage-analyzer/examples/example-invocation.md +208 -0
- package/.github/skills/code-test-coverage-analyzer/references/android-patterns.md +229 -0
- package/.github/skills/code-test-coverage-analyzer/references/angular-patterns.md +177 -0
- package/.github/skills/code-test-coverage-analyzer/references/backend-patterns.md +383 -0
- package/.github/skills/code-test-coverage-analyzer/references/flutter-patterns.md +254 -0
- package/.github/skills/code-test-coverage-analyzer/references/ios-patterns.md +228 -0
- package/.github/skills/code-test-coverage-analyzer/references/react-native-patterns.md +431 -0
- package/.github/skills/code-test-coverage-analyzer/references/react-patterns.md +206 -0
- package/.github/skills/code-test-coverage-analyzer/scripts/detect-platform.ps1 +261 -0
- package/.github/skills/code-test-coverage-analyzer/scripts/scan-repository.ps1 +242 -0
- package/.github/skills/code-test-coverage-analyzer/templates/brd-compliance-row.md +107 -0
- package/.github/skills/code-test-coverage-analyzer/templates/test-case-row.md +130 -0
- package/.github/skills/code-test-coverage-analyzer/templates/user-story-compliance-row.md +170 -0
- package/.github/skills/custom-font-integrator/SKILL.md +373 -0
- package/.github/skills/custom-font-integrator/assets/FontTestScreen.js +150 -0
- package/.github/skills/custom-font-integrator/references/example-info-plist.xml +21 -0
- package/.github/skills/custom-font-integrator/scripts/setup-fonts.sh +99 -0
- package/.github/skills/encryption-decryption-utility/Instructions.md +282 -0
- package/.github/skills/encryption-decryption-utility/README.md +222 -0
- package/.github/skills/encryption-decryption-utility/SKILL.md +645 -0
- package/.github/skills/encryption-decryption-utility/assets/encryption-config-template.json +13 -0
- package/.github/skills/encryption-decryption-utility/assets/platform-matrix.json +180 -0
- package/.github/skills/encryption-decryption-utility/metadata.yaml +51 -0
- package/.github/skills/encryption-decryption-utility/references/android-crypto.md +157 -0
- package/.github/skills/encryption-decryption-utility/references/angular-crypto.md +130 -0
- package/.github/skills/encryption-decryption-utility/references/approach-1-webcrypto.md +95 -0
- package/.github/skills/encryption-decryption-utility/references/approach-2-rsa-aes-cbc.md +111 -0
- package/.github/skills/encryption-decryption-utility/references/approach-3-aes-sharedkey.md +114 -0
- package/.github/skills/encryption-decryption-utility/references/architecture.md +233 -0
- package/.github/skills/encryption-decryption-utility/references/backend-alignment.md +506 -0
- package/.github/skills/encryption-decryption-utility/references/dependency-guidance.md +234 -0
- package/.github/skills/encryption-decryption-utility/references/ec-implementation.md +832 -0
- package/.github/skills/encryption-decryption-utility/references/error-handling-playbook.md +234 -0
- package/.github/skills/encryption-decryption-utility/references/flutter-crypto.md +105 -0
- package/.github/skills/encryption-decryption-utility/references/ios-crypto.md +338 -0
- package/.github/skills/encryption-decryption-utility/references/native-rsa-implementation.md +373 -0
- package/.github/skills/encryption-decryption-utility/references/node-crypto.md +86 -0
- package/.github/skills/encryption-decryption-utility/references/react-crypto.md +105 -0
- package/.github/skills/encryption-decryption-utility/references/react-native-crypto.md +1001 -0
- package/.github/skills/encryption-decryption-utility/references/react-web-crypto.md +668 -0
- package/.github/skills/encryption-decryption-utility/references/security-checklist.md +176 -0
- package/.github/skills/encryption-decryption-utility/references/web-crypto.md +74 -0
- package/.github/skills/encryption-decryption-utility/scripts/detect.js +128 -0
- package/.github/skills/encryption-decryption-utility/scripts/install.js +1713 -0
- package/.github/skills/encryption-decryption-utility/scripts/setup.js +800 -0
- package/.github/skills/encryption-decryption-utility/template.md +241 -0
- package/.github/skills/encryption-decryption-utility/templates/config-questionnaire.md +467 -0
- package/.github/skills/encryption-decryption-utility/templates/delivery-checklist.md +206 -0
- package/.github/skills/encryption-decryption-utility/templates/implementation-plan.md +304 -0
- package/.github/skills/feature-generator/SKILL.MD +2741 -0
- package/.github/skills/feature-generator/assets/fingerprint-schema.json +385 -0
- package/.github/skills/feature-generator/assets/spec-template.md +172 -0
- package/.github/skills/feature-generator/assets/transform-rules.json +82 -0
- package/.github/skills/feature-generator/references/api-envelope-patterns.md +327 -0
- package/.github/skills/feature-generator/references/screen-logic-patterns.md +399 -0
- package/.github/skills/feature-generator/references/state-library-patterns.md +464 -0
- package/.github/skills/figma-ui-mapper/README.md +34 -0
- package/.github/skills/figma-ui-mapper/SKILL.md +101 -0
- package/.github/skills/figma-ui-mapper/assets/templates/component-map-template.md +30 -0
- package/.github/skills/figma-ui-mapper/assets/templates/generation-report-template.md +49 -0
- package/.github/skills/figma-ui-mapper/metadata.yaml +22 -0
- package/.github/skills/figma-ui-mapper/references/android.md +11 -0
- package/.github/skills/figma-ui-mapper/references/angular.md +18 -0
- package/.github/skills/figma-ui-mapper/references/capacitor.md +18 -0
- package/.github/skills/figma-ui-mapper/references/common.md +23 -0
- package/.github/skills/figma-ui-mapper/references/expo.md +18 -0
- package/.github/skills/figma-ui-mapper/references/flutter.md +18 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/angular/rules.md +23 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/capacitor/rules.md +23 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/expo/rules.md +23 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/flutter/rules.md +23 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/ionic/rules.md +23 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/kotlin-multiplatform/rules.md +23 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/native-android/rules.md +23 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/native-ios/rules.md +23 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/next/rules.md +23 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/nuxt/rules.md +23 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/react/rules.md +19 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/react-native/rules.md +23 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/svelte/rules.md +23 -0
- package/.github/skills/figma-ui-mapper/references/frameworks/vue/rules.md +23 -0
- package/.github/skills/figma-ui-mapper/references/ionic.md +18 -0
- package/.github/skills/figma-ui-mapper/references/ios.md +11 -0
- package/.github/skills/figma-ui-mapper/references/kotlin-multiplatform.md +18 -0
- package/.github/skills/figma-ui-mapper/references/native-android.md +18 -0
- package/.github/skills/figma-ui-mapper/references/native-ios.md +18 -0
- package/.github/skills/figma-ui-mapper/references/next.md +18 -0
- package/.github/skills/figma-ui-mapper/references/nuxt.md +18 -0
- package/.github/skills/figma-ui-mapper/references/react-figma-guideline.md +21 -0
- package/.github/skills/figma-ui-mapper/references/react-native.md +18 -0
- package/.github/skills/figma-ui-mapper/references/react.md +18 -0
- package/.github/skills/figma-ui-mapper/references/script-usage.md +46 -0
- package/.github/skills/figma-ui-mapper/references/svelte.md +18 -0
- package/.github/skills/figma-ui-mapper/references/vue.md +18 -0
- package/.github/skills/figma-ui-mapper/references/workflow.md +74 -0
- package/.github/skills/figma-ui-mapper/scripts/generate-page-through-figma.js +635 -0
- package/.github/skills/figma-ui-mapper/scripts/generate-react-page-through-figma.js +4 -0
- package/.github/skills/frontend-task-breakdown/SKILL.md +734 -0
- package/.github/skills/md-file-converter/SKILL.md +291 -0
- package/.github/skills/md-file-converter/config/formats.json +114 -0
- package/.github/skills/md-file-converter/extractors/extract-docx.sh +120 -0
- package/.github/skills/md-file-converter/extractors/extract-eml.py +108 -0
- package/.github/skills/md-file-converter/extractors/extract-pdf.sh +97 -0
- package/.github/skills/md-file-converter/extractors/extract-pptx.py +143 -0
- package/.github/skills/md-file-converter/extractors/extract-xlsx.py +175 -0
- package/.github/skills/md-file-converter/scripts/check-tools.sh +47 -0
- package/.github/skills/md-file-converter/scripts/extract-archive.sh +83 -0
- package/.github/skills/md-file-converter/scripts/extract-ocr.sh +77 -0
- package/.github/skills/md-file-converter/scripts/get-metadata.sh +57 -0
- package/.github/skills/md-file-converter/templates/output.md +73 -0
- package/.github/skills/md-file-converter/templates/unsupported-object.md +6 -0
- package/.github/skills/mockAPI-contract-generator/SKILL.md +607 -0
- package/.github/skills/test-case-validator/CHANGELOG.md +155 -0
- package/.github/skills/test-case-validator/CONFIGURATION.md +130 -0
- package/.github/skills/test-case-validator/EXAMPLES.md +50 -0
- package/.github/skills/test-case-validator/QUALITY_SCORING.md +98 -0
- package/.github/skills/test-case-validator/README.md +111 -0
- package/.github/skills/test-case-validator/REPORT_TEMPLATE.md +116 -0
- package/.github/skills/test-case-validator/SKILL.md +209 -0
- package/.github/skills/test-case-validator/SYSTEM_PROMPT.md +127 -0
- package/.github/skills/test-case-validator/TRACEABILITY_ENGINE.md +152 -0
- package/.github/skills/test-case-validator/VALIDATION_RULES.md +411 -0
- package/.github/skills/test-case-validator/config/default.config.yaml +62 -0
- package/.github/skills/test-case-validator/docs/ARCHITECTURE.md +66 -0
- package/.github/skills/test-case-validator/docs/EXTENDING.md +85 -0
- package/.github/skills/test-case-validator/docs/FAQ.md +88 -0
- package/.github/skills/test-case-validator/docs/VERSIONING.md +55 -0
- package/.github/skills/test-case-validator/examples/example-1-manual-qa-ecommerce/input-brd.md +43 -0
- package/.github/skills/test-case-validator/examples/example-1-manual-qa-ecommerce/input-test-cases.csv +9 -0
- package/.github/skills/test-case-validator/examples/example-1-manual-qa-ecommerce/input-user-story.md +29 -0
- package/.github/skills/test-case-validator/examples/example-1-manual-qa-ecommerce/output-report.md +303 -0
- package/.github/skills/test-case-validator/examples/example-2-automated-frontend-suite/input-spec.md +43 -0
- package/.github/skills/test-case-validator/examples/example-2-automated-frontend-suite/input-test-files-index.md +56 -0
- package/.github/skills/test-case-validator/examples/example-2-automated-frontend-suite/output-report.md +274 -0
- package/.github/skills/test-case-validator/prompts/00-applicability-resolution.md +61 -0
- package/.github/skills/test-case-validator/prompts/01-extraction-user-story.md +58 -0
- package/.github/skills/test-case-validator/prompts/02-extraction-brd.md +64 -0
- package/.github/skills/test-case-validator/prompts/03-extraction-test-cases.md +92 -0
- package/.github/skills/test-case-validator/prompts/04-traceability-matrix.md +41 -0
- package/.github/skills/test-case-validator/prompts/05-coverage-analysis.md +46 -0
- package/.github/skills/test-case-validator/prompts/06-missing-scenario-detection.md +32 -0
- package/.github/skills/test-case-validator/prompts/07-duplicate-detection.md +36 -0
- package/.github/skills/test-case-validator/prompts/08-risk-analysis.md +39 -0
- package/.github/skills/test-case-validator/prompts/09-gated-wiring-validation.md +53 -0
- package/.github/skills/test-case-validator/prompts/10-observation-report.md +56 -0
- package/.github/skills/test-case-validator/prompts/11-final-report-assembly.md +57 -0
- package/.github/skills/test-case-validator/templates/coverage-table.md +25 -0
- package/.github/skills/test-case-validator/templates/executive-summary.md +38 -0
- package/.github/skills/test-case-validator/templates/final-summary-block.md +87 -0
- package/.github/skills/test-case-validator/templates/observation-entry.md +41 -0
- package/.github/skills/test-case-validator/templates/rtm-row.md +25 -0
- package/.github/skills/validation-engine-builder/README.md +50 -0
- package/.github/skills/validation-engine-builder/SKILL.md +241 -0
- package/.github/skills/validation-engine-builder/references/core.md +158 -0
- package/.github/skills/validation-engine-builder/references/platform-angular.md +166 -0
- package/.github/skills/validation-engine-builder/references/platform-flutter.md +118 -0
- package/.github/skills/validation-engine-builder/references/platform-react-native.md +170 -0
- package/.github/skills/validation-engine-builder/references/platform-react.md +94 -0
- package/.github/skills/validation-engine-builder/scripts/apply-to-project.js +80 -0
- package/.github/skills/validation-engine-builder/scripts/generate-angular.js +271 -0
- package/.github/skills/validation-engine-builder/scripts/generate-flutter.js +298 -0
- package/.github/skills/validation-engine-builder/scripts/generate-react-native.js +217 -0
- package/.github/skills/validation-engine-builder/scripts/generate-react.js +163 -0
- package/.github/skills/validation-engine-builder/scripts/install-deps.js +53 -0
- package/.github/skills/validation-engine-builder/scripts/shared/detect-platform.js +68 -0
- package/.github/skills/validation-engine-builder/scripts/shared/npm-deps.js +103 -0
- package/.github/skills/validation-engine-builder/scripts/shared/rhf-hook.js +43 -0
- package/.github/skills/validation-engine-builder/scripts/shared/ts-messages-regex.js +62 -0
- package/.github/skills/validation-engine-builder/scripts/shared/util.js +44 -0
- package/.github/skills/validation-engine-builder/scripts/shared/yup-schemas.js +80 -0
- package/.github/skills/validation-engine-builder/template.md +73 -0
- package/.github/skills/validation-engine-builder/templates/messages.json +22 -0
- package/.github/skills/validation-engine-builder/templates/regex.json +16 -0
- package/.github/skills/validation-engine-builder/templates/schemas.json +48 -0
- package/bin/index.js +145 -0
- package/package.json +22 -0
- package/readme.md +0 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Platform File — Flutter
|
|
2
|
+
|
|
3
|
+
Read `core.md` first. Flutter cannot run any JS library — no Yup, no react-hook-form. This
|
|
4
|
+
platform generates pure Dart, targeting Flutter's own `Form` + `TextFormField.validator`
|
|
5
|
+
mechanism, which needs no package at all.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Dependencies
|
|
10
|
+
|
|
11
|
+
None. `TextFormField.validator: (value) => ...` is part of the Flutter SDK's `material`/`widgets`
|
|
12
|
+
library — no `pubspec.yaml` addition is required for the baseline pattern documented here.
|
|
13
|
+
`scripts/shared/npm-deps.js` no-ops for this platform (prints an explanatory message).
|
|
14
|
+
|
|
15
|
+
**If the project already uses `reactive_forms` or `flutter_form_builder`** (check `pubspec.yaml`
|
|
16
|
+
dependencies first), generate against that project's existing pattern instead of the plain
|
|
17
|
+
`TextFormField.validator` approach below — do not introduce a second form-handling approach
|
|
18
|
+
alongside an existing one. The rest of this file assumes neither is present.
|
|
19
|
+
|
|
20
|
+
## Generated files
|
|
21
|
+
|
|
22
|
+
`node scripts/apply-to-project.js --platform flutter` writes to `lib/core/validation/`:
|
|
23
|
+
|
|
24
|
+
| File | Role |
|
|
25
|
+
|---|---|
|
|
26
|
+
| `validation_messages.dart` | `ValidationMessages` class — `static const String` per message key, plus `xxxMsg(...)` interpolation helpers |
|
|
27
|
+
| `validation_regex.dart` | `ValidationRegex` class — `static final RegExp` per regex key |
|
|
28
|
+
| `validators.dart` | One class per schema (`LoginValidators`, `SignupValidators`, ...), each with a `static String? fieldName(String? value)` method per field |
|
|
29
|
+
|
|
30
|
+
**There is no generated error-display file on this platform.** `TextFormField`'s `validator`
|
|
31
|
+
callback return value is rendered automatically beneath the field by the `Form`/`TextFormField`
|
|
32
|
+
widgets themselves — inventing a separate "ValidationError" widget (as the other 3 platforms need)
|
|
33
|
+
would duplicate what Flutter already does. This is a genuine platform difference, not an omission.
|
|
34
|
+
|
|
35
|
+
## `TextFormField` wiring per field type
|
|
36
|
+
|
|
37
|
+
```dart
|
|
38
|
+
final _emailController = TextEditingController();
|
|
39
|
+
|
|
40
|
+
TextFormField(
|
|
41
|
+
controller: _emailController,
|
|
42
|
+
decoration: const InputDecoration(labelText: 'Email'),
|
|
43
|
+
keyboardType: TextInputType.emailAddress,
|
|
44
|
+
validator: LoginValidators.email,
|
|
45
|
+
),
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
| Field type | `keyboardType` | Other props |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| email | `TextInputType.emailAddress` | — |
|
|
51
|
+
| password / confirmPassword | — | `obscureText: true` |
|
|
52
|
+
| phone | `TextInputType.phone` | — |
|
|
53
|
+
| otp | `TextInputType.number` | consider a max-length formatter (`LengthLimitingTextInputFormatter(6)`) |
|
|
54
|
+
| number fields | `TextInputType.number` | — |
|
|
55
|
+
| everything else | (default `TextInputType.text`) | — |
|
|
56
|
+
|
|
57
|
+
Always dispose every `TextEditingController` in the widget's `dispose()` override — a controller
|
|
58
|
+
leak is a common, easy-to-miss Flutter bug.
|
|
59
|
+
|
|
60
|
+
## `call()`, not `execute()` — matches `clean-architecture-generator`'s Flutter convention
|
|
61
|
+
|
|
62
|
+
If this project's use cases follow the `clean-architecture-generator` skill's Flutter pattern
|
|
63
|
+
(a `call()` method instead of `execute()`), the validators generated here are unrelated — they are
|
|
64
|
+
plain `String? Function(String?)` functions, not use-case classes, so there is no method-naming
|
|
65
|
+
choice to make for them. Do not add a `call()` wrapper to a validator function.
|
|
66
|
+
|
|
67
|
+
## confirmPassword / cross-field validation
|
|
68
|
+
|
|
69
|
+
A validator function only receives its own field's value — it cannot see another field's value
|
|
70
|
+
directly. Compare against the other field's live `TextEditingController` instead:
|
|
71
|
+
|
|
72
|
+
```dart
|
|
73
|
+
final _passwordController = TextEditingController();
|
|
74
|
+
final _confirmPasswordController = TextEditingController();
|
|
75
|
+
|
|
76
|
+
String? _confirmPasswordValidator(String? value) {
|
|
77
|
+
if (value == null || value.isEmpty) {
|
|
78
|
+
return ValidationMessages.requiredMsg('Confirm Password');
|
|
79
|
+
}
|
|
80
|
+
if (value != _passwordController.text) {
|
|
81
|
+
return ValidationMessages.passwordMatch;
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// wiring:
|
|
87
|
+
TextFormField(
|
|
88
|
+
controller: _confirmPasswordController,
|
|
89
|
+
obscureText: true,
|
|
90
|
+
decoration: const InputDecoration(labelText: 'Confirm Password'),
|
|
91
|
+
validator: _confirmPasswordValidator,
|
|
92
|
+
),
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
This validator is hand-written (not generated), since it closes over a controller that belongs to
|
|
96
|
+
the specific page — same spirit as the RN/React Yup `.oneOf()` addition and the Angular
|
|
97
|
+
`FormGroup`-level validator, each adapted to what that platform can actually express.
|
|
98
|
+
|
|
99
|
+
## Reusing the same validation on multiple pages
|
|
100
|
+
|
|
101
|
+
```dart
|
|
102
|
+
// login_page.dart
|
|
103
|
+
TextFormField(controller: _emailController, validator: LoginValidators.email),
|
|
104
|
+
|
|
105
|
+
// admin_login_page.dart
|
|
106
|
+
TextFormField(controller: _emailController, validator: LoginValidators.email), // same validator, different page
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Page scaffold generator (optional)
|
|
110
|
+
|
|
111
|
+
`generate-flutter.js` exports `generateScreen(projectRoot, pageName, schemaKey, pagePath, schemasRaw)`
|
|
112
|
+
— writes a starter `[pageName].dart` (a `StatefulWidget` with a `GlobalKey<FormState>`, one
|
|
113
|
+
`TextEditingController` per field, and a `TextFormField` wired to the matching validator method) for
|
|
114
|
+
every field in the given schema. `pageName` must be snake_case, per Effective Dart's file-naming
|
|
115
|
+
convention (see `clean-architecture-generator`'s Flutter platform file for the same rule applied to
|
|
116
|
+
other artifact types). The generated class name is `pageName` converted to PascalCase, with no
|
|
117
|
+
forced "Page" suffix — pass a name that already reflects it's a page (e.g. `login_page`) so the
|
|
118
|
+
class name reads correctly (`LoginPage`), not doubled (`LoginPagePage`).
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# Platform File — React Native
|
|
2
|
+
|
|
3
|
+
Read `core.md` first (field-type detection, regex/message/schema key tables, golden rules — all
|
|
4
|
+
shared across platforms). This file covers only what's specific to wiring a React Native screen.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Dependencies
|
|
9
|
+
|
|
10
|
+
| Dependency | Role |
|
|
11
|
+
|---|---|
|
|
12
|
+
| `react-hook-form` | Form state + validation orchestration |
|
|
13
|
+
| `@hookform/resolvers` | Bridges Yup schemas into react-hook-form's `resolver` |
|
|
14
|
+
| `yup` | Schema definition — compiled from `templates/schemas.json` |
|
|
15
|
+
|
|
16
|
+
Installed automatically by `scripts/install-deps.js` / `scripts/apply-to-project.js`, version-pinned
|
|
17
|
+
by detected React Native version:
|
|
18
|
+
|
|
19
|
+
| React Native | react-hook-form | @hookform/resolvers | yup |
|
|
20
|
+
|---|---|---|---|
|
|
21
|
+
| 0.80+ / React 19 | ^7.54.0 | ^3.9.0 | ^1.4.0 |
|
|
22
|
+
| 0.73–0.79 | ^7.51.0 | ^3.4.0 | ^1.3.0 |
|
|
23
|
+
| < 0.73 | ^7.43.0 | ^3.1.0 | ^1.0.0 |
|
|
24
|
+
|
|
25
|
+
## Generated files
|
|
26
|
+
|
|
27
|
+
`node scripts/apply-to-project.js --platform react-native` writes to `src/validation/`:
|
|
28
|
+
|
|
29
|
+
| File | Role |
|
|
30
|
+
|---|---|
|
|
31
|
+
| `messages.ts` | `VALIDATION_MESSAGES` const + `msg` interpolation helpers |
|
|
32
|
+
| `regex.ts` | `VALIDATION_REGEX` const |
|
|
33
|
+
| `schemas.ts` | Yup object schemas, one per `templates/schemas.json` key |
|
|
34
|
+
| `useValidatedForm.ts` | Typed react-hook-form wrapper (`mode: 'onBlur'`, `reValidateMode: 'onChange'`) |
|
|
35
|
+
| `ValidationError.tsx` | `<Text>`-based error display component |
|
|
36
|
+
|
|
37
|
+
The relative import path from a given screen file to `src/validation/` is computed from the real
|
|
38
|
+
project structure by `generate-react-native.js` (`relativeImportPath()`), not hand-counted — if
|
|
39
|
+
wiring a screen manually, compute it the same way (count directory levels from the screen file's
|
|
40
|
+
own folder to `src/validation/`, not from a fixed assumption about screen depth).
|
|
41
|
+
|
|
42
|
+
## Controller wiring template per field type
|
|
43
|
+
|
|
44
|
+
Always use `Controller` from `react-hook-form` for every `TextInput` — React Native's `TextInput`
|
|
45
|
+
does not integrate cleanly with `register()`-style uncontrolled refs the way a plain HTML `<input>`
|
|
46
|
+
does (contrast with `platform-react.md`, where `register()` is preferred instead).
|
|
47
|
+
|
|
48
|
+
### Email
|
|
49
|
+
```tsx
|
|
50
|
+
<Controller control={control} name="email"
|
|
51
|
+
render={({ field: { onChange, onBlur, value } }) => (
|
|
52
|
+
<View>
|
|
53
|
+
<TextInput
|
|
54
|
+
style={[styles.input, errors.email && styles.inputError]}
|
|
55
|
+
placeholder="Email"
|
|
56
|
+
keyboardType="email-address"
|
|
57
|
+
autoCapitalize="none"
|
|
58
|
+
onChangeText={onChange}
|
|
59
|
+
onBlur={onBlur}
|
|
60
|
+
value={value ?? ''}
|
|
61
|
+
/>
|
|
62
|
+
<ValidationError message={errors.email?.message} />
|
|
63
|
+
</View>
|
|
64
|
+
)}
|
|
65
|
+
/>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Password
|
|
69
|
+
```tsx
|
|
70
|
+
<Controller control={control} name="password"
|
|
71
|
+
render={({ field: { onChange, onBlur, value } }) => (
|
|
72
|
+
<View>
|
|
73
|
+
<TextInput
|
|
74
|
+
style={[styles.input, errors.password && styles.inputError]}
|
|
75
|
+
placeholder="Password"
|
|
76
|
+
secureTextEntry={true}
|
|
77
|
+
onChangeText={onChange}
|
|
78
|
+
onBlur={onBlur}
|
|
79
|
+
value={value ?? ''}
|
|
80
|
+
/>
|
|
81
|
+
<ValidationError message={errors.password?.message} />
|
|
82
|
+
</View>
|
|
83
|
+
)}
|
|
84
|
+
/>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Phone
|
|
88
|
+
```tsx
|
|
89
|
+
<Controller control={control} name="phone"
|
|
90
|
+
render={({ field: { onChange, onBlur, value } }) => (
|
|
91
|
+
<View>
|
|
92
|
+
<TextInput
|
|
93
|
+
style={[styles.input, errors.phone && styles.inputError]}
|
|
94
|
+
placeholder="Phone Number"
|
|
95
|
+
keyboardType="phone-pad"
|
|
96
|
+
onChangeText={onChange}
|
|
97
|
+
onBlur={onBlur}
|
|
98
|
+
value={value ?? ''}
|
|
99
|
+
/>
|
|
100
|
+
<ValidationError message={errors.phone?.message} />
|
|
101
|
+
</View>
|
|
102
|
+
)}
|
|
103
|
+
/>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### OTP
|
|
107
|
+
```tsx
|
|
108
|
+
<Controller control={control} name="otp"
|
|
109
|
+
render={({ field: { onChange, onBlur, value } }) => (
|
|
110
|
+
<View>
|
|
111
|
+
<TextInput
|
|
112
|
+
style={[styles.input, errors.otp && styles.inputError]}
|
|
113
|
+
placeholder="Enter OTP"
|
|
114
|
+
keyboardType="number-pad"
|
|
115
|
+
maxLength={6}
|
|
116
|
+
onChangeText={onChange}
|
|
117
|
+
onBlur={onBlur}
|
|
118
|
+
value={value ?? ''}
|
|
119
|
+
/>
|
|
120
|
+
<ValidationError message={errors.otp?.message} />
|
|
121
|
+
</View>
|
|
122
|
+
)}
|
|
123
|
+
/>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## confirmPassword cross-field validation
|
|
127
|
+
|
|
128
|
+
This cannot be expressed in `schemas.json`. After regenerating, add directly to `schemas.ts`:
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
// cross-field — added after generation, re-add if regenerated
|
|
132
|
+
confirmPassword: yup.string()
|
|
133
|
+
.required(msg.required('Confirm Password'))
|
|
134
|
+
.oneOf([yup.ref('password')], VALIDATION_MESSAGES.passwordMatch),
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Styles to add if not present
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
input: {
|
|
141
|
+
borderWidth: 1,
|
|
142
|
+
borderColor: '#D1D5DB',
|
|
143
|
+
borderRadius: 8,
|
|
144
|
+
paddingHorizontal: 16,
|
|
145
|
+
paddingVertical: 12,
|
|
146
|
+
fontSize: 16,
|
|
147
|
+
color: '#111827',
|
|
148
|
+
backgroundColor: '#F9FAFB',
|
|
149
|
+
},
|
|
150
|
+
inputError: {
|
|
151
|
+
borderColor: '#DC2626',
|
|
152
|
+
},
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Reusing the same validation on multiple screens
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
// LoginScreen.tsx
|
|
159
|
+
const form = useValidatedForm(schemas.login);
|
|
160
|
+
|
|
161
|
+
// AdminLoginScreen.tsx
|
|
162
|
+
const form = useValidatedForm(schemas.login); // same schema, different screen
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Screen scaffold generator (optional)
|
|
166
|
+
|
|
167
|
+
`generate-react-native.js` exports `generateScreen(projectRoot, screenName, schemaKey, screenPath, schemasRaw)`
|
|
168
|
+
— writes a starter `[screenName]/[screenName].tsx` wired with `Controller` for every field in the
|
|
169
|
+
given schema. Useful for a brand-new screen; for an existing screen, wire it by hand following the
|
|
170
|
+
patterns above instead of overwriting the file.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Platform File — React (Web)
|
|
2
|
+
|
|
3
|
+
Read `core.md` first. React web reuses the exact same `react-hook-form` + Yup engine as React
|
|
4
|
+
Native (react-hook-form is a React library, not a React-Native-only one) — the only real
|
|
5
|
+
differences are the DOM elements used and the wiring mechanism for native `<input>` elements.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Dependencies
|
|
10
|
+
|
|
11
|
+
Identical to React Native — see `platform-react-native.md`'s dependency table. There is no
|
|
12
|
+
separate RN-version gate for web; `scripts/shared/npm-deps.js` applies the same "current" tier
|
|
13
|
+
(`react-hook-form` ^7.54.0, `@hookform/resolvers` ^3.9.0, `yup` ^1.4.0) since there's no RN version
|
|
14
|
+
to detect. Verify against npm if a long time has passed since this skill was last updated.
|
|
15
|
+
|
|
16
|
+
## Generated files
|
|
17
|
+
|
|
18
|
+
`node scripts/apply-to-project.js --platform react` writes to `src/validation/` — same 5 files,
|
|
19
|
+
same shape, as React Native (`messages.ts`, `regex.ts`, `schemas.ts`, `useValidatedForm.ts`,
|
|
20
|
+
`ValidationError.tsx`). Only `ValidationError.tsx` differs in content: it renders a plain `<span>`
|
|
21
|
+
with an inline style object instead of RN's `<Text>` + `StyleSheet.create`, so it works with zero
|
|
22
|
+
assumptions about the project's CSS setup. If the project uses CSS Modules, Tailwind, or
|
|
23
|
+
styled-components, adapt `ValidationError`'s styling to match — its contract
|
|
24
|
+
(`{ message?: string }` prop) stays the same either way.
|
|
25
|
+
|
|
26
|
+
## Wiring native `<input>` — use `register()`, not `Controller`
|
|
27
|
+
|
|
28
|
+
**This is the one real mechanical difference from React Native.** A plain HTML `<input>` exposes a
|
|
29
|
+
real DOM ref, so react-hook-form's `register()` integrates directly — `Controller` is only needed
|
|
30
|
+
for custom/controlled components that don't expose a compatible ref (which is exactly why React
|
|
31
|
+
Native's `TextInput` needs `Controller` in `platform-react-native.md`). Do not port the `Controller`
|
|
32
|
+
pattern to a native `<input>`; it adds unnecessary boilerplate.
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
const {
|
|
36
|
+
register,
|
|
37
|
+
handleSubmit,
|
|
38
|
+
formState: { errors },
|
|
39
|
+
} = useValidatedForm(schemas.login);
|
|
40
|
+
|
|
41
|
+
<input
|
|
42
|
+
id="email"
|
|
43
|
+
type="email"
|
|
44
|
+
autoComplete="email"
|
|
45
|
+
{...register('email')}
|
|
46
|
+
/>
|
|
47
|
+
<ValidationError message={errors.email?.message} />
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
If the project's design system uses a custom input component that wraps a ref forwardable
|
|
51
|
+
`<input>` (e.g. `<TextField ref={...} />`), `register()` still works as long as the component
|
|
52
|
+
forwards its ref. Only fall back to `Controller` when the underlying component genuinely does not
|
|
53
|
+
forward a usable ref (e.g. a fully controlled third-party component).
|
|
54
|
+
|
|
55
|
+
### Per-field `type`/props
|
|
56
|
+
|
|
57
|
+
| Field type | `type` attribute | Other props |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| email | `email` | `autoComplete="email"` |
|
|
60
|
+
| password / confirmPassword | `password` | — |
|
|
61
|
+
| phone / otp / numeric | `number` (or `text` with `inputMode="numeric"` if leading zeros matter) | `maxLength={6}` for otp |
|
|
62
|
+
| url / website | `url` | — |
|
|
63
|
+
| everything else | `text` | — |
|
|
64
|
+
|
|
65
|
+
## confirmPassword cross-field validation
|
|
66
|
+
|
|
67
|
+
Identical to React Native — see `platform-react-native.md`'s section. Same Yup `.oneOf()` addition
|
|
68
|
+
to `schemas.ts`, since both platforms share the same generated `schemas.ts`.
|
|
69
|
+
|
|
70
|
+
## Reusing the same validation on multiple pages
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
// LoginPage.tsx
|
|
74
|
+
const form = useValidatedForm(schemas.login);
|
|
75
|
+
|
|
76
|
+
// AdminLoginPage.tsx
|
|
77
|
+
const form = useValidatedForm(schemas.login); // same schema, different page
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Page scaffold generator (optional)
|
|
81
|
+
|
|
82
|
+
`generate-react.js` exports `generateScreen(projectRoot, pageName, schemaKey, pagePath, schemasRaw)`
|
|
83
|
+
— writes a starter `[pageName]/[pageName].tsx` using `register()` for every field in the given
|
|
84
|
+
schema, inside a plain `<form>`. Useful for a brand-new page; for an existing page, wire it by hand
|
|
85
|
+
following the pattern above instead of overwriting the file.
|
|
86
|
+
|
|
87
|
+
## Next.js / CRA / Vite notes
|
|
88
|
+
|
|
89
|
+
The validation layer itself (`src/validation/`) does not depend on the bundler — only the page
|
|
90
|
+
file's own env var access (if any) does. If the target project is Next.js, the page component
|
|
91
|
+
still lives at `src/pages/[PageName]/[PageName].tsx` as generated; a thin Next.js route file
|
|
92
|
+
(`app/[route]/page.tsx` or `pages/[route].tsx`) imports and renders it, matching the same
|
|
93
|
+
"framework routing is a thin shell around a portable presentation component" approach used by
|
|
94
|
+
`clean-architecture-generator`'s React web platform file.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* apply-to-project.js
|
|
6
|
+
* Detects the target project's platform, installs compatible dependencies
|
|
7
|
+
* (React Native / React only — Angular and Flutter need none), and
|
|
8
|
+
* regenerates the platform's validation output files from the skill's
|
|
9
|
+
* shared templates.
|
|
10
|
+
*
|
|
11
|
+
* The AI handles screen/page/component analysis and wiring — this script
|
|
12
|
+
* handles only platform detection, dependency management, and file generation.
|
|
13
|
+
*
|
|
14
|
+
* Usage:
|
|
15
|
+
* node .github/skills/validation-engine-builder/scripts/apply-to-project.js
|
|
16
|
+
* node .github/skills/validation-engine-builder/scripts/apply-to-project.js --projectPath MyApp
|
|
17
|
+
* node .github/skills/validation-engine-builder/scripts/apply-to-project.js --platform angular
|
|
18
|
+
* node .github/skills/validation-engine-builder/scripts/apply-to-project.js --skipInstall
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
const path = require('path');
|
|
22
|
+
|
|
23
|
+
const { detectPlatform } = require('./shared/detect-platform.js');
|
|
24
|
+
const { ensureDeps } = require('./shared/npm-deps.js');
|
|
25
|
+
|
|
26
|
+
const GENERATORS = {
|
|
27
|
+
'react-native': './generate-react-native.js',
|
|
28
|
+
'react': './generate-react.js',
|
|
29
|
+
'angular': './generate-angular.js',
|
|
30
|
+
'flutter': './generate-flutter.js',
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
function parseArgs(argv) {
|
|
34
|
+
const parsed = {};
|
|
35
|
+
for (let i = 0; i < argv.length; i++) {
|
|
36
|
+
const token = argv[i];
|
|
37
|
+
if (!token.startsWith('--')) continue;
|
|
38
|
+
const key = token.slice(2);
|
|
39
|
+
const next = argv[i + 1];
|
|
40
|
+
if (!next || next.startsWith('--')) { parsed[key] = true; continue; }
|
|
41
|
+
parsed[key] = next;
|
|
42
|
+
i++;
|
|
43
|
+
}
|
|
44
|
+
return parsed;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function main() {
|
|
48
|
+
const args = parseArgs(process.argv.slice(2));
|
|
49
|
+
const projectRoot = args.projectPath ? path.resolve(args.projectPath) : process.cwd();
|
|
50
|
+
|
|
51
|
+
if (args.screenName || args.schema) {
|
|
52
|
+
console.log(' Note: --screenName and --schema are no longer supported.');
|
|
53
|
+
console.log(' Screen/page/component wiring is done by the AI agent, not this script.\n');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const platform = args.platform || detectPlatform(projectRoot);
|
|
57
|
+
|
|
58
|
+
if (!platform || !GENERATORS[platform]) {
|
|
59
|
+
console.error('\nERROR: Could not determine the target platform.');
|
|
60
|
+
console.error(' Detected neither pubspec.yaml (Flutter), angular.json (Angular), nor a');
|
|
61
|
+
console.error(' react-native/react dependency in package.json.');
|
|
62
|
+
console.error(' Re-run with --platform <react-native|react|angular|flutter> once the');
|
|
63
|
+
console.error(' platform has been confirmed with the user.');
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
console.log('\nValidation Engine — generating validation output');
|
|
68
|
+
console.log(` Project : ${projectRoot}`);
|
|
69
|
+
console.log(` Platform : ${platform}${args.platform ? ' (explicit override)' : ' (detected)'}\n`);
|
|
70
|
+
|
|
71
|
+
ensureDeps(projectRoot, platform, { skipInstall: !!args.skipInstall });
|
|
72
|
+
|
|
73
|
+
const { generate } = require(GENERATORS[platform]);
|
|
74
|
+
generate(projectRoot);
|
|
75
|
+
|
|
76
|
+
console.log('\nDone. Edit templates/messages.json, templates/regex.json, or templates/schemas.json');
|
|
77
|
+
console.log('and re-run this script to regenerate — never edit the generated output directly.\n');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
main();
|