- 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
64 lines
1.9 KiB
JavaScript
Executable File
64 lines
1.9 KiB
JavaScript
Executable File
'use strict';
|
|
|
|
const Assert = require('@hapi/hoek/lib/assert');
|
|
|
|
const Uri = require('./uri');
|
|
|
|
|
|
const internals = {};
|
|
|
|
|
|
exports.regex = function (options = {}) {
|
|
|
|
// CIDR
|
|
|
|
Assert(options.cidr === undefined || typeof options.cidr === 'string', 'options.cidr must be a string');
|
|
const cidr = options.cidr ? options.cidr.toLowerCase() : 'optional';
|
|
Assert(['required', 'optional', 'forbidden'].includes(cidr), 'options.cidr must be one of required, optional, forbidden');
|
|
|
|
// Versions
|
|
|
|
Assert(options.version === undefined || typeof options.version === 'string' || Array.isArray(options.version), 'options.version must be a string or an array of string');
|
|
let versions = options.version || ['ipv4', 'ipv6', 'ipvfuture'];
|
|
if (!Array.isArray(versions)) {
|
|
versions = [versions];
|
|
}
|
|
|
|
Assert(versions.length >= 1, 'options.version must have at least 1 version specified');
|
|
|
|
for (let i = 0; i < versions.length; ++i) {
|
|
Assert(typeof versions[i] === 'string', 'options.version must only contain strings');
|
|
versions[i] = versions[i].toLowerCase();
|
|
Assert(['ipv4', 'ipv6', 'ipvfuture'].includes(versions[i]), 'options.version contains unknown version ' + versions[i] + ' - must be one of ipv4, ipv6, ipvfuture');
|
|
}
|
|
|
|
versions = Array.from(new Set(versions));
|
|
|
|
// Regex
|
|
|
|
const parts = versions.map((version) => {
|
|
|
|
// Forbidden
|
|
|
|
if (cidr === 'forbidden') {
|
|
return Uri.ip[version];
|
|
}
|
|
|
|
// Required
|
|
|
|
const cidrpart = `\\/${version === 'ipv4' ? Uri.ip.v4Cidr : Uri.ip.v6Cidr}`;
|
|
|
|
if (cidr === 'required') {
|
|
return `${Uri.ip[version]}${cidrpart}`;
|
|
}
|
|
|
|
// Optional
|
|
|
|
return `${Uri.ip[version]}(?:${cidrpart})?`;
|
|
});
|
|
|
|
const raw = `(?:${parts.join('|')})`;
|
|
const regex = new RegExp(`^${raw}$`);
|
|
return { cidr, versions, regex, raw };
|
|
};
|