@flightloop/sdk-frontend 0.0.0-stage → 1.0.0-qa.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +145 -2
- package/dist/cjs/core/airspace/index.js +14 -0
- package/dist/cjs/core/airspace/index.js.map +1 -0
- package/dist/cjs/core/airspace/validation-client.js +112 -0
- package/dist/cjs/core/airspace/validation-client.js.map +1 -0
- package/dist/cjs/core/formatters/index.js +41 -0
- package/dist/cjs/core/formatters/index.js.map +1 -0
- package/dist/cjs/core/geometry/circle.js +137 -0
- package/dist/cjs/core/geometry/circle.js.map +1 -0
- package/dist/cjs/core/geometry/index.js +26 -0
- package/dist/cjs/core/geometry/index.js.map +1 -0
- package/dist/cjs/core/geometry/operations.js +169 -0
- package/dist/cjs/core/geometry/operations.js.map +1 -0
- package/dist/cjs/core/geometry/polygon.js +183 -0
- package/dist/cjs/core/geometry/polygon.js.map +1 -0
- package/dist/cjs/core/index.js +29 -0
- package/dist/cjs/core/index.js.map +1 -0
- package/dist/cjs/core/transformers/index.js +33 -0
- package/dist/cjs/core/transformers/index.js.map +1 -0
- package/dist/cjs/core/utils/constants.js +124 -0
- package/dist/cjs/core/utils/constants.js.map +1 -0
- package/dist/cjs/core/utils/helpers.js +98 -0
- package/dist/cjs/core/utils/helpers.js.map +1 -0
- package/dist/cjs/core/utils/index.js +35 -0
- package/dist/cjs/core/utils/index.js.map +1 -0
- package/dist/cjs/core/utils/timezone.js +52 -0
- package/dist/cjs/core/utils/timezone.js.map +1 -0
- package/dist/cjs/core/validation/index.js +26 -0
- package/dist/cjs/core/validation/index.js.map +1 -0
- package/dist/cjs/core/validation/operator.validator.js +156 -0
- package/dist/cjs/core/validation/operator.validator.js.map +1 -0
- package/dist/cjs/index.js +32 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/react/hooks/index.js +41 -0
- package/dist/cjs/react/hooks/index.js.map +1 -0
- package/dist/cjs/react/index.js +20 -0
- package/dist/cjs/react/index.js.map +1 -0
- package/dist/cjs/types/airspace.types.js +22 -0
- package/dist/cjs/types/airspace.types.js.map +1 -0
- package/dist/cjs/types/authorization.types.js +3 -0
- package/dist/cjs/types/authorization.types.js.map +1 -0
- package/dist/cjs/types/geometry.types.js +4 -0
- package/dist/cjs/types/geometry.types.js.map +1 -0
- package/dist/cjs/types/index.js +7 -0
- package/dist/cjs/types/index.js.map +1 -0
- package/dist/esm/core/airspace/index.js +9 -0
- package/dist/esm/core/airspace/index.js.map +1 -0
- package/dist/esm/core/airspace/validation-client.js +107 -0
- package/dist/esm/core/airspace/validation-client.js.map +1 -0
- package/dist/esm/core/formatters/index.js +35 -0
- package/dist/esm/core/formatters/index.js.map +1 -0
- package/dist/esm/core/geometry/circle.js +98 -0
- package/dist/esm/core/geometry/circle.js.map +1 -0
- package/dist/esm/core/geometry/index.js +7 -0
- package/dist/esm/core/geometry/index.js.map +1 -0
- package/dist/esm/core/geometry/operations.js +125 -0
- package/dist/esm/core/geometry/operations.js.map +1 -0
- package/dist/esm/core/geometry/polygon.js +145 -0
- package/dist/esm/core/geometry/polygon.js.map +1 -0
- package/dist/esm/core/index.js +13 -0
- package/dist/esm/core/index.js.map +1 -0
- package/dist/esm/core/transformers/index.js +28 -0
- package/dist/esm/core/transformers/index.js.map +1 -0
- package/dist/esm/core/utils/constants.js +121 -0
- package/dist/esm/core/utils/constants.js.map +1 -0
- package/dist/esm/core/utils/helpers.js +83 -0
- package/dist/esm/core/utils/helpers.js.map +1 -0
- package/dist/esm/core/utils/index.js +7 -0
- package/dist/esm/core/utils/index.js.map +1 -0
- package/dist/esm/core/utils/timezone.js +47 -0
- package/dist/esm/core/utils/timezone.js.map +1 -0
- package/dist/esm/core/validation/index.js +10 -0
- package/dist/esm/core/validation/index.js.map +1 -0
- package/dist/esm/core/validation/operator.validator.js +150 -0
- package/dist/esm/core/validation/operator.validator.js.map +1 -0
- package/dist/esm/index.js +15 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/react/hooks/index.js +35 -0
- package/dist/esm/react/hooks/index.js.map +1 -0
- package/dist/esm/react/index.js +4 -0
- package/dist/esm/react/index.js.map +1 -0
- package/dist/esm/types/airspace.types.js +19 -0
- package/dist/esm/types/airspace.types.js.map +1 -0
- package/dist/esm/types/authorization.types.js +2 -0
- package/dist/esm/types/authorization.types.js.map +1 -0
- package/dist/esm/types/geometry.types.js +3 -0
- package/dist/esm/types/geometry.types.js.map +1 -0
- package/dist/esm/types/index.js +3 -0
- package/dist/esm/types/index.js.map +1 -0
- package/dist/types/core/airspace/index.d.ts +8 -0
- package/dist/types/core/airspace/index.d.ts.map +1 -0
- package/dist/types/core/airspace/validation-client.d.ts +86 -0
- package/dist/types/core/airspace/validation-client.d.ts.map +1 -0
- package/dist/types/core/formatters/index.d.ts +28 -0
- package/dist/types/core/formatters/index.d.ts.map +1 -0
- package/dist/types/core/geometry/circle.d.ts +33 -0
- package/dist/types/core/geometry/circle.d.ts.map +1 -0
- package/dist/types/core/geometry/index.d.ts +4 -0
- package/dist/types/core/geometry/index.d.ts.map +1 -0
- package/dist/types/core/geometry/operations.d.ts +72 -0
- package/dist/types/core/geometry/operations.d.ts.map +1 -0
- package/dist/types/core/geometry/polygon.d.ts +25 -0
- package/dist/types/core/geometry/polygon.d.ts.map +1 -0
- package/dist/types/core/index.d.ts +7 -0
- package/dist/types/core/index.d.ts.map +1 -0
- package/dist/types/core/transformers/index.d.ts +26 -0
- package/dist/types/core/transformers/index.d.ts.map +1 -0
- package/dist/types/core/utils/constants.d.ts +116 -0
- package/dist/types/core/utils/constants.d.ts.map +1 -0
- package/dist/types/core/utils/helpers.d.ts +53 -0
- package/dist/types/core/utils/helpers.d.ts.map +1 -0
- package/dist/types/core/utils/index.d.ts +4 -0
- package/dist/types/core/utils/index.d.ts.map +1 -0
- package/dist/types/core/utils/timezone.d.ts +23 -0
- package/dist/types/core/utils/timezone.d.ts.map +1 -0
- package/dist/types/core/validation/index.d.ts +9 -0
- package/dist/types/core/validation/index.d.ts.map +1 -0
- package/dist/types/core/validation/operator.validator.d.ts +35 -0
- package/dist/types/core/validation/operator.validator.d.ts.map +1 -0
- package/dist/types/index.d.ts +12 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/react/hooks/index.d.ts +27 -0
- package/dist/types/react/hooks/index.d.ts.map +1 -0
- package/dist/types/react/index.d.ts +2 -0
- package/dist/types/react/index.d.ts.map +1 -0
- package/dist/types/types/airspace.types.d.ts +109 -0
- package/dist/types/types/airspace.types.d.ts.map +1 -0
- package/dist/types/types/authorization.types.d.ts +124 -0
- package/dist/types/types/authorization.types.d.ts.map +1 -0
- package/dist/types/types/geometry.types.d.ts +77 -0
- package/dist/types/types/geometry.types.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +5 -0
- package/dist/types/types/index.d.ts.map +1 -0
- package/package.json +84 -4
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import * as turf from '@turf/turf';
|
|
2
|
+
import { metersToFeet } from '../utils/helpers';
|
|
3
|
+
/**
|
|
4
|
+
* Calculate the area of a geometry in square feet
|
|
5
|
+
*
|
|
6
|
+
* @param geometry - GeoJSON geometry
|
|
7
|
+
* @returns Area in square feet
|
|
8
|
+
*/
|
|
9
|
+
export function calculateArea(geometry) {
|
|
10
|
+
const areaSquareMeters = turf.area(geometry);
|
|
11
|
+
return areaSquareMeters * 10.7639; // Convert to square feet
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Calculate the perimeter/length of a geometry in feet
|
|
15
|
+
*
|
|
16
|
+
* @param geometry - GeoJSON geometry
|
|
17
|
+
* @returns Perimeter/length in feet
|
|
18
|
+
*/
|
|
19
|
+
export function calculatePerimeter(geometry) {
|
|
20
|
+
const lengthMeters = turf.length(geometry, { units: 'meters' });
|
|
21
|
+
return metersToFeet(lengthMeters);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Calculate the centroid of a geometry
|
|
25
|
+
*
|
|
26
|
+
* @param geometry - GeoJSON geometry
|
|
27
|
+
* @returns Centroid as LatLng
|
|
28
|
+
*/
|
|
29
|
+
export function calculateCentroid(geometry) {
|
|
30
|
+
const centroid = turf.centroid(geometry);
|
|
31
|
+
return {
|
|
32
|
+
lng: centroid.geometry.coordinates[0],
|
|
33
|
+
lat: centroid.geometry.coordinates[1],
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Calculate the intersection of two geometries
|
|
38
|
+
*
|
|
39
|
+
* @param geometry1 - First geometry
|
|
40
|
+
* @param geometry2 - Second geometry
|
|
41
|
+
* @returns Intersection geometry, or null if no intersection
|
|
42
|
+
*/
|
|
43
|
+
export function calculateIntersection(geometry1, geometry2) {
|
|
44
|
+
try {
|
|
45
|
+
const intersection = turf.intersect(geometry1, geometry2);
|
|
46
|
+
return intersection ? intersection.geometry : null;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Check if two geometries intersect
|
|
54
|
+
*
|
|
55
|
+
* @param geometry1 - First geometry
|
|
56
|
+
* @param geometry2 - Second geometry
|
|
57
|
+
* @returns True if geometries intersect
|
|
58
|
+
*/
|
|
59
|
+
export function checkIntersection(geometry1, geometry2) {
|
|
60
|
+
try {
|
|
61
|
+
// Check if geometries intersect by attempting to find intersection
|
|
62
|
+
const intersection = calculateIntersection(geometry1, geometry2);
|
|
63
|
+
return intersection !== null;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Check if one geometry contains another
|
|
71
|
+
*
|
|
72
|
+
* @param container - Container geometry
|
|
73
|
+
* @param contained - Potentially contained geometry
|
|
74
|
+
* @returns True if container contains the other geometry
|
|
75
|
+
*/
|
|
76
|
+
export function checkContains(container, contained) {
|
|
77
|
+
try {
|
|
78
|
+
const feature1 = container.type === 'Feature' ? container : turf.feature(container);
|
|
79
|
+
const feature2 = contained.type === 'Feature' ? contained : turf.feature(contained);
|
|
80
|
+
return turf.booleanContains(feature1, feature2);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Calculate distance between two points in feet
|
|
88
|
+
*
|
|
89
|
+
* @param point1 - First point
|
|
90
|
+
* @param point2 - Second point
|
|
91
|
+
* @returns Distance in feet
|
|
92
|
+
*/
|
|
93
|
+
export function calculateDistance(point1, point2) {
|
|
94
|
+
const from = turf.point([point1.lng, point1.lat]);
|
|
95
|
+
const to = turf.point([point2.lng, point2.lat]);
|
|
96
|
+
const distanceMeters = turf.distance(from, to, { units: 'meters' });
|
|
97
|
+
return metersToFeet(distanceMeters);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Calculate bearing between two points in degrees
|
|
101
|
+
*
|
|
102
|
+
* @param point1 - Starting point
|
|
103
|
+
* @param point2 - Ending point
|
|
104
|
+
* @returns Bearing in degrees (0-360)
|
|
105
|
+
*/
|
|
106
|
+
export function calculateBearing(point1, point2) {
|
|
107
|
+
const from = turf.point([point1.lng, point1.lat]);
|
|
108
|
+
const to = turf.point([point2.lng, point2.lat]);
|
|
109
|
+
const bearing = turf.bearing(from, to);
|
|
110
|
+
// Convert to 0-360 range
|
|
111
|
+
return (bearing + 360) % 360;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Create a buffer around a geometry
|
|
115
|
+
*
|
|
116
|
+
* @param geometry - Input geometry
|
|
117
|
+
* @param radiusFeet - Buffer radius in feet
|
|
118
|
+
* @returns Buffered geometry
|
|
119
|
+
*/
|
|
120
|
+
export function createBuffer(geometry, radiusFeet) {
|
|
121
|
+
const radiusMeters = radiusFeet * 0.3048;
|
|
122
|
+
const radiusKm = radiusMeters / 1000;
|
|
123
|
+
return turf.buffer(geometry, radiusKm, { units: 'kilometers' });
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=operations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operations.js","sourceRoot":"","sources":["../../../../src/core/geometry/operations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import * as turf from '@turf/turf';
|
|
2
|
+
import { POLYGON_CONSTRAINTS, ERROR_CODES } from '../utils/constants';
|
|
3
|
+
/**
|
|
4
|
+
* Create a polygon from an array of points
|
|
5
|
+
*
|
|
6
|
+
* @param points - Array of LatLng points
|
|
7
|
+
* @param options - Polygon creation options
|
|
8
|
+
* @returns GeoJSON Feature with Polygon geometry
|
|
9
|
+
*/
|
|
10
|
+
export function createPolygon(points, options = {}) {
|
|
11
|
+
const { close = true } = options;
|
|
12
|
+
// Validate inputs
|
|
13
|
+
const validation = validatePolygon(points);
|
|
14
|
+
if (!validation.valid) {
|
|
15
|
+
throw new Error(`Invalid polygon parameters: ${validation.errors.map(e => e.message).join(', ')}`);
|
|
16
|
+
}
|
|
17
|
+
// Convert LatLng to GeoJSON coordinates [lng, lat]
|
|
18
|
+
const coordinates = points.map(p => [p.lng, p.lat]);
|
|
19
|
+
// Close the polygon if needed
|
|
20
|
+
if (close && coordinates.length > 0) {
|
|
21
|
+
const first = coordinates[0];
|
|
22
|
+
const last = coordinates[coordinates.length - 1];
|
|
23
|
+
if (first[0] !== last[0] || first[1] !== last[1]) {
|
|
24
|
+
coordinates.push([...first]);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
// Create polygon using Turf.js
|
|
28
|
+
const polygon = turf.polygon([coordinates]);
|
|
29
|
+
// Add metadata to properties
|
|
30
|
+
polygon.properties = {
|
|
31
|
+
geometryType: 'polygon',
|
|
32
|
+
pointCount: points.length,
|
|
33
|
+
};
|
|
34
|
+
return polygon;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Validate polygon parameters
|
|
38
|
+
*
|
|
39
|
+
* @param points - Array of LatLng points
|
|
40
|
+
* @returns Validation result
|
|
41
|
+
*/
|
|
42
|
+
export function validatePolygon(points) {
|
|
43
|
+
const errors = [];
|
|
44
|
+
const warnings = [];
|
|
45
|
+
// Check minimum points
|
|
46
|
+
if (!Array.isArray(points) || points.length < POLYGON_CONSTRAINTS.MIN_POINTS) {
|
|
47
|
+
errors.push({
|
|
48
|
+
field: 'points',
|
|
49
|
+
message: `Polygon must have at least ${POLYGON_CONSTRAINTS.MIN_POINTS} points`,
|
|
50
|
+
code: ERROR_CODES.POLYGON_TOO_FEW_POINTS,
|
|
51
|
+
});
|
|
52
|
+
return { valid: false, errors, warnings };
|
|
53
|
+
}
|
|
54
|
+
// Check maximum points
|
|
55
|
+
if (points.length > POLYGON_CONSTRAINTS.MAX_POINTS) {
|
|
56
|
+
errors.push({
|
|
57
|
+
field: 'points',
|
|
58
|
+
message: `Polygon must not have more than ${POLYGON_CONSTRAINTS.MAX_POINTS} points`,
|
|
59
|
+
code: ERROR_CODES.POLYGON_TOO_MANY_POINTS,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
// Validate each point
|
|
63
|
+
for (let i = 0; i < points.length; i++) {
|
|
64
|
+
const point = points[i];
|
|
65
|
+
if (!point || typeof point.lat !== 'number' || typeof point.lng !== 'number') {
|
|
66
|
+
errors.push({
|
|
67
|
+
field: `points[${i}]`,
|
|
68
|
+
message: `Point ${i} has invalid coordinates`,
|
|
69
|
+
code: ERROR_CODES.INVALID_COORDINATES,
|
|
70
|
+
});
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
// Validate coordinate ranges
|
|
74
|
+
if (point.lat < -90 || point.lat > 90) {
|
|
75
|
+
errors.push({
|
|
76
|
+
field: `points[${i}].lat`,
|
|
77
|
+
message: `Latitude must be between -90 and 90 (got ${point.lat})`,
|
|
78
|
+
code: ERROR_CODES.INVALID_COORDINATES,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
if (point.lng < -180 || point.lng > 180) {
|
|
82
|
+
errors.push({
|
|
83
|
+
field: `points[${i}].lng`,
|
|
84
|
+
message: `Longitude must be between -180 and 180 (got ${point.lng})`,
|
|
85
|
+
code: ERROR_CODES.INVALID_COORDINATES,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// If basic validation failed, return early
|
|
90
|
+
if (errors.length > 0) {
|
|
91
|
+
return { valid: false, errors, warnings };
|
|
92
|
+
}
|
|
93
|
+
// Check for self-intersection
|
|
94
|
+
try {
|
|
95
|
+
const coordinates = points.map(p => [p.lng, p.lat]);
|
|
96
|
+
// Close the polygon for validation
|
|
97
|
+
coordinates.push([coordinates[0][0], coordinates[0][1]]);
|
|
98
|
+
const polygon = turf.polygon([coordinates]);
|
|
99
|
+
const kinks = turf.kinks(polygon);
|
|
100
|
+
if (kinks.features.length > 0) {
|
|
101
|
+
errors.push({
|
|
102
|
+
field: 'points',
|
|
103
|
+
message: 'Polygon has self-intersections',
|
|
104
|
+
code: ERROR_CODES.POLYGON_SELF_INTERSECTING,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
// Check area if polygon is valid
|
|
108
|
+
if (errors.length === 0) {
|
|
109
|
+
const areaMeters = turf.area(polygon);
|
|
110
|
+
const areaFeet = areaMeters * 10.7639; // sq meters to sq feet
|
|
111
|
+
if (POLYGON_CONSTRAINTS.MAX_AREA && areaFeet > POLYGON_CONSTRAINTS.MAX_AREA) {
|
|
112
|
+
errors.push({
|
|
113
|
+
field: 'points',
|
|
114
|
+
message: `Polygon area exceeds maximum allowed (${POLYGON_CONSTRAINTS.MAX_AREA} sq ft)`,
|
|
115
|
+
code: ERROR_CODES.POLYGON_TOO_LARGE,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
errors.push({
|
|
122
|
+
field: 'points',
|
|
123
|
+
message: `Failed to validate polygon geometry: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
124
|
+
code: ERROR_CODES.INVALID_COORDINATES,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
valid: errors.length === 0,
|
|
129
|
+
errors,
|
|
130
|
+
warnings,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Get the points of a polygon geometry
|
|
135
|
+
*
|
|
136
|
+
* @param polygon - Polygon feature
|
|
137
|
+
* @returns Array of LatLng points
|
|
138
|
+
*/
|
|
139
|
+
export function getPolygonPoints(polygon) {
|
|
140
|
+
const coordinates = polygon.geometry.coordinates[0];
|
|
141
|
+
// Remove the last point if it's a duplicate of the first (closed polygon)
|
|
142
|
+
const points = coordinates.slice(0, -1);
|
|
143
|
+
return points.map(coord => ({ lng: coord[0], lat: coord[1] }));
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=polygon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"polygon.js","sourceRoot":"","sources":["../../../../src/core/geometry/polygon.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// ─── Geometry ────────────────────────────────────────────────────────────────
|
|
2
|
+
export * from './geometry';
|
|
3
|
+
// ─── Airspace ────────────────────────────────────────────────────────────────
|
|
4
|
+
export * from './airspace';
|
|
5
|
+
// ─── Validation ──────────────────────────────────────────────────────────────
|
|
6
|
+
export * from './validation';
|
|
7
|
+
// ─── Formatters ──────────────────────────────────────────────────────────────
|
|
8
|
+
export * from './formatters';
|
|
9
|
+
// ─── Transformers ────────────────────────────────────────────────────────────
|
|
10
|
+
export * from './transformers';
|
|
11
|
+
// ─── Utils ───────────────────────────────────────────────────────────────────
|
|
12
|
+
export * from './utils';
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/index.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,cAAc,YAAY,CAAC;AAE3B,gFAAgF;AAChF,cAAc,YAAY,CAAC;AAE3B,gFAAgF;AAChF,cAAc,cAAc,CAAC;AAE7B,gFAAgF;AAChF,cAAc,cAAc,CAAC;AAE7B,gFAAgF;AAChF,cAAc,gBAAgB,CAAC;AAE/B,gFAAgF;AAChF,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Airspace feature transformers
|
|
3
|
+
*
|
|
4
|
+
* This module provides utilities to transform airspace features from various
|
|
5
|
+
* map data sources into the standardized SDK format.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Transform Mapbox vector tile features to standard format
|
|
9
|
+
* TODO: Implement in future iteration
|
|
10
|
+
*/
|
|
11
|
+
export function transformMapboxFeature(_mapboxFeature, _layerId) {
|
|
12
|
+
throw new Error('Not implemented yet');
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Transform generic GeoJSON features to standard format
|
|
16
|
+
* TODO: Implement in future iteration
|
|
17
|
+
*/
|
|
18
|
+
export function transformGenericGeoJSON(_feature, _options) {
|
|
19
|
+
throw new Error('Not implemented yet');
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Auto-detect and transform features from various sources
|
|
23
|
+
* TODO: Implement in future iteration
|
|
24
|
+
*/
|
|
25
|
+
export function transformFeatures(_features, _source) {
|
|
26
|
+
throw new Error('Not implemented yet');
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/transformers/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,cAAmB,EACnB,QAAgB;IAEhB,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;AACzC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CACrC,QAAa,EACb,QAGC;IAED,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;AACzC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,SAAgB,EAChB,OAAuC;IAEvC,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LAANC authorization constraints and constants
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Altitude constraints (feet AGL)
|
|
6
|
+
*/
|
|
7
|
+
export const ALTITUDE_CONSTRAINTS = {
|
|
8
|
+
/** Maximum altitude for Part 107 operations */
|
|
9
|
+
MAX_PART_107: 400,
|
|
10
|
+
/** Maximum altitude for 44809 recreational operations */
|
|
11
|
+
MAX_44809: 400,
|
|
12
|
+
/** Minimum altitude */
|
|
13
|
+
MIN: 0,
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Circle geometry constraints (feet)
|
|
17
|
+
*/
|
|
18
|
+
export const CIRCLE_CONSTRAINTS = {
|
|
19
|
+
/** Minimum circle radius */
|
|
20
|
+
MIN_RADIUS: 10,
|
|
21
|
+
/** Maximum circle radius */
|
|
22
|
+
MAX_RADIUS: 3000,
|
|
23
|
+
/** Default number of steps for circle approximation */
|
|
24
|
+
DEFAULT_STEPS: 64,
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Polygon geometry constraints
|
|
28
|
+
*/
|
|
29
|
+
export const POLYGON_CONSTRAINTS = {
|
|
30
|
+
/** Minimum number of polygon points */
|
|
31
|
+
MIN_POINTS: 3,
|
|
32
|
+
/** Maximum number of polygon points */
|
|
33
|
+
MAX_POINTS: 100,
|
|
34
|
+
/** Maximum polygon area (square feet) - TBD based on requirements */
|
|
35
|
+
MAX_AREA: 100000000,
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Further Coordination (FC) timing constraints
|
|
39
|
+
*/
|
|
40
|
+
export const FC_CONSTRAINTS = {
|
|
41
|
+
/** Minimum lead time for FC requests (hours) */
|
|
42
|
+
MIN_HOURS: 72,
|
|
43
|
+
/** Maximum advance time for FC requests (days) */
|
|
44
|
+
MAX_DAYS: 90,
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Proximity search constraints
|
|
48
|
+
*/
|
|
49
|
+
export const PROXIMITY_CONSTRAINTS = {
|
|
50
|
+
/** Proximity radius for nearby airspace (nautical miles) */
|
|
51
|
+
RADIUS_NM: 2,
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Unit conversion constants
|
|
55
|
+
*/
|
|
56
|
+
export const UNIT_CONVERSIONS = {
|
|
57
|
+
/** Feet to meters */
|
|
58
|
+
FEET_TO_METERS: 0.3048,
|
|
59
|
+
/** Meters to feet */
|
|
60
|
+
METERS_TO_FEET: 3.28084,
|
|
61
|
+
/** Nautical miles to meters */
|
|
62
|
+
NM_TO_METERS: 1852,
|
|
63
|
+
/** Meters to nautical miles */
|
|
64
|
+
METERS_TO_NM: 1 / 1852,
|
|
65
|
+
/** Miles to meters */
|
|
66
|
+
MILES_TO_METERS: 1609.34,
|
|
67
|
+
/** Meters to miles */
|
|
68
|
+
METERS_TO_MILES: 1 / 1609.34,
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Validation error codes
|
|
72
|
+
*/
|
|
73
|
+
export const ERROR_CODES = {
|
|
74
|
+
// Geometry errors
|
|
75
|
+
CIRCLE_RADIUS_TOO_SMALL: 'CIRCLE_RADIUS_TOO_SMALL',
|
|
76
|
+
CIRCLE_RADIUS_TOO_LARGE: 'CIRCLE_RADIUS_TOO_LARGE',
|
|
77
|
+
POLYGON_TOO_FEW_POINTS: 'POLYGON_TOO_FEW_POINTS',
|
|
78
|
+
POLYGON_TOO_MANY_POINTS: 'POLYGON_TOO_MANY_POINTS',
|
|
79
|
+
POLYGON_TOO_LARGE: 'POLYGON_TOO_LARGE',
|
|
80
|
+
POLYGON_SELF_INTERSECTING: 'POLYGON_SELF_INTERSECTING',
|
|
81
|
+
INVALID_COORDINATES: 'INVALID_COORDINATES',
|
|
82
|
+
// Altitude errors
|
|
83
|
+
ALTITUDE_TOO_LOW: 'ALTITUDE_TOO_LOW',
|
|
84
|
+
ALTITUDE_TOO_HIGH: 'ALTITUDE_TOO_HIGH',
|
|
85
|
+
ALTITUDE_EXCEEDS_CEILING: 'ALTITUDE_EXCEEDS_CEILING',
|
|
86
|
+
// DateTime errors
|
|
87
|
+
INVALID_DATETIME: 'INVALID_DATETIME',
|
|
88
|
+
INVALID_TIMEZONE: 'INVALID_TIMEZONE',
|
|
89
|
+
OPERATION_IN_PAST: 'OPERATION_IN_PAST',
|
|
90
|
+
FC_INSUFFICIENT_LEAD_TIME: 'FC_INSUFFICIENT_LEAD_TIME',
|
|
91
|
+
FC_TOO_FAR_IN_FUTURE: 'FC_TOO_FAR_IN_FUTURE',
|
|
92
|
+
DURATION_INVALID: 'DURATION_INVALID',
|
|
93
|
+
// Operator errors
|
|
94
|
+
INVALID_EMAIL: 'INVALID_EMAIL',
|
|
95
|
+
INVALID_PHONE: 'INVALID_PHONE',
|
|
96
|
+
INVALID_FAA_ID: 'INVALID_FAA_ID',
|
|
97
|
+
// General errors
|
|
98
|
+
REQUIRED_FIELD_MISSING: 'REQUIRED_FIELD_MISSING',
|
|
99
|
+
INVALID_OPERATION_TYPE: 'INVALID_OPERATION_TYPE',
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Advisory priority weights (higher = more critical)
|
|
103
|
+
*/
|
|
104
|
+
export const ADVISORY_PRIORITY_WEIGHTS = {
|
|
105
|
+
critical: 5,
|
|
106
|
+
high: 4,
|
|
107
|
+
medium: 3,
|
|
108
|
+
low: 2,
|
|
109
|
+
info: 1,
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* Authorization status priority (for determining overall status)
|
|
113
|
+
*/
|
|
114
|
+
export const STATUS_PRIORITY = {
|
|
115
|
+
DNF: 5,
|
|
116
|
+
NOK: 4,
|
|
117
|
+
ALERT: 3,
|
|
118
|
+
CAUTION: 2,
|
|
119
|
+
OK: 1,
|
|
120
|
+
};
|
|
121
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../src/core/utils/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,+CAA+C;IAC/C,YAAY,EAAE,GAAG;IACjB,yDAAyD;IACzD,SAAS,EAAE,GAAG;IACd,uBAAuB;IACvB,GAAG,EAAE,CAAC;CACE,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,4BAA4B;IAC5B,UAAU,EAAE,EAAE;IACd,4BAA4B;IAC5B,UAAU,EAAE,IAAI;IAChB,uDAAuD;IACvD,aAAa,EAAE,EAAE;CACT,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,uCAAuC;IACvC,UAAU,EAAE,CAAC;IACb,uCAAuC;IACvC,UAAU,EAAE,GAAG;IACf,qEAAqE;IACrE,QAAQ,EAAE,SAAS;CACX,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,gDAAgD;IAChD,SAAS,EAAE,EAAE;IACb,kDAAkD;IAClD,QAAQ,EAAE,EAAE;CACJ,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,4DAA4D;IAC5D,SAAS,EAAE,CAAC;CACJ,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,qBAAqB;IACrB,cAAc,EAAE,MAAM;IACtB,qBAAqB;IACrB,cAAc,EAAE,OAAO;IACvB,+BAA+B;IAC/B,YAAY,EAAE,IAAI;IAClB,+BAA+B;IAC/B,YAAY,EAAE,CAAC,GAAG,IAAI;IACtB,sBAAsB;IACtB,eAAe,EAAE,OAAO;IACxB,sBAAsB;IACtB,eAAe,EAAE,CAAC,GAAG,OAAO;CACpB,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,kBAAkB;IAClB,uBAAuB,EAAE,yBAAyB;IAClD,uBAAuB,EAAE,yBAAyB;IAClD,sBAAsB,EAAE,wBAAwB;IAChD,uBAAuB,EAAE,yBAAyB;IAClD,iBAAiB,EAAE,mBAAmB;IACtC,yBAAyB,EAAE,2BAA2B;IACtD,mBAAmB,EAAE,qBAAqB;IAE1C,kBAAkB;IAClB,gBAAgB,EAAE,kBAAkB;IACpC,iBAAiB,EAAE,mBAAmB;IACtC,wBAAwB,EAAE,0BAA0B;IAEpD,kBAAkB;IAClB,gBAAgB,EAAE,kBAAkB;IACpC,gBAAgB,EAAE,kBAAkB;IACpC,iBAAiB,EAAE,mBAAmB;IACtC,yBAAyB,EAAE,2BAA2B;IACtD,oBAAoB,EAAE,sBAAsB;IAC5C,gBAAgB,EAAE,kBAAkB;IAEpC,kBAAkB;IAClB,aAAa,EAAE,eAAe;IAC9B,aAAa,EAAE,eAAe;IAC9B,cAAc,EAAE,gBAAgB;IAEhC,iBAAiB;IACjB,sBAAsB,EAAE,wBAAwB;IAChD,sBAAsB,EAAE,wBAAwB;CACxC,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,QAAQ,EAAE,CAAC;IACX,IAAI,EAAE,CAAC;IACP,MAAM,EAAE,CAAC;IACT,GAAG,EAAE,CAAC;IACN,IAAI,EAAE,CAAC;CACC,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,GAAG,EAAE,CAAC;IACN,GAAG,EAAE,CAAC;IACN,KAAK,EAAE,CAAC;IACR,OAAO,EAAE,CAAC;IACV,EAAE,EAAE,CAAC;CACG,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { UNIT_CONVERSIONS } from './constants';
|
|
2
|
+
/**
|
|
3
|
+
* Convert feet to meters
|
|
4
|
+
*/
|
|
5
|
+
export function feetToMeters(feet) {
|
|
6
|
+
return feet * UNIT_CONVERSIONS.FEET_TO_METERS;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Convert meters to feet
|
|
10
|
+
*/
|
|
11
|
+
export function metersToFeet(meters) {
|
|
12
|
+
return meters * UNIT_CONVERSIONS.METERS_TO_FEET;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Convert nautical miles to meters
|
|
16
|
+
*/
|
|
17
|
+
export function nauticalMilesToMeters(nm) {
|
|
18
|
+
return nm * UNIT_CONVERSIONS.NM_TO_METERS;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Convert meters to nautical miles
|
|
22
|
+
*/
|
|
23
|
+
export function metersToNauticalMiles(meters) {
|
|
24
|
+
return meters * UNIT_CONVERSIONS.METERS_TO_NM;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Convert miles to meters
|
|
28
|
+
*/
|
|
29
|
+
export function milesToMeters(miles) {
|
|
30
|
+
return miles * UNIT_CONVERSIONS.MILES_TO_METERS;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Convert meters to miles
|
|
34
|
+
*/
|
|
35
|
+
export function metersToMiles(meters) {
|
|
36
|
+
return meters * UNIT_CONVERSIONS.METERS_TO_MILES;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Check if a value is a valid finite number
|
|
40
|
+
*/
|
|
41
|
+
export function isValidNumber(value) {
|
|
42
|
+
return typeof value === 'number' && isFinite(value);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Check if a string is non-empty
|
|
46
|
+
*/
|
|
47
|
+
export function isNonEmptyString(value) {
|
|
48
|
+
return typeof value === 'string' && value.trim().length > 0;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Generate a unique ID
|
|
52
|
+
*/
|
|
53
|
+
export function generateId(prefix = '') {
|
|
54
|
+
const timestamp = Date.now().toString(36);
|
|
55
|
+
const randomStr = Math.random().toString(36).substring(2, 9);
|
|
56
|
+
return prefix ? `${prefix}_${timestamp}_${randomStr}` : `${timestamp}_${randomStr}`;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Deep clone an object (simple implementation for GeoJSON)
|
|
60
|
+
*/
|
|
61
|
+
export function deepClone(obj) {
|
|
62
|
+
return JSON.parse(JSON.stringify(obj));
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Round a number to a specified number of decimal places
|
|
66
|
+
*/
|
|
67
|
+
export function roundTo(value, decimals) {
|
|
68
|
+
const multiplier = Math.pow(10, decimals);
|
|
69
|
+
return Math.round(value * multiplier) / multiplier;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Format a number as a string with commas
|
|
73
|
+
*/
|
|
74
|
+
export function formatNumber(value, decimals = 0) {
|
|
75
|
+
return value.toFixed(decimals).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Clamp a value between min and max
|
|
79
|
+
*/
|
|
80
|
+
export function clamp(value, min, max) {
|
|
81
|
+
return Math.min(Math.max(value, min), max);
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../../src/core/utils/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,IAAI,GAAG,gBAAgB,CAAC,cAAc,CAAC;AAChD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,OAAO,MAAM,GAAG,gBAAgB,CAAC,cAAc,CAAC;AAClD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,EAAU;IAC9C,OAAO,EAAE,GAAG,gBAAgB,CAAC,YAAY,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAAc;IAClD,OAAO,MAAM,GAAG,gBAAgB,CAAC,YAAY,CAAC;AAChD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,OAAO,KAAK,GAAG,gBAAgB,CAAC,eAAe,CAAC;AAClD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,OAAO,MAAM,GAAG,gBAAgB,CAAC,eAAe,CAAC;AACnD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC;AACtD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;AAC9D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,MAAM,GAAG,EAAE;IACpC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7D,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,SAAS,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,GAAG,SAAS,IAAI,SAAS,EAAE,CAAC;AACtF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAI,GAAM;IACjC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,OAAO,CAAC,KAAa,EAAE,QAAgB;IACrD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;IAC1C,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC,GAAG,UAAU,CAAC;AACrD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,QAAQ,GAAG,CAAC;IACtD,OAAO,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;AACvE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,KAAK,CAAC,KAAa,EAAE,GAAW,EAAE,GAAW;IAC3D,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
2
|
+
export { ALTITUDE_CONSTRAINTS, CIRCLE_CONSTRAINTS, POLYGON_CONSTRAINTS, FC_CONSTRAINTS, PROXIMITY_CONSTRAINTS, UNIT_CONVERSIONS, ERROR_CODES, ADVISORY_PRIORITY_WEIGHTS, STATUS_PRIORITY, } from './constants';
|
|
3
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
4
|
+
export { feetToMeters, metersToFeet, nauticalMilesToMeters, metersToNauticalMiles, milesToMeters, metersToMiles, isValidNumber, isNonEmptyString, generateId, deepClone, roundTo, formatNumber, clamp, } from './helpers';
|
|
5
|
+
// ─── Timezone ────────────────────────────────────────────────────────────────
|
|
6
|
+
export { detectTimezone, isValidTimezone, getCurrentTimeInTimezone, } from './timezone';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/utils/index.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,qBAAqB,EACrB,gBAAgB,EAChB,WAAW,EACX,yBAAyB,EACzB,eAAe,GAChB,MAAM,aAAa,CAAC;AAErB,gFAAgF;AAChF,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,qBAAqB,EACrB,qBAAqB,EACrB,aAAa,EACb,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,SAAS,EACT,OAAO,EACP,YAAY,EACZ,KAAK,GACN,MAAM,WAAW,CAAC;AAEnB,gFAAgF;AAChF,OAAO,EACL,cAAc,EACd,eAAe,EACf,wBAAwB,GACzB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { find } from 'geo-tz';
|
|
2
|
+
/**
|
|
3
|
+
* Detect timezone from latitude/longitude coordinates
|
|
4
|
+
*
|
|
5
|
+
* @param lat - Latitude
|
|
6
|
+
* @param lng - Longitude
|
|
7
|
+
* @returns IANA timezone identifier (e.g., "America/New_York")
|
|
8
|
+
*/
|
|
9
|
+
export function detectTimezone(lat, lng) {
|
|
10
|
+
try {
|
|
11
|
+
const timezones = find(lat, lng);
|
|
12
|
+
if (timezones && timezones.length > 0) {
|
|
13
|
+
return timezones[0];
|
|
14
|
+
}
|
|
15
|
+
// Fallback to UTC if no timezone found
|
|
16
|
+
return 'UTC';
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
console.warn('Failed to detect timezone:', error);
|
|
20
|
+
return 'UTC';
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Validate IANA timezone identifier
|
|
25
|
+
*
|
|
26
|
+
* @param timezone - IANA timezone identifier
|
|
27
|
+
* @returns true if valid, false otherwise
|
|
28
|
+
*/
|
|
29
|
+
export function isValidTimezone(timezone) {
|
|
30
|
+
try {
|
|
31
|
+
Intl.DateTimeFormat(undefined, { timeZone: timezone });
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get current time in a specific timezone
|
|
40
|
+
*
|
|
41
|
+
* @param timezone - IANA timezone identifier
|
|
42
|
+
* @returns ISO datetime string
|
|
43
|
+
*/
|
|
44
|
+
export function getCurrentTimeInTimezone(timezone) {
|
|
45
|
+
return new Date().toLocaleString('en-US', { timeZone: timezone });
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=timezone.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timezone.js","sourceRoot":"","sources":["../../../../src/core/utils/timezone.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAE9B;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW,EAAE,GAAW;IACrD,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACjC,IAAI,SAAS,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;QACtB,CAAC;QACD,uCAAuC;QACvC,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;QAClD,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,IAAI,CAAC;QACH,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QACvD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,QAAgB;IACvD,OAAO,IAAI,IAAI,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;AACpE,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validation utilities for LAANC authorization
|
|
3
|
+
*
|
|
4
|
+
* This module provides basic format validation functions for operator information.
|
|
5
|
+
* Complex business logic validation (altitude, datetime, airspace) is now handled
|
|
6
|
+
* by the backend API.
|
|
7
|
+
*/
|
|
8
|
+
// Basic format validators (for immediate UI feedback)
|
|
9
|
+
export * from './operator.validator';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/validation/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,sDAAsD;AACtD,cAAc,sBAAsB,CAAC"}
|