@ -0,0 +1,8 @@
|
|||||||
|
> Why do I have a folder named ".expo" in my project?
|
||||||
|
The ".expo" folder is created when an Expo project is started using "expo start" command.
|
||||||
|
> What do the files contain?
|
||||||
|
- "devices.json": contains information about devices that have recently opened this project. This is used to populate the "Development sessions" list in your development builds.
|
||||||
|
- "settings.json": contains the server configuration that is used to serve the application manifest.
|
||||||
|
> Should I commit the ".expo" folder?
|
||||||
|
No, you should not share the ".expo" folder. It does not contain any information that is relevant for other developers working on the project, it is specific to your machine.
|
||||||
|
Upon project creation, the ".expo" folder is already added to your ".gitignore" file.
|
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"devices": []
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
import {FETCH_WEATHER} from './constants';
|
||||||
|
import { Weather } from '../data/stub';
|
||||||
|
|
||||||
|
export const setWeatherList = (weathers: Weather[]) => {
|
||||||
|
return {
|
||||||
|
type: FETCH_WEATHER,
|
||||||
|
payload: weathers,
|
||||||
|
toto : true,
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
export const FETCH_WEATHER = "weathers";
|
@ -0,0 +1,21 @@
|
|||||||
|
import { WEATHER_DATA } from "../data/stub";
|
||||||
|
import { FETCH_WEATHER } from "./constants";
|
||||||
|
import { getWeathersList } from "./thunk/actionListWeather";
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
weathers: [],
|
||||||
|
favoriteWeathers: [],
|
||||||
|
}
|
||||||
|
//@ts-ignore
|
||||||
|
export default appReducer = (state = initialState, action) => { ///action event receved
|
||||||
|
switch (action.type) {
|
||||||
|
|
||||||
|
case FETCH_WEATHER:
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
return {...state, weathers: action.payload};
|
||||||
|
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
import {configureStore} from '@reduxjs/toolkit'
|
||||||
|
import appReducer from './reducer';
|
||||||
|
|
||||||
|
// Reference here all your application reducers
|
||||||
|
const reducer = {
|
||||||
|
appReducer: appReducer,
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
const store = configureStore({
|
||||||
|
reducer,
|
||||||
|
/*middleware: (getDefaultMiddleware) =>
|
||||||
|
getDefaultMiddleware({
|
||||||
|
serializableCheck: false
|
||||||
|
})*/
|
||||||
|
},);
|
||||||
|
|
||||||
|
export default store;
|
@ -0,0 +1,46 @@
|
|||||||
|
import { City, Weather } from "../../data/stub";
|
||||||
|
import { setWeatherList } from "../Action";
|
||||||
|
|
||||||
|
export const getWeathersList = () => {
|
||||||
|
return async dispatch => {
|
||||||
|
try {
|
||||||
|
const citiesPromise = await fetch('https://iut-weather-api.azurewebsites.net/cities');
|
||||||
|
const citiesListJson = await citiesPromise.json();
|
||||||
|
const citiesList: City[] = citiesListJson.map(elt => new City(elt["name"], elt["latitude"], elt["longitude"]));
|
||||||
|
|
||||||
|
let weatherList: Weather[] = [];
|
||||||
|
|
||||||
|
for (let index = 0; index < citiesList.length; index++) {
|
||||||
|
const element = citiesList[index];
|
||||||
|
|
||||||
|
const weathersPromise = await fetch('https://iut-weather-api.azurewebsites.net/weather/city/name/' + citiesList[index].name);
|
||||||
|
const weathersListJson = await weathersPromise.json();
|
||||||
|
|
||||||
|
console.log(weathersListJson);
|
||||||
|
|
||||||
|
let weatherData = new Weather(
|
||||||
|
weathersListJson.at,
|
||||||
|
weathersListJson.visibility,
|
||||||
|
weathersListJson.weatherType,
|
||||||
|
weathersListJson.weatherDescription,
|
||||||
|
weathersListJson.temperature,
|
||||||
|
weathersListJson.temperatureFeelsLike,
|
||||||
|
weathersListJson.humidity,
|
||||||
|
weathersListJson.windSpeed,
|
||||||
|
weathersListJson.pressure,
|
||||||
|
citiesList[index]
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
weatherList.push(weatherData)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
dispatch(setWeatherList(weatherList));
|
||||||
|
} catch (error) {
|
||||||
|
console.log('Error---------', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Provider, useSelector } from 'react-redux'
|
||||||
|
import { SafeAreaView, ScrollView, View} from 'react-native';
|
||||||
|
import store from './Actions/store';
|
||||||
|
import Navigation from './Components/Navigation';
|
||||||
|
import { WeatherCard } from './Components/WeatherCard';
|
||||||
|
import { CITIES_DATA, WEATHER_DATA } from './data/stub';
|
||||||
|
|
||||||
|
const Card = () => {
|
||||||
|
|
||||||
|
|
||||||
|
// Get nounours data from the current application state
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<>
|
||||||
|
{/* Bind your application store to the Provider store */}
|
||||||
|
<Provider store={store}>
|
||||||
|
|
||||||
|
<Navigation></Navigation>
|
||||||
|
|
||||||
|
</Provider>
|
||||||
|
</>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default Card;
|
@ -0,0 +1,20 @@
|
|||||||
|
import { StatusBar } from 'expo-status-bar';
|
||||||
|
import { StyleSheet, Text, View } from 'react-native';
|
||||||
|
|
||||||
|
export default function App() {
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<Text>Open up App.js to start working on your app!</Text>
|
||||||
|
<StatusBar style="auto" />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
},
|
||||||
|
});
|
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
|
||||||
|
export const getImageSource = (weatherType) => {
|
||||||
|
switch (weatherType) {
|
||||||
|
case 'Ensoleillé':
|
||||||
|
return require('../assets/Ensoleille.png');
|
||||||
|
case 'Pluvieux':
|
||||||
|
return require('../assets/Pluvieux.png');
|
||||||
|
case 'Nuageux':
|
||||||
|
return require('../assets/Nuageux.png');
|
||||||
|
case 'Dégagé' :
|
||||||
|
return require('../assets/Degage.png');
|
||||||
|
default:
|
||||||
|
return require('../assets/type.png');
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1,25 @@
|
|||||||
|
// Navigation.js
|
||||||
|
|
||||||
|
import { createStackNavigator } from '@react-navigation/stack';
|
||||||
|
import { NavigationContainer } from '@react-navigation/native';
|
||||||
|
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
|
||||||
|
import Home from '../Screens/Home';
|
||||||
|
import Ajout from '../Screens/Ajout';
|
||||||
|
import Details from '../Screens/Details';
|
||||||
|
|
||||||
|
|
||||||
|
export default function Navigation() {
|
||||||
|
const BottomTabNavigator = createBottomTabNavigator();
|
||||||
|
const Stack = createStackNavigator();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NavigationContainer>
|
||||||
|
<Stack.Navigator initialRouteName="Home" >
|
||||||
|
<Stack.Screen name="Home" component={Home} />
|
||||||
|
<Stack.Screen name="Details" component={Ajout}/>
|
||||||
|
</Stack.Navigator>
|
||||||
|
</NavigationContainer>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { View, Text } from 'react-native';
|
||||||
|
|
||||||
|
const StringComponent = (props) => {
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<Text>{props.text}</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default StringComponent;
|
@ -0,0 +1,169 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { View, Text, Image, StyleSheet, Dimensions, ImageBackground, TouchableOpacity, Modal } from 'react-native';
|
||||||
|
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||||
|
import { City, Weather } from '../data/stub';
|
||||||
|
import { getImageSource } from './ImageWeatherType';
|
||||||
|
|
||||||
|
type MeteoProps = {
|
||||||
|
city : City,
|
||||||
|
weather : Weather
|
||||||
|
}
|
||||||
|
|
||||||
|
export function WeatherCard(props: MeteoProps) {
|
||||||
|
|
||||||
|
|
||||||
|
const [showPopup, setShowPopup] = useState(false);
|
||||||
|
|
||||||
|
const togglePopup = () => {
|
||||||
|
setShowPopup(!showPopup);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
|
||||||
|
|
||||||
|
<View style={styles.container}>
|
||||||
|
|
||||||
|
<View style={styles.titleContainer}>
|
||||||
|
<Text style={styles.title}>{props.city.name}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={styles.contentContainer}>
|
||||||
|
<View style={styles.imageContainer}>
|
||||||
|
<Image
|
||||||
|
source={getImageSource(props.weather.weatherType)}
|
||||||
|
style={styles.image}
|
||||||
|
/>
|
||||||
|
<Text style={styles.title} > {props.weather.weatherType} </Text>
|
||||||
|
</View>
|
||||||
|
<View style={styles.iconContainer}>
|
||||||
|
|
||||||
|
<View style={styles.row}>
|
||||||
|
<View style={styles.iconWithText}>
|
||||||
|
<Icon name="thermometer" style={styles.icon} />
|
||||||
|
<Text style={styles.iconText}>{props.weather.temperature} °C</Text>
|
||||||
|
</View>
|
||||||
|
<View style={styles.iconWithText}>
|
||||||
|
<Icon name="eye" style={styles.icon} />
|
||||||
|
<Text style={styles.iconText}>{props.weather.visibility}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={styles.iconWithText}>
|
||||||
|
<Icon name="weather-windy" style={styles.icon} />
|
||||||
|
<Text style={styles.iconText}>{props.weather.windSpeed}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View style={styles.row}>
|
||||||
|
<View style={styles.iconWithText}>
|
||||||
|
<Icon name="gauge" style={styles.icon} />
|
||||||
|
<Text style={styles.iconText}>{props.weather.pressure}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={styles.iconWithText}>
|
||||||
|
<Icon name="water" style={styles.icon} />
|
||||||
|
<Text style={styles.iconText}>{props.weather.humidity}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={styles.iconWithText}>
|
||||||
|
<Icon name="heart" style={styles.icon} />
|
||||||
|
<Text style={styles.iconText}>{props.weather.temperatureFeelsLike}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
</View>
|
||||||
|
<Modal visible={showPopup} animationType="fade" >
|
||||||
|
<View style={styles.popupContainer}>
|
||||||
|
<Text style={styles.popupText}>Popup content</Text>
|
||||||
|
<TouchableOpacity onPress={togglePopup} style={styles.closeButton}>
|
||||||
|
<Icon name="close" style={styles.closeIcon} />
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</Modal>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
|
||||||
|
container: {
|
||||||
|
backgroundColor: 'rgba(255, 255, 255, 0.5)',
|
||||||
|
borderRadius: 8,
|
||||||
|
borderWidth: 2,
|
||||||
|
borderColor:'rgba(200, 200, 200, 0.5)',
|
||||||
|
marginBottom: 16,
|
||||||
|
alignSelf: 'center',
|
||||||
|
width: '75%', // 3/4 de la largeur de l'écran
|
||||||
|
},
|
||||||
|
titleContainer: {
|
||||||
|
|
||||||
|
padding: 8,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
contentContainer: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
padding: 16,
|
||||||
|
},
|
||||||
|
imageContainer: {
|
||||||
|
marginRight: 16,
|
||||||
|
},
|
||||||
|
image: {
|
||||||
|
width: 80,
|
||||||
|
height: 80,
|
||||||
|
borderRadius: 15,
|
||||||
|
},
|
||||||
|
iconContainer: {
|
||||||
|
flex: 1,
|
||||||
|
flexDirection: 'column',
|
||||||
|
},
|
||||||
|
row: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
marginBottom: 8,
|
||||||
|
},
|
||||||
|
iconWithText: {
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
fontSize: 20,
|
||||||
|
color: '#333333',
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: '#333333',
|
||||||
|
borderRadius: 8,
|
||||||
|
padding: 8,
|
||||||
|
marginBottom: 8,
|
||||||
|
},
|
||||||
|
iconText: {
|
||||||
|
marginTop: 4,
|
||||||
|
fontSize: 12,
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
popupContainer: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
popupText: {
|
||||||
|
fontSize: 24,
|
||||||
|
color: '#FFFFFF',
|
||||||
|
marginBottom: 16,
|
||||||
|
},
|
||||||
|
closeButton: {
|
||||||
|
position: 'absolute',
|
||||||
|
top: 16,
|
||||||
|
right: 16,
|
||||||
|
backgroundColor: '#FFFFFF',
|
||||||
|
borderRadius: 20,
|
||||||
|
padding: 8,
|
||||||
|
},
|
||||||
|
closeIcon: {
|
||||||
|
fontSize: 20,
|
||||||
|
color: '#333333',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { View, Text, Button, StyleSheet } from 'react-native';
|
||||||
|
import { Weather } from '../data/stub';
|
||||||
|
|
||||||
|
|
||||||
|
const Ajout = ({route}) => {
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<Text style={styles.text}>Bienvenu sur mon application {route.params.weather.city.name} </Text>
|
||||||
|
<Button
|
||||||
|
title="Démarrez ici"
|
||||||
|
onPress={() => {
|
||||||
|
// Logique à exécuter lors de l'appui sur le bouton
|
||||||
|
console.log("Le bouton a été appuyé !");
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
fontSize: 24,
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Ajout;
|
@ -0,0 +1,35 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { View, Text, Button } from 'react-native';
|
||||||
|
|
||||||
|
const TaskDetailsScreen = ({ route, navigation }) => {
|
||||||
|
const { taskId } = route.params;
|
||||||
|
|
||||||
|
// Fonction de modification du statut de la tâche
|
||||||
|
const toggleTaskStatus = () => {
|
||||||
|
// Implémentez ici la logique pour modifier le statut de la tâche
|
||||||
|
// en fonction de l'ID de la tâche taskId
|
||||||
|
console.log('Statut de la tâche modifié');
|
||||||
|
};
|
||||||
|
|
||||||
|
// Obtenez les détails de la tâche en fonction de l'ID de la tâche taskId
|
||||||
|
// Vous pouvez utiliser votre propre logique pour récupérer les détails de la tâche
|
||||||
|
const taskDetails = {
|
||||||
|
id: taskId,
|
||||||
|
title: 'Acheter des courses',
|
||||||
|
description: 'Aliments, produits d\'entretien, etc.',
|
||||||
|
completed: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={{ flex: 1, padding: 16 }}>
|
||||||
|
<Text style={{ fontSize: 20, fontWeight: 'bold', marginBottom: 8 }}>{taskDetails.title}</Text>
|
||||||
|
<Text style={{ fontSize: 16, marginBottom: 16 }}>{taskDetails.description}</Text>
|
||||||
|
<Text style={{ fontSize: 16, color: taskDetails.completed ? 'green' : 'red' }}>
|
||||||
|
{taskDetails.completed ? 'Complétée' : 'Non complétée'}
|
||||||
|
</Text>
|
||||||
|
<Button title="Modifier le statut" onPress={toggleTaskStatus} />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TaskDetailsScreen;
|
@ -0,0 +1,53 @@
|
|||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { Button, FlatList, ScrollView, StyleSheet, TextInput, TouchableHighlight, View } from 'react-native';
|
||||||
|
import { WeatherCard } from '../Components/WeatherCard';
|
||||||
|
import { useNavigation } from '@react-navigation/native';
|
||||||
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
import { SearchBar } from 'react-native-elements';
|
||||||
|
import { getWeathersList } from "../Actions/thunk/actionListWeather";
|
||||||
|
|
||||||
|
const Home = () => {
|
||||||
|
const [search, setSearch] = useState('');
|
||||||
|
const navigation = useNavigation();
|
||||||
|
const data = useSelector(state => state.appReducer.weathers);
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const loadWeathers = async () => {
|
||||||
|
await dispatch(getWeathersList());
|
||||||
|
};
|
||||||
|
loadWeathers();
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<View>
|
||||||
|
<SearchBar
|
||||||
|
placeholder="Rechercher..."
|
||||||
|
onChangeText={(text) => setSearch(text)}
|
||||||
|
value={search}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<FlatList
|
||||||
|
data={data.filter(item => item.city.name.toLowerCase().includes(search.toLowerCase()))}
|
||||||
|
renderItem={({ item }) => (
|
||||||
|
<TouchableHighlight onPress={() => navigation.navigate("Details", { "weather": item })}>
|
||||||
|
<WeatherCard city={item.city} weather={item} />
|
||||||
|
</TouchableHighlight>
|
||||||
|
)}
|
||||||
|
keyExtractor={(item) => item.city.name}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
padding: 16,
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Home;
|
@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"expo": {
|
||||||
|
"name": "my-app",
|
||||||
|
"slug": "my-app",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"orientation": "portrait",
|
||||||
|
"icon": "./assets/icon.png",
|
||||||
|
"userInterfaceStyle": "light",
|
||||||
|
"splash": {
|
||||||
|
"image": "./assets/splash.png",
|
||||||
|
"resizeMode": "contain",
|
||||||
|
"backgroundColor": "#ffffff"
|
||||||
|
},
|
||||||
|
"assetBundlePatterns": [
|
||||||
|
"**/*"
|
||||||
|
],
|
||||||
|
"ios": {
|
||||||
|
"supportsTablet": true
|
||||||
|
},
|
||||||
|
"android": {
|
||||||
|
"adaptiveIcon": {
|
||||||
|
"foregroundImage": "./assets/adaptive-icon.png",
|
||||||
|
"backgroundColor": "#ffffff"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"web": {
|
||||||
|
"favicon": "./assets/favicon.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 29 KiB |
@ -0,0 +1,6 @@
|
|||||||
|
module.exports = function(api) {
|
||||||
|
api.cache(true);
|
||||||
|
return {
|
||||||
|
presets: ['babel-preset-expo'],
|
||||||
|
};
|
||||||
|
};
|
@ -0,0 +1,188 @@
|
|||||||
|
export class City {
|
||||||
|
private _name: string;
|
||||||
|
private _latitude: number;
|
||||||
|
private _longitude: number;
|
||||||
|
|
||||||
|
constructor(name: string, latitude: number, longitude: number) {
|
||||||
|
this._name = name;
|
||||||
|
this._latitude = latitude;
|
||||||
|
this._longitude = longitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
get name(): string {
|
||||||
|
return this._name;
|
||||||
|
}
|
||||||
|
|
||||||
|
set name(value: string) {
|
||||||
|
this._name = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get latitude(): number {
|
||||||
|
return this._latitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
set latitude(value: number) {
|
||||||
|
this._latitude = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get longitude(): number {
|
||||||
|
return this._longitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
set longitude(value: number) {
|
||||||
|
this._longitude = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Weather {
|
||||||
|
private _at: string;
|
||||||
|
private _visibility: number;
|
||||||
|
private _weatherType: string;
|
||||||
|
private _weatherDescription: string;
|
||||||
|
private _temperature: number;
|
||||||
|
private _temperatureFeelsLike: number;
|
||||||
|
private _humidity: number;
|
||||||
|
private _windSpeed: number;
|
||||||
|
private _pressure: number;
|
||||||
|
private _city: City;
|
||||||
|
|
||||||
|
constructor(at: string, visibility: number, weatherType: string, weatherDescription: string, temperature: number, temperatureFeelsLike: number, humidity: number, windSpeed: number, pressure: number, city: City) {
|
||||||
|
this._at = at;
|
||||||
|
this._visibility = visibility;
|
||||||
|
this._weatherType = weatherType;
|
||||||
|
this._weatherDescription = weatherDescription;
|
||||||
|
this._temperature = temperature;
|
||||||
|
this._temperatureFeelsLike = temperatureFeelsLike;
|
||||||
|
this._humidity = humidity;
|
||||||
|
this._windSpeed = windSpeed;
|
||||||
|
this._pressure = pressure;
|
||||||
|
this._city = city;
|
||||||
|
}
|
||||||
|
|
||||||
|
get at(): string {
|
||||||
|
return this._at;
|
||||||
|
}
|
||||||
|
|
||||||
|
set at(value: string) {
|
||||||
|
this._at = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get visibility(): number {
|
||||||
|
return this._visibility;
|
||||||
|
}
|
||||||
|
|
||||||
|
set visibility(value: number) {
|
||||||
|
this._visibility = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get weatherType(): string {
|
||||||
|
return this._weatherType;
|
||||||
|
}
|
||||||
|
|
||||||
|
set weatherType(value: string) {
|
||||||
|
this._weatherType = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get weatherDescription(): string {
|
||||||
|
return this._weatherDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
set weatherDescription(value: string) {
|
||||||
|
this._weatherDescription = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get temperature(): number {
|
||||||
|
return this._temperature;
|
||||||
|
}
|
||||||
|
|
||||||
|
set temperature(value: number) {
|
||||||
|
this._temperature = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get temperatureFeelsLike(): number {
|
||||||
|
return this._temperatureFeelsLike;
|
||||||
|
}
|
||||||
|
|
||||||
|
set temperatureFeelsLike(value: number) {
|
||||||
|
this._temperatureFeelsLike = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get humidity(): number {
|
||||||
|
return this._humidity;
|
||||||
|
}
|
||||||
|
|
||||||
|
set humidity(value: number) {
|
||||||
|
this._humidity = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get windSpeed(): number {
|
||||||
|
return this._windSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
set windSpeed(value: number) {
|
||||||
|
this._windSpeed = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get pressure(): number {
|
||||||
|
return this._pressure;
|
||||||
|
}
|
||||||
|
|
||||||
|
set pressure(value: number) {
|
||||||
|
this._pressure = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get city(): City {
|
||||||
|
return this._city;
|
||||||
|
}
|
||||||
|
|
||||||
|
set city(value: City) {
|
||||||
|
this._city = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CITIES_DATA: City[] = [
|
||||||
|
new City("Paris", 48.866667, 2.333333),
|
||||||
|
new City("Clermont-Ferrand", 45.777222, 3.087025),
|
||||||
|
new City("Lyon", 45.764043, 4.835659),
|
||||||
|
new City("Marseille", 43.296482, 5.36978),
|
||||||
|
new City("Bruxelles", 50.85034, 4.35171),
|
||||||
|
];
|
||||||
|
|
||||||
|
export const FAVORITE_CITY_DATA =
|
||||||
|
new City("Clermont-Ferrand", 45.777222, 3.087025);
|
||||||
|
|
||||||
|
export const DEFAULT_SELECTED_CITY_DATA: City =
|
||||||
|
new City("Paris", 48.866667, 2.333333);
|
||||||
|
|
||||||
|
export const WEATHER_DATA: Weather[] = [
|
||||||
|
new Weather("2023-01-22 09:55:59", 10000, "Nuageux",
|
||||||
|
"couvert", 0.52, -4.34,
|
||||||
|
82, 5.14, 1032,
|
||||||
|
new City("Paris", 48.866667, 2.333333)
|
||||||
|
),
|
||||||
|
new Weather("2023-01-22 09:55:59", 10000, "Nuageux",
|
||||||
|
"couvert", 0.52, -4.34,
|
||||||
|
82, 5.14, 1032,
|
||||||
|
new City("Clermont-Ferrand", 45.777222, 3.087025)
|
||||||
|
),
|
||||||
|
new Weather("2023-01-22 09:55:59", 10000, "Nuageux",
|
||||||
|
"couvert", 0.52, -4.34,
|
||||||
|
82, 5.14, 1032,
|
||||||
|
new City("Lyon", 45.764043, 4.835659)
|
||||||
|
),
|
||||||
|
new Weather("2023-01-22 09:55:59", 10000, "Nuageux",
|
||||||
|
"couvert", 0.52, -4.34,
|
||||||
|
82, 5.14, 1032,
|
||||||
|
new City("Marseille", 43.296482, 5.36978)
|
||||||
|
),
|
||||||
|
new Weather("2023-01-22 09:55:59", 10000, "Nuageux",
|
||||||
|
"couvert", 0.52, -4.34,
|
||||||
|
82, 5.14, 1032,
|
||||||
|
new City("Bruxelles", 50.85034, 4.35171)
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
export const getCurrentWeather = (cityName: string) => {
|
||||||
|
if (cityName === undefined) return {};
|
||||||
|
return WEATHER_DATA.filter(elt => elt.city.name === cityName)[0];
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
../acorn/bin/acorn
|
@ -0,0 +1 @@
|
|||||||
|
../atob/bin/atob.js
|
@ -0,0 +1 @@
|
|||||||
|
../browserslist/cli.js
|
@ -0,0 +1 @@
|
|||||||
|
../envinfo/dist/cli.js
|
@ -0,0 +1 @@
|
|||||||
|
../esprima/bin/esparse.js
|
@ -0,0 +1 @@
|
|||||||
|
../esprima/bin/esvalidate.js
|
@ -0,0 +1 @@
|
|||||||
|
../@expo/xcpretty/build/cli.js
|
@ -0,0 +1 @@
|
|||||||
|
../expo/bin/cli.js
|
@ -0,0 +1 @@
|
|||||||
|
../@expo/cli/build/bin/cli
|
@ -0,0 +1 @@
|
|||||||
|
../expo-modules-autolinking/bin/expo-modules-autolinking.js
|
@ -0,0 +1 @@
|
|||||||
|
../react-native-vector-icons/bin/fa5-upgrade.sh
|
@ -0,0 +1 @@
|
|||||||
|
../fast-xml-parser/src/cli/cli.js
|
@ -0,0 +1 @@
|
|||||||
|
../react-native-vector-icons/bin/generate-icon.js
|
@ -0,0 +1 @@
|
|||||||
|
../image-size/bin/image-size.js
|
@ -0,0 +1 @@
|
|||||||
|
../is-docker/cli.js
|
@ -0,0 +1 @@
|
|||||||
|
../js-yaml/bin/js-yaml.js
|
@ -0,0 +1 @@
|
|||||||
|
../jscodeshift/bin/jscodeshift.js
|
@ -0,0 +1 @@
|
|||||||
|
../jsesc/bin/jsesc
|
@ -0,0 +1 @@
|
|||||||
|
../json5/lib/cli.js
|
@ -0,0 +1 @@
|
|||||||
|
../logkitty/bin/logkitty.js
|
@ -0,0 +1 @@
|
|||||||
|
../loose-envify/cli.js
|
@ -0,0 +1 @@
|
|||||||
|
../md5-file/cli.js
|
@ -0,0 +1 @@
|
|||||||
|
../metro/src/cli.js
|
@ -0,0 +1 @@
|
|||||||
|
../metro-inspector-proxy/src/cli.js
|
@ -0,0 +1 @@
|
|||||||
|
../metro-symbolicate/src/index.js
|
@ -0,0 +1 @@
|
|||||||
|
../mime/cli.js
|
@ -0,0 +1 @@
|
|||||||
|
../mkdirp/bin/cmd.js
|
@ -0,0 +1 @@
|
|||||||
|
../nanoid/bin/nanoid.cjs
|
@ -0,0 +1 @@
|
|||||||
|
../ncp/bin/ncp
|
@ -0,0 +1 @@
|
|||||||
|
../opencollective-postinstall/index.js
|
@ -0,0 +1 @@
|
|||||||
|
../@babel/parser/bin/babel-parser.js
|
@ -0,0 +1 @@
|
|||||||
|
../qrcode-terminal/bin/qrcode-terminal.js
|
@ -0,0 +1 @@
|
|||||||
|
../rc/cli.js
|
@ -0,0 +1 @@
|
|||||||
|
../@react-native-community/cli/build/bin.js
|
@ -0,0 +1 @@
|
|||||||
|
../regjsparser/bin/parser
|
@ -0,0 +1 @@
|
|||||||
|
../resolve/bin/resolve
|
@ -0,0 +1 @@
|
|||||||
|
../rimraf/bin.js
|
@ -0,0 +1 @@
|
|||||||
|
../semver/bin/semver.js
|
@ -0,0 +1 @@
|
|||||||
|
../sucrase/bin/sucrase
|
@ -0,0 +1 @@
|
|||||||
|
../sucrase/bin/sucrase-node
|
@ -0,0 +1 @@
|
|||||||
|
../terser/bin/terser
|
@ -0,0 +1 @@
|
|||||||
|
../typescript/bin/tsc
|
@ -0,0 +1 @@
|
|||||||
|
../typescript/bin/tsserver
|
@ -0,0 +1 @@
|
|||||||
|
../uglify-es/bin/uglifyjs
|
@ -0,0 +1 @@
|
|||||||
|
../update-browserslist-db/cli.js
|
@ -0,0 +1 @@
|
|||||||
|
../uuid/bin/uuid
|
@ -0,0 +1 @@
|
|||||||
|
../which/bin/which
|
@ -0,0 +1,202 @@
|
|||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
@ -0,0 +1,218 @@
|
|||||||
|
# @ampproject/remapping
|
||||||
|
|
||||||
|
> Remap sequential sourcemaps through transformations to point at the original source code
|
||||||
|
|
||||||
|
Remapping allows you to take the sourcemaps generated through transforming your code and "remap"
|
||||||
|
them to the original source locations. Think "my minified code, transformed with babel and bundled
|
||||||
|
with webpack", all pointing to the correct location in your original source code.
|
||||||
|
|
||||||
|
With remapping, none of your source code transformations need to be aware of the input's sourcemap,
|
||||||
|
they only need to generate an output sourcemap. This greatly simplifies building custom
|
||||||
|
transformations (think a find-and-replace).
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm install @ampproject/remapping
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function remapping(
|
||||||
|
map: SourceMap | SourceMap[],
|
||||||
|
loader: (file: string, ctx: LoaderContext) => (SourceMap | null | undefined),
|
||||||
|
options?: { excludeContent: boolean, decodedMappings: boolean }
|
||||||
|
): SourceMap;
|
||||||
|
|
||||||
|
// LoaderContext gives the loader the importing sourcemap, tree depth, the ability to override the
|
||||||
|
// "source" location (where child sources are resolved relative to, or the location of original
|
||||||
|
// source), and the ability to override the "content" of an original source for inclusion in the
|
||||||
|
// output sourcemap.
|
||||||
|
type LoaderContext = {
|
||||||
|
readonly importer: string;
|
||||||
|
readonly depth: number;
|
||||||
|
source: string;
|
||||||
|
content: string | null | undefined;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`remapping` takes the final output sourcemap, and a `loader` function. For every source file pointer
|
||||||
|
in the sourcemap, the `loader` will be called with the resolved path. If the path itself represents
|
||||||
|
a transformed file (it has a sourcmap associated with it), then the `loader` should return that
|
||||||
|
sourcemap. If not, the path will be treated as an original, untransformed source code.
|
||||||
|
|
||||||
|
```js
|
||||||
|
// Babel transformed "helloworld.js" into "transformed.js"
|
||||||
|
const transformedMap = JSON.stringify({
|
||||||
|
file: 'transformed.js',
|
||||||
|
// 1st column of 2nd line of output file translates into the 1st source
|
||||||
|
// file, line 3, column 2
|
||||||
|
mappings: ';CAEE',
|
||||||
|
sources: ['helloworld.js'],
|
||||||
|
version: 3,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Uglify minified "transformed.js" into "transformed.min.js"
|
||||||
|
const minifiedTransformedMap = JSON.stringify({
|
||||||
|
file: 'transformed.min.js',
|
||||||
|
// 0th column of 1st line of output file translates into the 1st source
|
||||||
|
// file, line 2, column 1.
|
||||||
|
mappings: 'AACC',
|
||||||
|
names: [],
|
||||||
|
sources: ['transformed.js'],
|
||||||
|
version: 3,
|
||||||
|
});
|
||||||
|
|
||||||
|
const remapped = remapping(
|
||||||
|
minifiedTransformedMap,
|
||||||
|
(file, ctx) => {
|
||||||
|
|
||||||
|
// The "transformed.js" file is an transformed file.
|
||||||
|
if (file === 'transformed.js') {
|
||||||
|
// The root importer is empty.
|
||||||
|
console.assert(ctx.importer === '');
|
||||||
|
// The depth in the sourcemap tree we're currently loading.
|
||||||
|
// The root `minifiedTransformedMap` is depth 0, and its source children are depth 1, etc.
|
||||||
|
console.assert(ctx.depth === 1);
|
||||||
|
|
||||||
|
return transformedMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loader will be called to load transformedMap's source file pointers as well.
|
||||||
|
console.assert(file === 'helloworld.js');
|
||||||
|
// `transformed.js`'s sourcemap points into `helloworld.js`.
|
||||||
|
console.assert(ctx.importer === 'transformed.js');
|
||||||
|
// This is a source child of `transformed`, which is a source child of `minifiedTransformedMap`.
|
||||||
|
console.assert(ctx.depth === 2);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(remapped);
|
||||||
|
// {
|
||||||
|
// file: 'transpiled.min.js',
|
||||||
|
// mappings: 'AAEE',
|
||||||
|
// sources: ['helloworld.js'],
|
||||||
|
// version: 3,
|
||||||
|
// };
|
||||||
|
```
|
||||||
|
|
||||||
|
In this example, `loader` will be called twice:
|
||||||
|
|
||||||
|
1. `"transformed.js"`, the first source file pointer in the `minifiedTransformedMap`. We return the
|
||||||
|
associated sourcemap for it (its a transformed file, after all) so that sourcemap locations can
|
||||||
|
be traced through it into the source files it represents.
|
||||||
|
2. `"helloworld.js"`, our original, unmodified source code. This file does not have a sourcemap, so
|
||||||
|
we return `null`.
|
||||||
|
|
||||||
|
The `remapped` sourcemap now points from `transformed.min.js` into locations in `helloworld.js`. If
|
||||||
|
you were to read the `mappings`, it says "0th column of the first line output line points to the 1st
|
||||||
|
column of the 2nd line of the file `helloworld.js`".
|
||||||
|
|
||||||
|
### Multiple transformations of a file
|
||||||
|
|
||||||
|
As a convenience, if you have multiple single-source transformations of a file, you may pass an
|
||||||
|
array of sourcemap files in the order of most-recent transformation sourcemap first. Note that this
|
||||||
|
changes the `importer` and `depth` of each call to our loader. So our above example could have been
|
||||||
|
written as:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const remapped = remapping(
|
||||||
|
[minifiedTransformedMap, transformedMap],
|
||||||
|
() => null
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(remapped);
|
||||||
|
// {
|
||||||
|
// file: 'transpiled.min.js',
|
||||||
|
// mappings: 'AAEE',
|
||||||
|
// sources: ['helloworld.js'],
|
||||||
|
// version: 3,
|
||||||
|
// };
|
||||||
|
```
|
||||||
|
|
||||||
|
### Advanced control of the loading graph
|
||||||
|
|
||||||
|
#### `source`
|
||||||
|
|
||||||
|
The `source` property can overridden to any value to change the location of the current load. Eg,
|
||||||
|
for an original source file, it allows us to change the location to the original source regardless
|
||||||
|
of what the sourcemap source entry says. And for transformed files, it allows us to change the
|
||||||
|
relative resolving location for child sources of the loaded sourcemap.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const remapped = remapping(
|
||||||
|
minifiedTransformedMap,
|
||||||
|
(file, ctx) => {
|
||||||
|
|
||||||
|
if (file === 'transformed.js') {
|
||||||
|
// We pretend the transformed.js file actually exists in the 'src/' directory. When the nested
|
||||||
|
// source files are loaded, they will now be relative to `src/`.
|
||||||
|
ctx.source = 'src/transformed.js';
|
||||||
|
return transformedMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.assert(file === 'src/helloworld.js');
|
||||||
|
// We could futher change the source of this original file, eg, to be inside a nested directory
|
||||||
|
// itself. This will be reflected in the remapped sourcemap.
|
||||||
|
ctx.source = 'src/nested/transformed.js';
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(remapped);
|
||||||
|
// {
|
||||||
|
// …,
|
||||||
|
// sources: ['src/nested/helloworld.js'],
|
||||||
|
// };
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### `content`
|
||||||
|
|
||||||
|
The `content` property can be overridden when we encounter an original source file. Eg, this allows
|
||||||
|
you to manually provide the source content of the original file regardless of whether the
|
||||||
|
`sourcesContent` field is present in the parent sourcemap. It can also be set to `null` to remove
|
||||||
|
the source content.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const remapped = remapping(
|
||||||
|
minifiedTransformedMap,
|
||||||
|
(file, ctx) => {
|
||||||
|
|
||||||
|
if (file === 'transformed.js') {
|
||||||
|
// transformedMap does not include a `sourcesContent` field, so usually the remapped sourcemap
|
||||||
|
// would not include any `sourcesContent` values.
|
||||||
|
return transformedMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.assert(file === 'helloworld.js');
|
||||||
|
// We can read the file to provide the source content.
|
||||||
|
ctx.content = fs.readFileSync(file, 'utf8');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(remapped);
|
||||||
|
// {
|
||||||
|
// …,
|
||||||
|
// sourcesContent: [
|
||||||
|
// 'console.log("Hello world!")',
|
||||||
|
// ],
|
||||||
|
// };
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
#### excludeContent
|
||||||
|
|
||||||
|
By default, `excludeContent` is `false`. Passing `{ excludeContent: true }` will exclude the
|
||||||
|
`sourcesContent` field from the returned sourcemap. This is mainly useful when you want to reduce
|
||||||
|
the size out the sourcemap.
|
||||||
|
|
||||||
|
#### decodedMappings
|
||||||
|
|
||||||
|
By default, `decodedMappings` is `false`. Passing `{ decodedMappings: true }` will leave the
|
||||||
|
`mappings` field in a [decoded state](https://github.com/rich-harris/sourcemap-codec) instead of
|
||||||
|
encoding into a VLQ string.
|
@ -0,0 +1,191 @@
|
|||||||
|
import { decodedMappings, traceSegment, TraceMap } from '@jridgewell/trace-mapping';
|
||||||
|
import { GenMapping, maybeAddSegment, setSourceContent, toDecodedMap, toEncodedMap } from '@jridgewell/gen-mapping';
|
||||||
|
|
||||||
|
const SOURCELESS_MAPPING = /* #__PURE__ */ SegmentObject('', -1, -1, '', null);
|
||||||
|
const EMPTY_SOURCES = [];
|
||||||
|
function SegmentObject(source, line, column, name, content) {
|
||||||
|
return { source, line, column, name, content };
|
||||||
|
}
|
||||||
|
function Source(map, sources, source, content) {
|
||||||
|
return {
|
||||||
|
map,
|
||||||
|
sources,
|
||||||
|
source,
|
||||||
|
content,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* MapSource represents a single sourcemap, with the ability to trace mappings into its child nodes
|
||||||
|
* (which may themselves be SourceMapTrees).
|
||||||
|
*/
|
||||||
|
function MapSource(map, sources) {
|
||||||
|
return Source(map, sources, '', null);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* A "leaf" node in the sourcemap tree, representing an original, unmodified source file. Recursive
|
||||||
|
* segment tracing ends at the `OriginalSource`.
|
||||||
|
*/
|
||||||
|
function OriginalSource(source, content) {
|
||||||
|
return Source(null, EMPTY_SOURCES, source, content);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* traceMappings is only called on the root level SourceMapTree, and begins the process of
|
||||||
|
* resolving each mapping in terms of the original source files.
|
||||||
|
*/
|
||||||
|
function traceMappings(tree) {
|
||||||
|
// TODO: Eventually support sourceRoot, which has to be removed because the sources are already
|
||||||
|
// fully resolved. We'll need to make sources relative to the sourceRoot before adding them.
|
||||||
|
const gen = new GenMapping({ file: tree.map.file });
|
||||||
|
const { sources: rootSources, map } = tree;
|
||||||
|
const rootNames = map.names;
|
||||||
|
const rootMappings = decodedMappings(map);
|
||||||
|
for (let i = 0; i < rootMappings.length; i++) {
|
||||||
|
const segments = rootMappings[i];
|
||||||
|
for (let j = 0; j < segments.length; j++) {
|
||||||
|
const segment = segments[j];
|
||||||
|
const genCol = segment[0];
|
||||||
|
let traced = SOURCELESS_MAPPING;
|
||||||
|
// 1-length segments only move the current generated column, there's no source information
|
||||||
|
// to gather from it.
|
||||||
|
if (segment.length !== 1) {
|
||||||
|
const source = rootSources[segment[1]];
|
||||||
|
traced = originalPositionFor(source, segment[2], segment[3], segment.length === 5 ? rootNames[segment[4]] : '');
|
||||||
|
// If the trace is invalid, then the trace ran into a sourcemap that doesn't contain a
|
||||||
|
// respective segment into an original source.
|
||||||
|
if (traced == null)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const { column, line, name, content, source } = traced;
|
||||||
|
maybeAddSegment(gen, i, genCol, source, line, column, name);
|
||||||
|
if (source && content != null)
|
||||||
|
setSourceContent(gen, source, content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return gen;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* originalPositionFor is only called on children SourceMapTrees. It recurses down into its own
|
||||||
|
* child SourceMapTrees, until we find the original source map.
|
||||||
|
*/
|
||||||
|
function originalPositionFor(source, line, column, name) {
|
||||||
|
if (!source.map) {
|
||||||
|
return SegmentObject(source.source, line, column, name, source.content);
|
||||||
|
}
|
||||||
|
const segment = traceSegment(source.map, line, column);
|
||||||
|
// If we couldn't find a segment, then this doesn't exist in the sourcemap.
|
||||||
|
if (segment == null)
|
||||||
|
return null;
|
||||||
|
// 1-length segments only move the current generated column, there's no source information
|
||||||
|
// to gather from it.
|
||||||
|
if (segment.length === 1)
|
||||||
|
return SOURCELESS_MAPPING;
|
||||||
|
return originalPositionFor(source.sources[segment[1]], segment[2], segment[3], segment.length === 5 ? source.map.names[segment[4]] : name);
|
||||||
|
}
|
||||||
|
|
||||||
|
function asArray(value) {
|
||||||
|
if (Array.isArray(value))
|
||||||
|
return value;
|
||||||
|
return [value];
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Recursively builds a tree structure out of sourcemap files, with each node
|
||||||
|
* being either an `OriginalSource` "leaf" or a `SourceMapTree` composed of
|
||||||
|
* `OriginalSource`s and `SourceMapTree`s.
|
||||||
|
*
|
||||||
|
* Every sourcemap is composed of a collection of source files and mappings
|
||||||
|
* into locations of those source files. When we generate a `SourceMapTree` for
|
||||||
|
* the sourcemap, we attempt to load each source file's own sourcemap. If it
|
||||||
|
* does not have an associated sourcemap, it is considered an original,
|
||||||
|
* unmodified source file.
|
||||||
|
*/
|
||||||
|
function buildSourceMapTree(input, loader) {
|
||||||
|
const maps = asArray(input).map((m) => new TraceMap(m, ''));
|
||||||
|
const map = maps.pop();
|
||||||
|
for (let i = 0; i < maps.length; i++) {
|
||||||
|
if (maps[i].sources.length > 1) {
|
||||||
|
throw new Error(`Transformation map ${i} must have exactly one source file.\n` +
|
||||||
|
'Did you specify these with the most recent transformation maps first?');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let tree = build(map, loader, '', 0);
|
||||||
|
for (let i = maps.length - 1; i >= 0; i--) {
|
||||||
|
tree = MapSource(maps[i], [tree]);
|
||||||
|
}
|
||||||
|
return tree;
|
||||||
|
}
|
||||||
|
function build(map, loader, importer, importerDepth) {
|
||||||
|
const { resolvedSources, sourcesContent } = map;
|
||||||
|
const depth = importerDepth + 1;
|
||||||
|
const children = resolvedSources.map((sourceFile, i) => {
|
||||||
|
// The loading context gives the loader more information about why this file is being loaded
|
||||||
|
// (eg, from which importer). It also allows the loader to override the location of the loaded
|
||||||
|
// sourcemap/original source, or to override the content in the sourcesContent field if it's
|
||||||
|
// an unmodified source file.
|
||||||
|
const ctx = {
|
||||||
|
importer,
|
||||||
|
depth,
|
||||||
|
source: sourceFile || '',
|
||||||
|
content: undefined,
|
||||||
|
};
|
||||||
|
// Use the provided loader callback to retrieve the file's sourcemap.
|
||||||
|
// TODO: We should eventually support async loading of sourcemap files.
|
||||||
|
const sourceMap = loader(ctx.source, ctx);
|
||||||
|
const { source, content } = ctx;
|
||||||
|
// If there is a sourcemap, then we need to recurse into it to load its source files.
|
||||||
|
if (sourceMap)
|
||||||
|
return build(new TraceMap(sourceMap, source), loader, source, depth);
|
||||||
|
// Else, it's an an unmodified source file.
|
||||||
|
// The contents of this unmodified source file can be overridden via the loader context,
|
||||||
|
// allowing it to be explicitly null or a string. If it remains undefined, we fall back to
|
||||||
|
// the importing sourcemap's `sourcesContent` field.
|
||||||
|
const sourceContent = content !== undefined ? content : sourcesContent ? sourcesContent[i] : null;
|
||||||
|
return OriginalSource(source, sourceContent);
|
||||||
|
});
|
||||||
|
return MapSource(map, children);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SourceMap v3 compatible sourcemap, which only includes fields that were
|
||||||
|
* provided to it.
|
||||||
|
*/
|
||||||
|
class SourceMap {
|
||||||
|
constructor(map, options) {
|
||||||
|
const out = options.decodedMappings ? toDecodedMap(map) : toEncodedMap(map);
|
||||||
|
this.version = out.version; // SourceMap spec says this should be first.
|
||||||
|
this.file = out.file;
|
||||||
|
this.mappings = out.mappings;
|
||||||
|
this.names = out.names;
|
||||||
|
this.sourceRoot = out.sourceRoot;
|
||||||
|
this.sources = out.sources;
|
||||||
|
if (!options.excludeContent) {
|
||||||
|
this.sourcesContent = out.sourcesContent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
toString() {
|
||||||
|
return JSON.stringify(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Traces through all the mappings in the root sourcemap, through the sources
|
||||||
|
* (and their sourcemaps), all the way back to the original source location.
|
||||||
|
*
|
||||||
|
* `loader` will be called every time we encounter a source file. If it returns
|
||||||
|
* a sourcemap, we will recurse into that sourcemap to continue the trace. If
|
||||||
|
* it returns a falsey value, that source file is treated as an original,
|
||||||
|
* unmodified source file.
|
||||||
|
*
|
||||||
|
* Pass `excludeContent` to exclude any self-containing source file content
|
||||||
|
* from the output sourcemap.
|
||||||
|
*
|
||||||
|
* Pass `decodedMappings` to receive a SourceMap with decoded (instead of
|
||||||
|
* VLQ encoded) mappings.
|
||||||
|
*/
|
||||||
|
function remapping(input, loader, options) {
|
||||||
|
const opts = typeof options === 'object' ? options : { excludeContent: !!options, decodedMappings: false };
|
||||||
|
const tree = buildSourceMapTree(input, loader);
|
||||||
|
return new SourceMap(traceMappings(tree), opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { remapping as default };
|
||||||
|
//# sourceMappingURL=remapping.mjs.map
|
@ -0,0 +1,196 @@
|
|||||||
|
(function (global, factory) {
|
||||||
|
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@jridgewell/trace-mapping'), require('@jridgewell/gen-mapping')) :
|
||||||
|
typeof define === 'function' && define.amd ? define(['@jridgewell/trace-mapping', '@jridgewell/gen-mapping'], factory) :
|
||||||
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.remapping = factory(global.traceMapping, global.genMapping));
|
||||||
|
})(this, (function (traceMapping, genMapping) { 'use strict';
|
||||||
|
|
||||||
|
const SOURCELESS_MAPPING = /* #__PURE__ */ SegmentObject('', -1, -1, '', null);
|
||||||
|
const EMPTY_SOURCES = [];
|
||||||
|
function SegmentObject(source, line, column, name, content) {
|
||||||
|
return { source, line, column, name, content };
|
||||||
|
}
|
||||||
|
function Source(map, sources, source, content) {
|
||||||
|
return {
|
||||||
|
map,
|
||||||
|
sources,
|
||||||
|
source,
|
||||||
|
content,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* MapSource represents a single sourcemap, with the ability to trace mappings into its child nodes
|
||||||
|
* (which may themselves be SourceMapTrees).
|
||||||
|
*/
|
||||||
|
function MapSource(map, sources) {
|
||||||
|
return Source(map, sources, '', null);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* A "leaf" node in the sourcemap tree, representing an original, unmodified source file. Recursive
|
||||||
|
* segment tracing ends at the `OriginalSource`.
|
||||||
|
*/
|
||||||
|
function OriginalSource(source, content) {
|
||||||
|
return Source(null, EMPTY_SOURCES, source, content);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* traceMappings is only called on the root level SourceMapTree, and begins the process of
|
||||||
|
* resolving each mapping in terms of the original source files.
|
||||||
|
*/
|
||||||
|
function traceMappings(tree) {
|
||||||
|
// TODO: Eventually support sourceRoot, which has to be removed because the sources are already
|
||||||
|
// fully resolved. We'll need to make sources relative to the sourceRoot before adding them.
|
||||||
|
const gen = new genMapping.GenMapping({ file: tree.map.file });
|
||||||
|
const { sources: rootSources, map } = tree;
|
||||||
|
const rootNames = map.names;
|
||||||
|
const rootMappings = traceMapping.decodedMappings(map);
|
||||||
|
for (let i = 0; i < rootMappings.length; i++) {
|
||||||
|
const segments = rootMappings[i];
|
||||||
|
for (let j = 0; j < segments.length; j++) {
|
||||||
|
const segment = segments[j];
|
||||||
|
const genCol = segment[0];
|
||||||
|
let traced = SOURCELESS_MAPPING;
|
||||||
|
// 1-length segments only move the current generated column, there's no source information
|
||||||
|
// to gather from it.
|
||||||
|
if (segment.length !== 1) {
|
||||||
|
const source = rootSources[segment[1]];
|
||||||
|
traced = originalPositionFor(source, segment[2], segment[3], segment.length === 5 ? rootNames[segment[4]] : '');
|
||||||
|
// If the trace is invalid, then the trace ran into a sourcemap that doesn't contain a
|
||||||
|
// respective segment into an original source.
|
||||||
|
if (traced == null)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const { column, line, name, content, source } = traced;
|
||||||
|
genMapping.maybeAddSegment(gen, i, genCol, source, line, column, name);
|
||||||
|
if (source && content != null)
|
||||||
|
genMapping.setSourceContent(gen, source, content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return gen;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* originalPositionFor is only called on children SourceMapTrees. It recurses down into its own
|
||||||
|
* child SourceMapTrees, until we find the original source map.
|
||||||
|
*/
|
||||||
|
function originalPositionFor(source, line, column, name) {
|
||||||
|
if (!source.map) {
|
||||||
|
return SegmentObject(source.source, line, column, name, source.content);
|
||||||
|
}
|
||||||
|
const segment = traceMapping.traceSegment(source.map, line, column);
|
||||||
|
// If we couldn't find a segment, then this doesn't exist in the sourcemap.
|
||||||
|
if (segment == null)
|
||||||
|
return null;
|
||||||
|
// 1-length segments only move the current generated column, there's no source information
|
||||||
|
// to gather from it.
|
||||||
|
if (segment.length === 1)
|
||||||
|
return SOURCELESS_MAPPING;
|
||||||
|
return originalPositionFor(source.sources[segment[1]], segment[2], segment[3], segment.length === 5 ? source.map.names[segment[4]] : name);
|
||||||
|
}
|
||||||
|
|
||||||
|
function asArray(value) {
|
||||||
|
if (Array.isArray(value))
|
||||||
|
return value;
|
||||||
|
return [value];
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Recursively builds a tree structure out of sourcemap files, with each node
|
||||||
|
* being either an `OriginalSource` "leaf" or a `SourceMapTree` composed of
|
||||||
|
* `OriginalSource`s and `SourceMapTree`s.
|
||||||
|
*
|
||||||
|
* Every sourcemap is composed of a collection of source files and mappings
|
||||||
|
* into locations of those source files. When we generate a `SourceMapTree` for
|
||||||
|
* the sourcemap, we attempt to load each source file's own sourcemap. If it
|
||||||
|
* does not have an associated sourcemap, it is considered an original,
|
||||||
|
* unmodified source file.
|
||||||
|
*/
|
||||||
|
function buildSourceMapTree(input, loader) {
|
||||||
|
const maps = asArray(input).map((m) => new traceMapping.TraceMap(m, ''));
|
||||||
|
const map = maps.pop();
|
||||||
|
for (let i = 0; i < maps.length; i++) {
|
||||||
|
if (maps[i].sources.length > 1) {
|
||||||
|
throw new Error(`Transformation map ${i} must have exactly one source file.\n` +
|
||||||
|
'Did you specify these with the most recent transformation maps first?');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let tree = build(map, loader, '', 0);
|
||||||
|
for (let i = maps.length - 1; i >= 0; i--) {
|
||||||
|
tree = MapSource(maps[i], [tree]);
|
||||||
|
}
|
||||||
|
return tree;
|
||||||
|
}
|
||||||
|
function build(map, loader, importer, importerDepth) {
|
||||||
|
const { resolvedSources, sourcesContent } = map;
|
||||||
|
const depth = importerDepth + 1;
|
||||||
|
const children = resolvedSources.map((sourceFile, i) => {
|
||||||
|
// The loading context gives the loader more information about why this file is being loaded
|
||||||
|
// (eg, from which importer). It also allows the loader to override the location of the loaded
|
||||||
|
// sourcemap/original source, or to override the content in the sourcesContent field if it's
|
||||||
|
// an unmodified source file.
|
||||||
|
const ctx = {
|
||||||
|
importer,
|
||||||
|
depth,
|
||||||
|
source: sourceFile || '',
|
||||||
|
content: undefined,
|
||||||
|
};
|
||||||
|
// Use the provided loader callback to retrieve the file's sourcemap.
|
||||||
|
// TODO: We should eventually support async loading of sourcemap files.
|
||||||
|
const sourceMap = loader(ctx.source, ctx);
|
||||||
|
const { source, content } = ctx;
|
||||||
|
// If there is a sourcemap, then we need to recurse into it to load its source files.
|
||||||
|
if (sourceMap)
|
||||||
|
return build(new traceMapping.TraceMap(sourceMap, source), loader, source, depth);
|
||||||
|
// Else, it's an an unmodified source file.
|
||||||
|
// The contents of this unmodified source file can be overridden via the loader context,
|
||||||
|
// allowing it to be explicitly null or a string. If it remains undefined, we fall back to
|
||||||
|
// the importing sourcemap's `sourcesContent` field.
|
||||||
|
const sourceContent = content !== undefined ? content : sourcesContent ? sourcesContent[i] : null;
|
||||||
|
return OriginalSource(source, sourceContent);
|
||||||
|
});
|
||||||
|
return MapSource(map, children);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SourceMap v3 compatible sourcemap, which only includes fields that were
|
||||||
|
* provided to it.
|
||||||
|
*/
|
||||||
|
class SourceMap {
|
||||||
|
constructor(map, options) {
|
||||||
|
const out = options.decodedMappings ? genMapping.toDecodedMap(map) : genMapping.toEncodedMap(map);
|
||||||
|
this.version = out.version; // SourceMap spec says this should be first.
|
||||||
|
this.file = out.file;
|
||||||
|
this.mappings = out.mappings;
|
||||||
|
this.names = out.names;
|
||||||
|
this.sourceRoot = out.sourceRoot;
|
||||||
|
this.sources = out.sources;
|
||||||
|
if (!options.excludeContent) {
|
||||||
|
this.sourcesContent = out.sourcesContent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
toString() {
|
||||||
|
return JSON.stringify(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Traces through all the mappings in the root sourcemap, through the sources
|
||||||
|
* (and their sourcemaps), all the way back to the original source location.
|
||||||
|
*
|
||||||
|
* `loader` will be called every time we encounter a source file. If it returns
|
||||||
|
* a sourcemap, we will recurse into that sourcemap to continue the trace. If
|
||||||
|
* it returns a falsey value, that source file is treated as an original,
|
||||||
|
* unmodified source file.
|
||||||
|
*
|
||||||
|
* Pass `excludeContent` to exclude any self-containing source file content
|
||||||
|
* from the output sourcemap.
|
||||||
|
*
|
||||||
|
* Pass `decodedMappings` to receive a SourceMap with decoded (instead of
|
||||||
|
* VLQ encoded) mappings.
|
||||||
|
*/
|
||||||
|
function remapping(input, loader, options) {
|
||||||
|
const opts = typeof options === 'object' ? options : { excludeContent: !!options, decodedMappings: false };
|
||||||
|
const tree = buildSourceMapTree(input, loader);
|
||||||
|
return new SourceMap(traceMappings(tree), opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
return remapping;
|
||||||
|
|
||||||
|
}));
|
||||||
|
//# sourceMappingURL=remapping.umd.js.map
|
14
Meteo/node_modules/@ampproject/remapping/dist/types/build-source-map-tree.d.ts
generated
vendored
@ -0,0 +1,14 @@
|
|||||||
|
import type { MapSource as MapSourceType } from './source-map-tree';
|
||||||
|
import type { SourceMapInput, SourceMapLoader } from './types';
|
||||||
|
/**
|
||||||
|
* Recursively builds a tree structure out of sourcemap files, with each node
|
||||||
|
* being either an `OriginalSource` "leaf" or a `SourceMapTree` composed of
|
||||||
|
* `OriginalSource`s and `SourceMapTree`s.
|
||||||
|
*
|
||||||
|
* Every sourcemap is composed of a collection of source files and mappings
|
||||||
|
* into locations of those source files. When we generate a `SourceMapTree` for
|
||||||
|
* the sourcemap, we attempt to load each source file's own sourcemap. If it
|
||||||
|
* does not have an associated sourcemap, it is considered an original,
|
||||||
|
* unmodified source file.
|
||||||
|
*/
|
||||||
|
export default function buildSourceMapTree(input: SourceMapInput | SourceMapInput[], loader: SourceMapLoader): MapSourceType;
|
@ -0,0 +1,19 @@
|
|||||||
|
import SourceMap from './source-map';
|
||||||
|
import type { SourceMapInput, SourceMapLoader, Options } from './types';
|
||||||
|
export type { SourceMapSegment, EncodedSourceMap, EncodedSourceMap as RawSourceMap, DecodedSourceMap, SourceMapInput, SourceMapLoader, LoaderContext, Options, } from './types';
|
||||||
|
/**
|
||||||
|
* Traces through all the mappings in the root sourcemap, through the sources
|
||||||
|
* (and their sourcemaps), all the way back to the original source location.
|
||||||
|
*
|
||||||
|
* `loader` will be called every time we encounter a source file. If it returns
|
||||||
|
* a sourcemap, we will recurse into that sourcemap to continue the trace. If
|
||||||
|
* it returns a falsey value, that source file is treated as an original,
|
||||||
|
* unmodified source file.
|
||||||
|
*
|
||||||
|
* Pass `excludeContent` to exclude any self-containing source file content
|
||||||
|
* from the output sourcemap.
|
||||||
|
*
|
||||||
|
* Pass `decodedMappings` to receive a SourceMap with decoded (instead of
|
||||||
|
* VLQ encoded) mappings.
|
||||||
|
*/
|
||||||
|
export default function remapping(input: SourceMapInput | SourceMapInput[], loader: SourceMapLoader, options?: boolean | Options): SourceMap;
|
@ -0,0 +1,42 @@
|
|||||||
|
import { GenMapping } from '@jridgewell/gen-mapping';
|
||||||
|
import type { TraceMap } from '@jridgewell/trace-mapping';
|
||||||
|
export declare type SourceMapSegmentObject = {
|
||||||
|
column: number;
|
||||||
|
line: number;
|
||||||
|
name: string;
|
||||||
|
source: string;
|
||||||
|
content: string | null;
|
||||||
|
};
|
||||||
|
export declare type OriginalSource = {
|
||||||
|
map: null;
|
||||||
|
sources: Sources[];
|
||||||
|
source: string;
|
||||||
|
content: string | null;
|
||||||
|
};
|
||||||
|
export declare type MapSource = {
|
||||||
|
map: TraceMap;
|
||||||
|
sources: Sources[];
|
||||||
|
source: string;
|
||||||
|
content: null;
|
||||||
|
};
|
||||||
|
export declare type Sources = OriginalSource | MapSource;
|
||||||
|
/**
|
||||||
|
* MapSource represents a single sourcemap, with the ability to trace mappings into its child nodes
|
||||||
|
* (which may themselves be SourceMapTrees).
|
||||||
|
*/
|
||||||
|
export declare function MapSource(map: TraceMap, sources: Sources[]): MapSource;
|
||||||
|
/**
|
||||||
|
* A "leaf" node in the sourcemap tree, representing an original, unmodified source file. Recursive
|
||||||
|
* segment tracing ends at the `OriginalSource`.
|
||||||
|
*/
|
||||||
|
export declare function OriginalSource(source: string, content: string | null): OriginalSource;
|
||||||
|
/**
|
||||||
|
* traceMappings is only called on the root level SourceMapTree, and begins the process of
|
||||||
|
* resolving each mapping in terms of the original source files.
|
||||||
|
*/
|
||||||
|
export declare function traceMappings(tree: MapSource): GenMapping;
|
||||||
|
/**
|
||||||
|
* originalPositionFor is only called on children SourceMapTrees. It recurses down into its own
|
||||||
|
* child SourceMapTrees, until we find the original source map.
|
||||||
|
*/
|
||||||
|
export declare function originalPositionFor(source: Sources, line: number, column: number, name: string): SourceMapSegmentObject | null;
|
@ -0,0 +1,17 @@
|
|||||||
|
import type { GenMapping } from '@jridgewell/gen-mapping';
|
||||||
|
import type { DecodedSourceMap, EncodedSourceMap, Options } from './types';
|
||||||
|
/**
|
||||||
|
* A SourceMap v3 compatible sourcemap, which only includes fields that were
|
||||||
|
* provided to it.
|
||||||
|
*/
|
||||||
|
export default class SourceMap {
|
||||||
|
file?: string | null;
|
||||||
|
mappings: EncodedSourceMap['mappings'] | DecodedSourceMap['mappings'];
|
||||||
|
sourceRoot?: string;
|
||||||
|
names: string[];
|
||||||
|
sources: (string | null)[];
|
||||||
|
sourcesContent?: (string | null)[];
|
||||||
|
version: 3;
|
||||||
|
constructor(map: GenMapping, options: Options);
|
||||||
|
toString(): string;
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
import type { SourceMapInput } from '@jridgewell/trace-mapping';
|
||||||
|
export type { SourceMapSegment, DecodedSourceMap, EncodedSourceMap, } from '@jridgewell/trace-mapping';
|
||||||
|
export type { SourceMapInput };
|
||||||
|
export declare type LoaderContext = {
|
||||||
|
readonly importer: string;
|
||||||
|
readonly depth: number;
|
||||||
|
source: string;
|
||||||
|
content: string | null | undefined;
|
||||||
|
};
|
||||||
|
export declare type SourceMapLoader = (file: string, ctx: LoaderContext) => SourceMapInput | null | undefined | void;
|
||||||
|
export declare type Options = {
|
||||||
|
excludeContent?: boolean;
|
||||||
|
decodedMappings?: boolean;
|
||||||
|
};
|
@ -0,0 +1,75 @@
|
|||||||
|
{
|
||||||
|
"name": "@ampproject/remapping",
|
||||||
|
"version": "2.2.1",
|
||||||
|
"description": "Remap sequential sourcemaps through transformations to point at the original source code",
|
||||||
|
"keywords": [
|
||||||
|
"source",
|
||||||
|
"map",
|
||||||
|
"remap"
|
||||||
|
],
|
||||||
|
"main": "dist/remapping.umd.js",
|
||||||
|
"module": "dist/remapping.mjs",
|
||||||
|
"types": "dist/types/remapping.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": [
|
||||||
|
{
|
||||||
|
"types": "./dist/types/remapping.d.ts",
|
||||||
|
"browser": "./dist/remapping.umd.js",
|
||||||
|
"require": "./dist/remapping.umd.js",
|
||||||
|
"import": "./dist/remapping.mjs"
|
||||||
|
},
|
||||||
|
"./dist/remapping.umd.js"
|
||||||
|
],
|
||||||
|
"./package.json": "./package.json"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"dist"
|
||||||
|
],
|
||||||
|
"author": "Justin Ridgewell <jridgewell@google.com>",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/ampproject/remapping.git"
|
||||||
|
},
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0.0"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "run-s -n build:*",
|
||||||
|
"build:rollup": "rollup -c rollup.config.js",
|
||||||
|
"build:ts": "tsc --project tsconfig.build.json",
|
||||||
|
"lint": "run-s -n lint:*",
|
||||||
|
"lint:prettier": "npm run test:lint:prettier -- --write",
|
||||||
|
"lint:ts": "npm run test:lint:ts -- --fix",
|
||||||
|
"prebuild": "rm -rf dist",
|
||||||
|
"prepublishOnly": "npm run preversion",
|
||||||
|
"preversion": "run-s test build",
|
||||||
|
"test": "run-s -n test:lint test:only",
|
||||||
|
"test:debug": "node --inspect-brk node_modules/.bin/jest --runInBand",
|
||||||
|
"test:lint": "run-s -n test:lint:*",
|
||||||
|
"test:lint:prettier": "prettier --check '{src,test}/**/*.ts'",
|
||||||
|
"test:lint:ts": "eslint '{src,test}/**/*.ts'",
|
||||||
|
"test:only": "jest --coverage",
|
||||||
|
"test:watch": "jest --coverage --watch"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@rollup/plugin-typescript": "8.3.2",
|
||||||
|
"@types/jest": "27.4.1",
|
||||||
|
"@typescript-eslint/eslint-plugin": "5.20.0",
|
||||||
|
"@typescript-eslint/parser": "5.20.0",
|
||||||
|
"eslint": "8.14.0",
|
||||||
|
"eslint-config-prettier": "8.5.0",
|
||||||
|
"jest": "27.5.1",
|
||||||
|
"jest-config": "27.5.1",
|
||||||
|
"npm-run-all": "4.1.5",
|
||||||
|
"prettier": "2.6.2",
|
||||||
|
"rollup": "2.70.2",
|
||||||
|
"ts-jest": "27.1.4",
|
||||||
|
"tslib": "2.4.0",
|
||||||
|
"typescript": "4.6.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@jridgewell/gen-mapping": "^0.3.0",
|
||||||
|
"@jridgewell/trace-mapping": "^0.3.9"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2014-present Sebastian McKenzie and other contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@ -0,0 +1,19 @@
|
|||||||
|
# @babel/code-frame
|
||||||
|
|
||||||
|
> Generate errors that contain a code frame that point to source locations.
|
||||||
|
|
||||||
|
See our website [@babel/code-frame](https://babeljs.io/docs/en/babel-code-frame) for more information.
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
Using npm:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm install --save-dev @babel/code-frame
|
||||||
|
```
|
||||||
|
|
||||||
|
or using yarn:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
yarn add @babel/code-frame --dev
|
||||||
|
```
|
@ -0,0 +1,142 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.codeFrameColumns = codeFrameColumns;
|
||||||
|
exports.default = _default;
|
||||||
|
var _highlight = require("@babel/highlight");
|
||||||
|
let deprecationWarningShown = false;
|
||||||
|
function getDefs(chalk) {
|
||||||
|
return {
|
||||||
|
gutter: chalk.grey,
|
||||||
|
marker: chalk.red.bold,
|
||||||
|
message: chalk.red.bold
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const NEWLINE = /\r\n|[\n\r\u2028\u2029]/;
|
||||||
|
function getMarkerLines(loc, source, opts) {
|
||||||
|
const startLoc = Object.assign({
|
||||||
|
column: 0,
|
||||||
|
line: -1
|
||||||
|
}, loc.start);
|
||||||
|
const endLoc = Object.assign({}, startLoc, loc.end);
|
||||||
|
const {
|
||||||
|
linesAbove = 2,
|
||||||
|
linesBelow = 3
|
||||||
|
} = opts || {};
|
||||||
|
const startLine = startLoc.line;
|
||||||
|
const startColumn = startLoc.column;
|
||||||
|
const endLine = endLoc.line;
|
||||||
|
const endColumn = endLoc.column;
|
||||||
|
let start = Math.max(startLine - (linesAbove + 1), 0);
|
||||||
|
let end = Math.min(source.length, endLine + linesBelow);
|
||||||
|
if (startLine === -1) {
|
||||||
|
start = 0;
|
||||||
|
}
|
||||||
|
if (endLine === -1) {
|
||||||
|
end = source.length;
|
||||||
|
}
|
||||||
|
const lineDiff = endLine - startLine;
|
||||||
|
const markerLines = {};
|
||||||
|
if (lineDiff) {
|
||||||
|
for (let i = 0; i <= lineDiff; i++) {
|
||||||
|
const lineNumber = i + startLine;
|
||||||
|
if (!startColumn) {
|
||||||
|
markerLines[lineNumber] = true;
|
||||||
|
} else if (i === 0) {
|
||||||
|
const sourceLength = source[lineNumber - 1].length;
|
||||||
|
markerLines[lineNumber] = [startColumn, sourceLength - startColumn + 1];
|
||||||
|
} else if (i === lineDiff) {
|
||||||
|
markerLines[lineNumber] = [0, endColumn];
|
||||||
|
} else {
|
||||||
|
const sourceLength = source[lineNumber - i].length;
|
||||||
|
markerLines[lineNumber] = [0, sourceLength];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (startColumn === endColumn) {
|
||||||
|
if (startColumn) {
|
||||||
|
markerLines[startLine] = [startColumn, 0];
|
||||||
|
} else {
|
||||||
|
markerLines[startLine] = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
markerLines[startLine] = [startColumn, endColumn - startColumn];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
markerLines
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function codeFrameColumns(rawLines, loc, opts = {}) {
|
||||||
|
const highlighted = (opts.highlightCode || opts.forceColor) && (0, _highlight.shouldHighlight)(opts);
|
||||||
|
const chalk = (0, _highlight.getChalk)(opts);
|
||||||
|
const defs = getDefs(chalk);
|
||||||
|
const maybeHighlight = (chalkFn, string) => {
|
||||||
|
return highlighted ? chalkFn(string) : string;
|
||||||
|
};
|
||||||
|
const lines = rawLines.split(NEWLINE);
|
||||||
|
const {
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
markerLines
|
||||||
|
} = getMarkerLines(loc, lines, opts);
|
||||||
|
const hasColumns = loc.start && typeof loc.start.column === "number";
|
||||||
|
const numberMaxWidth = String(end).length;
|
||||||
|
const highlightedLines = highlighted ? (0, _highlight.default)(rawLines, opts) : rawLines;
|
||||||
|
let frame = highlightedLines.split(NEWLINE, end).slice(start, end).map((line, index) => {
|
||||||
|
const number = start + 1 + index;
|
||||||
|
const paddedNumber = ` ${number}`.slice(-numberMaxWidth);
|
||||||
|
const gutter = ` ${paddedNumber} |`;
|
||||||
|
const hasMarker = markerLines[number];
|
||||||
|
const lastMarkerLine = !markerLines[number + 1];
|
||||||
|
if (hasMarker) {
|
||||||
|
let markerLine = "";
|
||||||
|
if (Array.isArray(hasMarker)) {
|
||||||
|
const markerSpacing = line.slice(0, Math.max(hasMarker[0] - 1, 0)).replace(/[^\t]/g, " ");
|
||||||
|
const numberOfMarkers = hasMarker[1] || 1;
|
||||||
|
markerLine = ["\n ", maybeHighlight(defs.gutter, gutter.replace(/\d/g, " ")), " ", markerSpacing, maybeHighlight(defs.marker, "^").repeat(numberOfMarkers)].join("");
|
||||||
|
if (lastMarkerLine && opts.message) {
|
||||||
|
markerLine += " " + maybeHighlight(defs.message, opts.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [maybeHighlight(defs.marker, ">"), maybeHighlight(defs.gutter, gutter), line.length > 0 ? ` ${line}` : "", markerLine].join("");
|
||||||
|
} else {
|
||||||
|
return ` ${maybeHighlight(defs.gutter, gutter)}${line.length > 0 ? ` ${line}` : ""}`;
|
||||||
|
}
|
||||||
|
}).join("\n");
|
||||||
|
if (opts.message && !hasColumns) {
|
||||||
|
frame = `${" ".repeat(numberMaxWidth + 1)}${opts.message}\n${frame}`;
|
||||||
|
}
|
||||||
|
if (highlighted) {
|
||||||
|
return chalk.reset(frame);
|
||||||
|
} else {
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function _default(rawLines, lineNumber, colNumber, opts = {}) {
|
||||||
|
if (!deprecationWarningShown) {
|
||||||
|
deprecationWarningShown = true;
|
||||||
|
const message = "Passing lineNumber and colNumber is deprecated to @babel/code-frame. Please use `codeFrameColumns`.";
|
||||||
|
if (process.emitWarning) {
|
||||||
|
process.emitWarning(message, "DeprecationWarning");
|
||||||
|
} else {
|
||||||
|
const deprecationError = new Error(message);
|
||||||
|
deprecationError.name = "DeprecationWarning";
|
||||||
|
console.warn(new Error(message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
colNumber = Math.max(colNumber, 0);
|
||||||
|
const location = {
|
||||||
|
start: {
|
||||||
|
column: colNumber,
|
||||||
|
line: lineNumber
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return codeFrameColumns(rawLines, location, opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
//# sourceMappingURL=index.js.map
|
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"name": "@babel/code-frame",
|
||||||
|
"version": "7.21.4",
|
||||||
|
"description": "Generate errors that contain a code frame that point to source locations.",
|
||||||
|
"author": "The Babel Team (https://babel.dev/team)",
|
||||||
|
"homepage": "https://babel.dev/docs/en/next/babel-code-frame",
|
||||||
|
"bugs": "https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen",
|
||||||
|
"license": "MIT",
|
||||||
|
"publishConfig": {
|
||||||
|
"access": "public"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/babel/babel.git",
|
||||||
|
"directory": "packages/babel-code-frame"
|
||||||
|
},
|
||||||
|
"main": "./lib/index.js",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/highlight": "^7.18.6"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"strip-ansi": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
},
|
||||||
|
"type": "commonjs"
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2014-present Sebastian McKenzie and other contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@ -0,0 +1,19 @@
|
|||||||
|
# @babel/compat-data
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
See our website [@babel/compat-data](https://babeljs.io/docs/en/babel-compat-data) for more information.
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
Using npm:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm install --save @babel/compat-data
|
||||||
|
```
|
||||||
|
|
||||||
|
or using yarn:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
yarn add @babel/compat-data
|
||||||
|
```
|
@ -0,0 +1,2 @@
|
|||||||
|
// Todo (Babel 8): remove this file as Babel 8 drop support of core-js 2
|
||||||
|
module.exports = require("./data/corejs2-built-ins.json");
|
@ -0,0 +1,2 @@
|
|||||||
|
// Todo (Babel 8): remove this file now that it is included in babel-plugin-polyfill-corejs3
|
||||||
|
module.exports = require("./data/corejs3-shipped-proposals.json");
|