samre-cli 1.0.4 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/templates/flutter_sdk.js +15 -15
- package/src/utils/flutter.js +54 -31
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
// Modèle complet pour lib/samre_sdk.dart (Version 100%
|
|
1
|
+
// Modèle complet pour lib/samre_sdk.dart (Version Professionnelle 100% Autonome)
|
|
2
2
|
|
|
3
3
|
export function generateFlutterSdkCode({ apiUrl, apiKey, appId, appName, dureeJours }) {
|
|
4
4
|
return `// =================================================================
|
|
5
|
-
// SDK Samré Mobile pour Flutter (Généré
|
|
5
|
+
// SDK Samré Mobile pour Flutter (Généré par samre-cli)
|
|
6
6
|
// Application : ${appName || 'App Samré'} (ID: ${appId})
|
|
7
7
|
// Campagne : ${dureeJours || 12} jours
|
|
8
8
|
// =================================================================
|
|
@@ -18,7 +18,7 @@ class SamreConfig {
|
|
|
18
18
|
static const String apiUrl = "${apiUrl}";
|
|
19
19
|
static const String apiKey = "${apiKey}";
|
|
20
20
|
static const String appId = "${appId}";
|
|
21
|
-
static const int requiredDurationSeconds = 25; // Compteur
|
|
21
|
+
static const int requiredDurationSeconds = 25; // Compteur anti-triche
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
/// Overlay automatique avec compteur de sécurité de 25 secondes
|
|
@@ -79,27 +79,27 @@ class _SamreOverlayState extends State<SamreOverlay> {
|
|
|
79
79
|
children: [
|
|
80
80
|
widget.child,
|
|
81
81
|
|
|
82
|
-
// ── Bouton Flottant Rehaussé avec SafeArea
|
|
82
|
+
// ── Bouton Flottant Rehaussé avec SafeArea ─────────────────────────
|
|
83
83
|
Positioned(
|
|
84
|
-
bottom:
|
|
84
|
+
bottom: 56,
|
|
85
85
|
right: 18,
|
|
86
86
|
child: SafeArea(
|
|
87
87
|
child: Material(
|
|
88
88
|
elevation: 10,
|
|
89
|
-
borderRadius: BorderRadius.circular(
|
|
89
|
+
borderRadius: BorderRadius.circular(30),
|
|
90
90
|
color: _canSubmit ? const Color(0xFF2563EB) : Colors.black.withOpacity(0.85),
|
|
91
91
|
child: InkWell(
|
|
92
|
-
borderRadius: BorderRadius.circular(
|
|
92
|
+
borderRadius: BorderRadius.circular(30),
|
|
93
93
|
onTap: _canSubmit ? _openDialog : null,
|
|
94
94
|
child: Padding(
|
|
95
|
-
padding: const EdgeInsets.symmetric(horizontal:
|
|
95
|
+
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
|
96
96
|
child: Row(
|
|
97
97
|
mainAxisSize: MainAxisSize.min,
|
|
98
98
|
children: [
|
|
99
99
|
Icon(
|
|
100
|
-
_canSubmit ? Icons.
|
|
100
|
+
_canSubmit ? Icons.verified_user_rounded : Icons.timer_outlined,
|
|
101
101
|
color: Colors.white,
|
|
102
|
-
size:
|
|
102
|
+
size: 20,
|
|
103
103
|
),
|
|
104
104
|
const SizedBox(width: 8),
|
|
105
105
|
Text(
|
|
@@ -107,7 +107,7 @@ class _SamreOverlayState extends State<SamreOverlay> {
|
|
|
107
107
|
style: const TextStyle(
|
|
108
108
|
color: Colors.white,
|
|
109
109
|
fontWeight: FontWeight.bold,
|
|
110
|
-
fontSize:
|
|
110
|
+
fontSize: 13,
|
|
111
111
|
decoration: TextDecoration.none,
|
|
112
112
|
),
|
|
113
113
|
),
|
|
@@ -119,7 +119,7 @@ class _SamreOverlayState extends State<SamreOverlay> {
|
|
|
119
119
|
),
|
|
120
120
|
),
|
|
121
121
|
|
|
122
|
-
// ── Fenêtre Modale de Validation (Indépendante du Navigator)
|
|
122
|
+
// ── Fenêtre Modale de Validation (100% Indépendante du Navigator) ──
|
|
123
123
|
if (_showValidationDialog)
|
|
124
124
|
Positioned.fill(
|
|
125
125
|
child: Container(
|
|
@@ -233,8 +233,8 @@ class _SamreValidationCardState extends State<SamreValidationCard> {
|
|
|
233
233
|
border: Border.all(color: const Color(0xFF334155), width: 1.5),
|
|
234
234
|
boxShadow: [
|
|
235
235
|
BoxShadow(
|
|
236
|
-
color: Colors.black.withOpacity(0.
|
|
237
|
-
blurRadius:
|
|
236
|
+
color: Colors.black.withOpacity(0.6),
|
|
237
|
+
blurRadius: 30,
|
|
238
238
|
spreadRadius: 5,
|
|
239
239
|
),
|
|
240
240
|
],
|
|
@@ -244,7 +244,7 @@ class _SamreValidationCardState extends State<SamreValidationCard> {
|
|
|
244
244
|
mainAxisSize: MainAxisSize.min,
|
|
245
245
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
246
246
|
children: [
|
|
247
|
-
//
|
|
247
|
+
// En-tête
|
|
248
248
|
Row(
|
|
249
249
|
children: [
|
|
250
250
|
Container(
|
package/src/utils/flutter.js
CHANGED
|
@@ -54,6 +54,24 @@ export const FlutterUtil = {
|
|
|
54
54
|
return sdkPath;
|
|
55
55
|
},
|
|
56
56
|
|
|
57
|
+
cleanMainDartContent(rawContent) {
|
|
58
|
+
let content = rawContent;
|
|
59
|
+
|
|
60
|
+
// 1. Supprimer l'import du SDK Samré et les commentaires associés
|
|
61
|
+
content = content.replace(/import\s+['"]samre_sdk\.dart['"];\s*\n?/g, '');
|
|
62
|
+
content = content.replace(/\/\/\s*SDK Samré[^\n]*\n?/gi, '');
|
|
63
|
+
content = content.replace(/\/\/\s*👉\s*SamreOverlay[^\n]*\n?/gi, '');
|
|
64
|
+
|
|
65
|
+
// 2. Supprimer la propriété builder SamreOverlay dans MaterialApp
|
|
66
|
+
content = content.replace(/builder\s*:\s*\([^)]*\)\s*=>\s*SamreOverlay\s*\(\s*child\s*:\s*child\s*\?\?\s*const\s*SizedBox\(\)\s*\),?\s*\n?/g, '');
|
|
67
|
+
content = content.replace(/builder\s*:\s*\([^)]*\)\s*=>\s*SamreOverlay\s*\(\s*child\s*:\s*([^)]+)\),?\s*\n?/g, 'builder: (context, child) => $1,\n');
|
|
68
|
+
|
|
69
|
+
// 3. Déballer SamreOverlay s'il entoure un widget (ex: home: SamreOverlay(child: SplashPage()))
|
|
70
|
+
content = content.replace(/SamreOverlay\s*\(\s*child\s*:\s*([^)]+)\)/g, '$1');
|
|
71
|
+
|
|
72
|
+
return content;
|
|
73
|
+
},
|
|
74
|
+
|
|
57
75
|
injectIntoMain(cwd = process.cwd()) {
|
|
58
76
|
const mainPath = path.join(cwd, 'lib', 'main.dart');
|
|
59
77
|
const backupPath = path.join(cwd, 'lib', 'main.dart.samre_bak');
|
|
@@ -62,49 +80,46 @@ export const FlutterUtil = {
|
|
|
62
80
|
return { injected: false, reason: 'main.dart introuvable' };
|
|
63
81
|
}
|
|
64
82
|
|
|
65
|
-
const
|
|
83
|
+
const originalContent = fs.readFileSync(mainPath, 'utf-8');
|
|
66
84
|
|
|
67
|
-
//
|
|
68
|
-
|
|
69
|
-
fs.writeFileSync(backupPath, content, 'utf-8');
|
|
70
|
-
}
|
|
85
|
+
// Nettoyer d'abord tout résidu ou ancienne injection pour garantir l'idempotence
|
|
86
|
+
let cleanContent = this.cleanMainDartContent(originalContent);
|
|
71
87
|
|
|
72
|
-
//
|
|
73
|
-
if (
|
|
74
|
-
|
|
88
|
+
// Sauvegarde de secours du fichier propre initial
|
|
89
|
+
if (!fs.existsSync(backupPath)) {
|
|
90
|
+
fs.writeFileSync(backupPath, cleanContent, 'utf-8');
|
|
75
91
|
}
|
|
76
92
|
|
|
77
|
-
let modified =
|
|
93
|
+
let modified = cleanContent;
|
|
78
94
|
|
|
79
95
|
// 1. Ajouter l'import de samre_sdk en haut (sans dupliquer material.dart)
|
|
80
96
|
if (!modified.includes('samre_sdk.dart')) {
|
|
81
97
|
modified = "import 'samre_sdk.dart';\n" + modified;
|
|
82
98
|
}
|
|
83
99
|
|
|
84
|
-
// 2.
|
|
85
|
-
|
|
86
|
-
|
|
100
|
+
// 2. Injecter proprement dans builder de MaterialApp (supporte MaterialApp, MaterialApp.router, GetMaterialApp)
|
|
101
|
+
const appRegex = /((?:Get)?MaterialApp(?:\.router)?\s*\()/;
|
|
102
|
+
if (appRegex.test(modified)) {
|
|
103
|
+
// Si MaterialApp a déjà une propriété builder existante
|
|
87
104
|
const builderRegex = /builder\s*:\s*\(([^)]*)\)\s*=>\s*([^,\n;]+)/;
|
|
88
105
|
if (builderRegex.test(modified)) {
|
|
89
106
|
modified = modified.replace(builderRegex, (match, args, body) => {
|
|
90
107
|
return `builder: (${args}) => SamreOverlay(child: ${body.trim()})`;
|
|
91
108
|
});
|
|
92
|
-
|
|
93
|
-
|
|
109
|
+
} else {
|
|
110
|
+
// Sinon insérer builder: (context, child) => SamreOverlay(...)
|
|
111
|
+
modified = modified.replace(
|
|
112
|
+
appRegex,
|
|
113
|
+
'$1\n builder: (context, child) => SamreOverlay(child: child ?? const SizedBox()),'
|
|
114
|
+
);
|
|
94
115
|
}
|
|
95
|
-
|
|
96
|
-
// Sinon insérer la propriété builder juste après MaterialApp(
|
|
97
|
-
modified = modified.replace(
|
|
98
|
-
/MaterialApp\s*\(/,
|
|
99
|
-
'MaterialApp(\n builder: (context, child) => SamreOverlay(child: child ?? const SizedBox()),'
|
|
100
|
-
);
|
|
101
116
|
fs.writeFileSync(mainPath, modified, 'utf-8');
|
|
102
117
|
return { injected: true, modifiedBuilder: true, backupPath };
|
|
103
118
|
}
|
|
104
119
|
|
|
105
120
|
// Fallback : injection sur home:
|
|
106
121
|
const homeRegex = /home\s*:\s*([^,\n\);]+)/;
|
|
107
|
-
if (homeRegex.test(modified)
|
|
122
|
+
if (homeRegex.test(modified)) {
|
|
108
123
|
modified = modified.replace(homeRegex, (match, p1) => {
|
|
109
124
|
return `home: SamreOverlay(child: ${p1.trim()})`;
|
|
110
125
|
});
|
|
@@ -125,22 +140,30 @@ export const FlutterUtil = {
|
|
|
125
140
|
let sdkDeleted = false;
|
|
126
141
|
let mainRestored = false;
|
|
127
142
|
|
|
143
|
+
// 1. Supprimer le fichier SDK
|
|
128
144
|
if (fs.existsSync(sdkPath)) {
|
|
129
145
|
fs.unlinkSync(sdkPath);
|
|
130
146
|
sdkDeleted = true;
|
|
131
147
|
}
|
|
132
148
|
|
|
149
|
+
// 2. Si un backup existe, essayer de le restaurer
|
|
133
150
|
if (fs.existsSync(backupPath)) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
151
|
+
try {
|
|
152
|
+
const backupContent = fs.readFileSync(backupPath, 'utf-8');
|
|
153
|
+
const cleanBackup = this.cleanMainDartContent(backupContent);
|
|
154
|
+
fs.writeFileSync(mainPath, cleanBackup, 'utf-8');
|
|
155
|
+
fs.unlinkSync(backupPath);
|
|
156
|
+
mainRestored = true;
|
|
157
|
+
} catch {
|
|
158
|
+
// Fallback nettoyage direct
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// 3. Dans tous les cas, s'assurer que main.dart est 100% purgé de toute trace de Samré
|
|
163
|
+
if (fs.existsSync(mainPath)) {
|
|
164
|
+
const currentContent = fs.readFileSync(mainPath, 'utf-8');
|
|
165
|
+
const cleanContent = this.cleanMainDartContent(currentContent);
|
|
166
|
+
fs.writeFileSync(mainPath, cleanContent, 'utf-8');
|
|
144
167
|
mainRestored = true;
|
|
145
168
|
}
|
|
146
169
|
|