Files
smart-city-digital-twin-mar…/smart-app-city/frontend/node_modules/del/index.js
Eric FELIXINE e30ae8ed09 feat(smart-app): implement complete mobile app MVP
- App.tsx: full navigation (Auth stack + Main tabs with 5 screens)
- Auth: LoginScreen, RegisterScreen, ForgotPasswordScreen
- HomeScreen: dashboard with IoT metrics, weather widget, alerts, quick actions, sensors
- MapScreen: interactive map with layer toggles (6 layers)
- MarketplaceScreen: categories (6), products (5), search
- ChatScreen: AI chat with quick prompts (4), bot responses
- ProfileScreen: user info, stats, menu (9 items), logout
- AlertsScreen: alert list with severity, acknowledge
- SensorsScreen: sensor list with type filters (6 types), search
- ZonesScreen: zone cards with stats
- SettingsScreen: language picker (FR/EN/ES/DE), privacy, about
- Stores: iotStore (sensors, zones, alerts), notificationStore, uiStore + i18n
- Hooks: useSensors, useAlerts, useNotifications, useLocation
- Components: Card, Button, LoadingSpinner, ErrorBoundary, Header
- Services: iotService, notificationService (with axios API client)
- Utils: formatters (temp, AQI, noise, dates), validators (email, password, IBAN)
- Theme: colors.ts with full design system (Blue Ocean palette)
- Ditto: fixed MongoDB connection, new JWT secrets, official gateway image
2026-06-01 18:00:35 -04:00

140 lines
3.0 KiB
JavaScript

'use strict';
const {promisify} = require('util');
const path = require('path');
const globby = require('globby');
const isGlob = require('is-glob');
const slash = require('slash');
const gracefulFs = require('graceful-fs');
const isPathCwd = require('is-path-cwd');
const isPathInside = require('is-path-inside');
const rimraf = require('rimraf');
const pMap = require('p-map');
const rimrafP = promisify(rimraf);
const rimrafOptions = {
glob: false,
unlink: gracefulFs.unlink,
unlinkSync: gracefulFs.unlinkSync,
chmod: gracefulFs.chmod,
chmodSync: gracefulFs.chmodSync,
stat: gracefulFs.stat,
statSync: gracefulFs.statSync,
lstat: gracefulFs.lstat,
lstatSync: gracefulFs.lstatSync,
rmdir: gracefulFs.rmdir,
rmdirSync: gracefulFs.rmdirSync,
readdir: gracefulFs.readdir,
readdirSync: gracefulFs.readdirSync
};
function safeCheck(file, cwd) {
if (isPathCwd(file)) {
throw new Error('Cannot delete the current working directory. Can be overridden with the `force` option.');
}
if (!isPathInside(file, cwd)) {
throw new Error('Cannot delete files/directories outside the current working directory. Can be overridden with the `force` option.');
}
}
function normalizePatterns(patterns) {
patterns = Array.isArray(patterns) ? patterns : [patterns];
patterns = patterns.map(pattern => {
if (process.platform === 'win32' && isGlob(pattern) === false) {
return slash(pattern);
}
return pattern;
});
return patterns;
}
module.exports = async (patterns, {force, dryRun, cwd = process.cwd(), onProgress = () => {}, ...options} = {}) => {
options = {
expandDirectories: false,
onlyFiles: false,
followSymbolicLinks: false,
cwd,
...options
};
patterns = normalizePatterns(patterns);
const files = (await globby(patterns, options))
.sort((a, b) => b.localeCompare(a));
if (files.length === 0) {
onProgress({
totalCount: 0,
deletedCount: 0,
percent: 1
});
}
let deletedCount = 0;
const mapper = async file => {
file = path.resolve(cwd, file);
if (!force) {
safeCheck(file, cwd);
}
if (!dryRun) {
await rimrafP(file, rimrafOptions);
}
deletedCount += 1;
onProgress({
totalCount: files.length,
deletedCount,
percent: deletedCount / files.length
});
return file;
};
const removedFiles = await pMap(files, mapper, options);
removedFiles.sort((a, b) => a.localeCompare(b));
return removedFiles;
};
module.exports.sync = (patterns, {force, dryRun, cwd = process.cwd(), ...options} = {}) => {
options = {
expandDirectories: false,
onlyFiles: false,
followSymbolicLinks: false,
cwd,
...options
};
patterns = normalizePatterns(patterns);
const files = globby.sync(patterns, options)
.sort((a, b) => b.localeCompare(a));
const removedFiles = files.map(file => {
file = path.resolve(cwd, file);
if (!force) {
safeCheck(file, cwd);
}
if (!dryRun) {
rimraf.sync(file, rimrafOptions);
}
return file;
});
removedFiles.sort((a, b) => a.localeCompare(b));
return removedFiles;
};