Compare commits

..

17 Commits

Author SHA1 Message Date
a045942630 Merge branch '96-switch-from-azure-table-storage-to-sqlite' of https://github.com/noahspannbauer/noahspan-flying into 96-switch-from-azure-table-storage-to-sqlite
Please enter a commit message to explain why this merge is necessary,
 especially if it merges an updated upstream into a topic branch.

 Lines starting with '#' will be ignored, and an empty message aborts
 the commit.
2025-11-23 11:14:14 -06:00
2236132340 updating infrastructure 2025-11-23 11:14:07 -06:00
6baff58a36 Merge branch 'main' into 96-switch-from-azure-table-storage-to-sqlite 2025-11-23 11:04:17 -06:00
b5093045e3 updating infrastructure 2025-11-23 11:03:39 -06:00
b85b58a324 Merge branch '96-switch-from-azure-table-storage-to-sqlite' of https://github.com/noahspannbauer/noahspan-flying into 96-switch-from-azure-table-storage-to-sqlite
Please enter a commit message to explain why this merge is necessary,
 especially if it merges an updated upstream into a topic branch.

 Lines starting with '#' will be ignored, and an empty message aborts
 the commit.
2025-11-23 11:00:01 -06:00
bffbf35a43 updating infrastructure 2025-11-23 10:59:53 -06:00
73f08c970b Merge branch 'main' into 96-switch-from-azure-table-storage-to-sqlite 2025-11-23 10:48:39 -06:00
662dcc0a64 updating infrastructure 2025-11-23 10:47:54 -06:00
3ca72b2c7d updating infrastructure 2025-11-23 10:43:27 -06:00
0ea7e48b90 updating infrastructure 2025-11-23 10:43:19 -06:00
23b0361718 updating infrastructure 2025-11-23 10:24:57 -06:00
2a596b29f7 updating terraform 2025-11-20 19:08:24 -06:00
280b222d9a migrating to sqlite 2025-10-24 08:31:13 -05:00
05b17878d7 switching to sqlite 2025-10-02 12:00:24 -05:00
ab304a469b switching to sqlite 2025-08-20 21:04:32 -05:00
e1605992b0 switching to sqlite 2025-08-07 14:59:06 -05:00
25886c8498 adding typeorm to api 2025-07-24 21:11:13 -05:00
35 changed files with 499 additions and 151 deletions

View File

@@ -23,13 +23,13 @@ jobs:
- name: Log in to Azure - name: Log in to Azure
uses: azure/login@v2 uses: azure/login@v2
with: with:
client-id: ${{ vars.AZURE_CLIENT_ID }} client-id: ${{ vars.VITE_CLIENT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
tenant-id: ${{ vars.AZURE_TENANT_ID }} tenant-id: ${{ vars.VITE_TENANT_ID }}
- name: Azure CLI script - name: Azure CLI script
uses: azure/cli@v2 uses: azure/cli@v2
with: with:
azcliversion: latest azcliversion: latest
inlineScript: | inlineScript: |
az containerapp update --name ${{ inputs.app_name }}-${{ inputs.environment_name }} --container-name ${{ inputs.app_name }} --resource-group noahspan --image docker.io/noahspan/${{ inputs.app_name }}:${{ inputs.version_number }} az containerapp update --name ${{ inputs.app_name }}-${{ inputs.environment_name }} --resource-group noahspan-flying --image docker.io/noahspan/${{ inputs.app_name }}:${{ inputs.version_number }}

View File

@@ -1,6 +1,6 @@
{ {
"name": "api", "name": "api",
"version": "2.0.0-alpha-3", "version": "2.0.0-alpha-1",
"description": "", "description": "",
"author": "", "author": "",
"private": true, "private": true,

View File

@@ -30,25 +30,25 @@ import { join } from 'path';
isGlobal: true, isGlobal: true,
load: [configuration] load: [configuration]
}), }),
HealthModule, // HealthModule,
LogModule, LogModule,
// MsGraphModule.registerAsync({
// inject: [ConfigService],
// imports: [ConfigModule],
// useFactory: async (configService: ConfigService) => {
// return {
// clientId: configService.get<string>('clientId'),
// clientSecret: configService.get<string>('clientSecret'),
// tenantId: configService.get<string>('tenantId')
// }
// }
// }),
PilotModule, PilotModule,
ServeStaticModule.forRoot({ ServeStaticModule.forRoot({
rootPath: join(__dirname, '../..', 'client', 'dist') rootPath: join(__dirname, '../..', 'client', 'dist')
}), }),
TrackModule, TrackModule,
TypeOrmModule.forRoot(dataSourceOptions) TypeOrmModule.forRoot(dataSourceOptions),
MsGraphModule.registerAsync({
inject: [ConfigService],
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => {
return {
clientId: configService.get<string>('clientId'),
clientSecret: configService.get<string>('clientSecret'),
tenantId: configService.get<string>('tenantId')
}
}
})
], ],
providers: [ providers: [
{ {

View File

@@ -1,5 +1,5 @@
import { JwtPayload } from "jwt-decode"; import { JwtPayload } from "jwt-decode";
export interface CustomJwtPayload extends JwtPayload { export interface CustomJwtPayload extends JwtPayload {
permissions: string[]; roles: string[];
} }

View File

@@ -37,10 +37,11 @@ export class LogController {
@Param('id') id: string, @Param('id') id: string,
): Promise<LogEntity> { ): Promise<LogEntity> {
try { try {
console.log(id)
return await this.logService.find(id); return await this.logService.find(id);
} catch (error) { } catch (error) {
const customError = error as CustomError; const customError = error as CustomError;
console.log(error)
throw new HttpException(customError.message, customError.statusCode); throw new HttpException(customError.message, customError.statusCode);
} }
} }
@@ -49,10 +50,11 @@ export class LogController {
@Public() @Public()
async findAll(): Promise<LogEntity[]> { async findAll(): Promise<LogEntity[]> {
try { try {
console.log('blah')
return await this.logService.findAll(); return await this.logService.findAll();
} catch (error) { } catch (error) {
const customError = error as CustomError; const customError = error as CustomError;
console.log(error)
throw new HttpException(customError.message, customError.statusCode); throw new HttpException(customError.message, customError.statusCode);
} }
} }
@@ -65,7 +67,7 @@ export class LogController {
return await this.logService.create(logDto); return await this.logService.create(logDto);
} catch (error) { } catch (error) {
const customError = error as CustomError; const customError = error as CustomError;
console.log(error)
throw new HttpException(customError.message, customError.statusCode); throw new HttpException(customError.message, customError.statusCode);
} }
} }
@@ -77,10 +79,12 @@ export class LogController {
@Body() logDto: LogDto @Body() logDto: LogDto
): Promise<UpdateResult> { ): Promise<UpdateResult> {
try { try {
console.log(id)
console.log(logDto)
return await this.logService.update(id, logDto); return await this.logService.update(id, logDto);
} catch (error) { } catch (error) {
const customError = error as CustomError; const customError = error as CustomError;
console.log(error)
throw new HttpException(customError.message, customError.statusCode); throw new HttpException(customError.message, customError.statusCode);
} }
} }
@@ -93,6 +97,7 @@ export class LogController {
try { try {
return await this.logService.delete(id); return await this.logService.delete(id);
} catch (error) { } catch (error) {
console.log(error)
const customError = error as CustomError; const customError = error as CustomError;
throw new HttpException(customError.message, customError.statusCode); throw new HttpException(customError.message, customError.statusCode);

View File

@@ -2,6 +2,7 @@ import { CallHandler, ExecutionContext, NestInterceptor, UnauthorizedException }
import { Observable, map } from 'rxjs'; import { Observable, map } from 'rxjs';
import { LogEntity } from './log.entity'; import { LogEntity } from './log.entity';
import { jwtDecode } from 'jwt-decode'; import { jwtDecode } from 'jwt-decode';
import { CustomJwtPayload } from 'src/interfaces/customJwtPayload.interface';
import { IS_PUBLIC_KEY } from '@noahspan/noahspan-modules'; import { IS_PUBLIC_KEY } from '@noahspan/noahspan-modules';
import { Reflector } from '@nestjs/core'; import { Reflector } from '@nestjs/core';
@@ -37,10 +38,9 @@ export class LogInterceptor implements NestInterceptor {
if (req.headers.authorization) { if (req.headers.authorization) {
const authHeader = req.headers.authorization; const authHeader = req.headers.authorization;
const token = authHeader && authHeader.split(' ')[1]; const token = authHeader && authHeader.split(' ')[1];
const jwtPayload = jwtDecode(token); const jwtPayload: CustomJwtPayload = jwtDecode(token);
const rolesKeyName = Object.keys(jwtPayload).find((key) => key.includes('roles'));
if (jwtPayload[rolesKeyName].includes('Flying.Read')) { if (jwtPayload.roles.includes('Flying.Read')) {
const logs = limitData(data); const logs = limitData(data);
return logs; return logs;

View File

@@ -43,7 +43,7 @@ export class PilotController {
return await this.pilotService.findAll(); return await this.pilotService.findAll();
} catch (error) { } catch (error) {
const customError = error as CustomError; const customError = error as CustomError;
console.log(error)
throw new HttpException(customError.message, customError.statusCode); throw new HttpException(customError.message, customError.statusCode);
} }
} }
@@ -55,9 +55,10 @@ export class PilotController {
return await this.pilotService.create(pilotDto); return await this.pilotService.create(pilotDto);
} catch (error) { } catch (error) {
const customError = error as CustomError; console.log(error)
// const customError = error as CustomError;
throw new HttpException(customError.message, customError.statusCode); // throw new HttpException(customError.message, customError.statusCode);
} }
} }

View File

@@ -1,6 +1,7 @@
import { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common'; import { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common';
import { jwtDecode } from 'jwt-decode'; import { jwtDecode } from 'jwt-decode';
import { Observable, map } from 'rxjs'; import { Observable, map } from 'rxjs';
import { CustomJwtPayload } from 'src/interfaces/customJwtPayload.interface';
import { PilotEntity } from './pilot.entity'; import { PilotEntity } from './pilot.entity';
import { IS_PUBLIC_KEY } from '@noahspan/noahspan-modules'; import { IS_PUBLIC_KEY } from '@noahspan/noahspan-modules';
import { Reflector } from '@nestjs/core'; import { Reflector } from '@nestjs/core';
@@ -25,14 +26,13 @@ export class PilotInterceptor implements NestInterceptor {
}; };
}) })
} }
console.log(req.headers.authorization)
if (req.headers.authorization) { if (req.headers.authorization) {
const authHeader = req.headers.authorization; const authHeader = req.headers.authorization;
const token = authHeader && authHeader.split(' ')[1]; const token = authHeader && authHeader.split(' ')[1];
const jwtPayload = jwtDecode(token); const jwtPayload: CustomJwtPayload = jwtDecode(token);
const rolesKeyName = Object.keys(jwtPayload).find((key) => key.includes('roles'));
if (jwtPayload[rolesKeyName].includes('Flying.Read')) { if (jwtPayload.roles.includes('Flying.Read')) {
const pilots = limitData(data) const pilots = limitData(data)
return pilots; return pilots;

View File

@@ -1 +0,0 @@
BLAH BLAH

View File

@@ -1,7 +1,7 @@
{ {
"name": "client", "name": "client",
"private": true, "private": true,
"version": "2.0.0-alpha-3", "version": "2.0.0-alpha-1",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
@@ -14,14 +14,12 @@
"@fortawesome/fontawesome-svg-core": "^7.1.0", "@fortawesome/fontawesome-svg-core": "^7.1.0",
"@fortawesome/free-solid-svg-icons": "^7.1.0", "@fortawesome/free-solid-svg-icons": "^7.1.0",
"@fortawesome/react-fontawesome": "^3.1.0", "@fortawesome/react-fontawesome": "^3.1.0",
"@heroui/react": "^2.8.5",
"@noahspan/noahspan-components": "^2.0.0-alpha-14", "@noahspan/noahspan-components": "^2.0.0-alpha-14",
"@tailwindcss/typography": "^0.5.19",
"@tailwindcss/vite": "^4.1.13", "@tailwindcss/vite": "^4.1.13",
"@tanstack/react-table": "^8.21.3", "@tanstack/react-table": "^8.21.3",
"axios": "^1.7.2", "axios": "^1.7.2",
"daisyui": "^5.1.10",
"dotenv": "^16.4.7", "dotenv": "^16.4.7",
"framer-motion": "^12.23.24",
"leaflet": "^1.9.4", "leaflet": "^1.9.4",
"oidc-spa": "^7.2.4", "oidc-spa": "^7.2.4",
"react": "^19.1.1", "react": "^19.1.1",

View File

@@ -5,6 +5,7 @@ import Pilots from './components/pilots/Pilots';
import SiteNav from './components/siteNav/SiteNav'; import SiteNav from './components/siteNav/SiteNav';
import { HeroUIProvider } from '@heroui/react'; import { HeroUIProvider } from '@heroui/react';
import { useHref, useNavigate } from 'react-router-dom'; import { useHref, useNavigate } from 'react-router-dom';
import './styles.css';
const App = () => { const App = () => {
const navigate = useNavigate(); const navigate = useNavigate();

View File

@@ -1,13 +1,11 @@
import { createReactOidc } from "oidc-spa/react"; import { createReactOidc } from "oidc-spa/react";
export const { OidcProvider, useOidc, getOidc } = createReactOidc(async () => ({ export const { OidcProvider, useOidc, getOidc } = createReactOidc(async () => ({
issuerUri: import.meta.env.VITE_ISSUER_URI, issuerUri: `https://login.microsoftonline.com/${import.meta.env.VITE_TENANT_ID}/v2.0`,
clientId: import.meta.env.VITE_CLIENT_ID, clientId: import.meta.env.VITE_CLIENT_APP_ID,
homeUrl: import.meta.env.VITE_BASE_URL, homeUrl: import.meta.env.BASE_URL,
scopes: ['email', 'openid', 'profile', `api://${import.meta.env.VITE_API_APP_ID}/user_impersonation`],
autoLogin: false, autoLogin: false,
postLoginRedirectUrl: '/', postLoginRedirectUrl: '/',
noIframe: true, noIframe: true
extraQueryParams: {
audience: "api://flying-test-api"
}
})); }));

View File

@@ -12,7 +12,6 @@ const Flights = () => {
const { logs, logsLoading } = useLogs(); const { logs, logsLoading } = useLogs();
useEffect(() => { useEffect(() => {
const flights: LogbookEntry[] | undefined = logs?.filter((log: LogbookEntry) => { const flights: LogbookEntry[] | undefined = logs?.filter((log: LogbookEntry) => {
if (log.tracks && log.tracks.length > 0) { if (log.tracks && log.tracks.length > 0) {
return log; return log;
@@ -27,6 +26,10 @@ const Flights = () => {
} }
}, [logs]) }, [logs])
useEffect(() => {
console.log(logsLoading)
}, [logsLoading])
return ( return (
<div className='max-w-screen-lg mx-auto'> <div className='max-w-screen-lg mx-auto'>
<div className='prose mt-5 mb-5'> <div className='prose mt-5 mb-5'>

View File

@@ -508,6 +508,7 @@ const Logbook: React.FC<unknown> = () => {
onPress={() => onOpenCloseDrawer(FormMode.ADD)} onPress={() => onOpenCloseDrawer(FormMode.ADD)}
startContent={<FontAwesomeIcon icon={faAdd} />} startContent={<FontAwesomeIcon icon={faAdd} />}
data-testid="pilot-add-button" data-testid="pilot-add-button"
data-theme="lofi"
> >
Add Entry Add Entry
</Button> </Button>

View File

@@ -6,6 +6,7 @@ const LogbookCard = ({ logs, mode, onDelete, onOpenCloseForm }: LogbookCardProps
return ( return (
<div> <div>
{logs.map((log) => { {logs.map((log) => {
console.log(log)
const date = new Date(log.date); const date = new Date(log.date);
const formattedDate: string = `${date.getMonth()}/${date.getDate()}/${date.getFullYear()}`; const formattedDate: string = `${date.getMonth()}/${date.getDate()}/${date.getFullYear()}`;

View File

@@ -48,6 +48,7 @@ const LogbookDrawer = ({ onOpenClose }: LogbookDrawerProps) => {
}; };
const onSubmit = async (data: unknown) => { const onSubmit = async (data: unknown) => {
console.log(data)
try { try {
logbookContext.dispatch({ type: 'SET_IS_FORM_LOADING', payload: true }); logbookContext.dispatch({ type: 'SET_IS_FORM_LOADING', payload: true });

View File

@@ -50,6 +50,7 @@ const Pilots: React.FC<unknown> = () => {
}; };
const onOpenClosePilotForm = async (mode: FormMode, pilotId?: string) => { const onOpenClosePilotForm = async (mode: FormMode, pilotId?: string) => {
console.log(pilotId)
switch (mode) { switch (mode) {
case FormMode.ADD: case FormMode.ADD:
case FormMode.EDIT: case FormMode.EDIT:

View File

@@ -101,11 +101,16 @@ const TracksForm = () => {
}, [logbookContext.state.selectedLogId]) }, [logbookContext.state.selectedLogId])
useEffect(() => { useEffect(() => {
console.log(logbookContext.state.formMode)
if (logbookContext.state.formMode === FormMode.VIEW) { if (logbookContext.state.formMode === FormMode.VIEW) {
dispatch({ type: 'SET_IS_DISABLED', payload: true }); dispatch({ type: 'SET_IS_DISABLED', payload: true });
} }
}, [logbookContext.state.formMode]); }, [logbookContext.state.formMode]);
useEffect(() => {
console.log(state.isDisabled)
}, [state.isDisabled])
return ( return (
<div className='grid grid-cols-12 gap-3'> <div className='grid grid-cols-12 gap-3'>
{state.tracks.length > 0 && {state.tracks.length > 0 &&

View File

@@ -11,7 +11,7 @@ export const useBreakpoints = () => {
switch (true) { switch (true) {
case width < 640: { case width < 640: {
size = ScreenSize.SM; size = ScreenSize.SM;
console.log('small')
break; break;
} }
case width >= 640: { case width >= 640: {
@@ -42,10 +42,14 @@ export const useBreakpoints = () => {
const onWindowResize = () => { const onWindowResize = () => {
const width: number = window.innerWidth; const width: number = window.innerWidth;
const newScreenSize: ScreenSize = getWindowSize(width); const newScreenSize: ScreenSize = getWindowSize(width);
console.log(newScreenSize)
setScreenSize(newScreenSize); setScreenSize(newScreenSize);
} }
useEffect(() => {
console.log(windowWidth)
}, [])
useEffect(() => { useEffect(() => {
onWindowResize() onWindowResize()

View File

@@ -8,8 +8,7 @@ export const useUserRole = () => {
useEffect(() => { useEffect(() => {
if (isUserLoggedIn && decodedIdToken) { if (isUserLoggedIn && decodedIdToken) {
const rolesKeyName: string | undefined = Object.keys(decodedIdToken).find((key) => key.includes('roles')); const idTokenRoles: string[] = decodedIdToken!.roles as string[];
const idTokenRoles: string[] = decodedIdToken[rolesKeyName!] as string[];
let newUserRole: string | undefined; let newUserRole: string | undefined;

View File

@@ -5,7 +5,6 @@ import AppContextProvider from './context/appContext/AppContextProvider.tsx';
import LogbookContextProvider from './context/logbookContext/LogbookContextProvider.tsx' import LogbookContextProvider from './context/logbookContext/LogbookContextProvider.tsx'
import { BrowserRouter } from 'react-router-dom'; import { BrowserRouter } from 'react-router-dom';
import { OidcProvider } from './auth/oidcConfig.ts'; import { OidcProvider } from './auth/oidcConfig.ts';
import './styles.css';
ReactDOM.createRoot(document.getElementById('root')!).render( ReactDOM.createRoot(document.getElementById('root')!).render(
<OidcProvider> <OidcProvider>

View File

@@ -10,6 +10,3 @@
} }

View File

@@ -1,10 +1,10 @@
/// <reference types="vite/client" /> /// <reference types="vite/client" />
interface ImportMetaEnv { interface ImportMetaEnv {
readonly VITE_BASE_URL: string; readonly VITE_API_URL: string;
readonly VITE_CLIENT_ID: string; readonly VITE_CLIENT_ID: string;
readonly VITE_ISSUER_URI: string;
readonly VITE_TENANT_ID: string; readonly VITE_TENANT_ID: string;
readonly VITE_REDIRECT_URL: string;
} }
interface ImportMeta { interface ImportMeta {

View File

@@ -19,7 +19,7 @@ export default defineConfig({
target: 'http://localhost:3000', target: 'http://localhost:3000',
changeOrigin: true, changeOrigin: true,
secure: false, secure: false,
rewrite: (path) => path.replace(/^\/api/, '') // rewrite: (path) => path.replace(/^\/api/, '')
} }
} }
} }

View File

@@ -1,25 +1,6 @@
# This file is maintained automatically by "terraform init". # This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates. # Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/azuread" {
version = "3.7.0"
hashes = [
"h1:+DHwtiYCOYEhLMot5KQ0hm+zopmUJwPJ/gJiXVfdNOs=",
"zh:01114beb07eb8415a563ca80a513e7fd11fd6f0670bdd960e9092e58464ab2b7",
"zh:1460c790ca28cc11c3efd4abec076fc5cdd4ae1cc654a45c69e10ca064e0a611",
"zh:161b6dd82cf279e7ac7a31c404f2ace491a5a9e7ec382ace91de2fd18f8c190b",
"zh:1c3e89cf19118fc07d7b04257251fc9897e722c16e0a0df7b07fcd261f8c12e7",
"zh:2eff0bea92c48be0221863ebf7752f491232088f4ec3cbe4da2ebf9f478fed1f",
"zh:69a689198fcac054da30fea6a8abce2f12b667f6f327c9bb388f2c307ee782fd",
"zh:6f5acf42d71a2f5157c54e67b2db9b080c4ebb27b812112c0c84241e66d94803",
"zh:8e0a58ff2c21aff372c66c679db48578be48e99f5cf6727f082cf4b629dbda6c",
"zh:9c88cc06ba7ee1f6e6b43af7e223c4d107fb77e5a984f1441fffb00c3693537f",
"zh:e8656e8143baac71029857c72899f8503cede41f2559c89ce29d21c0436c96fc",
"zh:e8e21913956a3f043c0e65cc95278bdc82f62ff33fd75a56b1919bd63fd14f8a",
"zh:f7f213dd61d1c75b8397d97660cf329870a241e88ec6e0dc07c60725d975252e",
]
}
provider "registry.terraform.io/hashicorp/azurerm" { provider "registry.terraform.io/hashicorp/azurerm" {
version = "4.40.0" version = "4.40.0"
constraints = "4.40.0" constraints = "4.40.0"
@@ -39,22 +20,3 @@ provider "registry.terraform.io/hashicorp/azurerm" {
"zh:f6fd85bfca8516f9f3840acc3f0e5e335f6195b66231c2db05c0fb43dd8aebe1", "zh:f6fd85bfca8516f9f3840acc3f0e5e335f6195b66231c2db05c0fb43dd8aebe1",
] ]
} }
provider "registry.terraform.io/hashicorp/random" {
version = "3.7.2"
hashes = [
"h1:KG4NuIBl1mRWU0KD/BGfCi1YN/j3F7H4YgeeM7iSdNs=",
"zh:14829603a32e4bc4d05062f059e545a91e27ff033756b48afbae6b3c835f508f",
"zh:1527fb07d9fea400d70e9e6eb4a2b918d5060d604749b6f1c361518e7da546dc",
"zh:1e86bcd7ebec85ba336b423ba1db046aeaa3c0e5f921039b3f1a6fc2f978feab",
"zh:24536dec8bde66753f4b4030b8f3ef43c196d69cccbea1c382d01b222478c7a3",
"zh:29f1786486759fad9b0ce4fdfbbfece9343ad47cd50119045075e05afe49d212",
"zh:4d701e978c2dd8604ba1ce962b047607701e65c078cb22e97171513e9e57491f",
"zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
"zh:7b8434212eef0f8c83f5a90c6d76feaf850f6502b61b53c329e85b3b281cba34",
"zh:ac8a23c212258b7976e1621275e3af7099e7e4a3d4478cf8d5d2a27f3bc3e967",
"zh:b516ca74431f3df4c6cf90ddcdb4042c626e026317a33c53f0b445a3d93b720d",
"zh:dc76e4326aec2490c1600d6871a95e78f9050f9ce427c71707ea412a2f2f1a62",
"zh:eac7b63e86c749c7d48f527671c7aee5b4e26c10be6ad7232d6860167f99dbb0",
]
}

View File

@@ -4,16 +4,6 @@ locals {
prod = "flying-prod" prod = "flying-prod"
} }
app_reg_name = {
test = "noahspan-flying-test"
prod = "noahspan-flying-prod"
}
app_reg_federated_identity_credential_subject = {
test = "repo:noahspannbauer/noahspan-flying:environment:test"
prod = "repo:noahspannbauer/noahspan-flying:environment:prod"
}
container_image = { container_image = {
test = "noahspan/flying-app:v2.0.0-alpha" test = "noahspan/flying-app:v2.0.0-alpha"
prod = "noahspan/flying-app:v2.0.0-alpha" prod = "noahspan/flying-app:v2.0.0-alpha"

View File

@@ -2,14 +2,6 @@ output "app_name" {
value = local.app_name[var.environment] value = local.app_name[var.environment]
} }
output "app_reg_name" {
value = local.app_reg_name[var.environment]
}
output "app_reg_federated_identity_credential_subject" {
value = local.app_reg_federated_identity_credential_subject[var.environment]
}
output "container_image" { output "container_image" {
value = local.container_image[var.environment] value = local.container_image[var.environment]
} }

View File

@@ -1,8 +1,3 @@
# data "azuread_application" "app_registration" {
# provider = azuread.external_tenant
# display_name = module.environment.app_reg_name
# }
resource "azurerm_container_app" "container_app" { resource "azurerm_container_app" "container_app" {
name = module.environment.app_name name = module.environment.app_name
container_app_environment_id = data.azurerm_container_app_environment.container_app_environment.id container_app_environment_id = data.azurerm_container_app_environment.container_app_environment.id
@@ -65,7 +60,7 @@ resource "azurerm_container_app" "container_app" {
container { container {
cpu = 0.25 cpu = 0.25
image = "noahspan/flying:19615036250" image = "noahspan/flying-app:v2.0.0-alpha"
memory = "0.5Gi" memory = "0.5Gi"
name = "flying" name = "flying"
@@ -76,7 +71,7 @@ resource "azurerm_container_app" "container_app" {
env { env {
name = "CLIENT_ID" name = "CLIENT_ID"
value = var.CLIENT_ID secret_name = "client-id"
} }
env { env {
@@ -86,7 +81,7 @@ resource "azurerm_container_app" "container_app" {
env { env {
name = "TENANT_ID" name = "TENANT_ID"
value = var.EXTERNAL_TENANT_ID value = var.TENANT_ID
} }
env { env {
@@ -149,6 +144,11 @@ resource "azurerm_container_app" "container_app" {
value = azurerm_storage_account.storage_account.primary_connection_string value = azurerm_storage_account.storage_account.primary_connection_string
} }
secret {
name = "client-id"
value = var.CLIENT_ID
}
secret { secret {
name = "client-secret" name = "client-secret"
value = var.CLIENT_SECRET value = var.CLIENT_SECRET

View File

@@ -1,5 +1,3 @@
provider "azurerm" { provider "azurerm" {
features {} features {}
} }
provider "random" {}

View File

@@ -6,14 +6,6 @@ terraform {
source = "hashicorp/azurerm" source = "hashicorp/azurerm"
version = "4.40.0" version = "4.40.0"
} }
azuread = {
source = "hashicorp/azuread"
}
random = {
source = "hashicorp/random"
}
} }
backend "remote" { backend "remote" {

View File

@@ -21,10 +21,6 @@ variable "RESOURCE_GROUP_NAME" {
type = string type = string
} }
variable "EXTERNAL_TENANT_ID" {
type = string
}
variable "TENANT_ID" { variable "TENANT_ID" {
type = string type = string
} }

419
package-lock.json generated
View File

@@ -1,31 +1,42 @@
{ {
"name": "@noahspan/flying", "name": "@noahspan/flying",
"version": "2.0.0-alpha-3", "version": "2.0.0-alpha",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@noahspan/flying", "name": "@noahspan/flying",
"version": "2.0.0-alpha-3", "version": "2.0.0-alpha",
"workspaces": [ "workspaces": [
"api", "api",
"client", "client",
"tests" "tests"
], ],
"dependencies": {
"@heroui/react": "^2.8.5",
"@tanstack/react-table": "^8.21.3",
"daisyui": "^5.1.10",
"framer-motion": "^12.23.24"
},
"devDependencies": { "devDependencies": {
"@tailwindcss/typography": "^0.5.16",
"@typescript-eslint/eslint-plugin": "^7.2.0", "@typescript-eslint/eslint-plugin": "^7.2.0",
"@typescript-eslint/parser": "^7.2.0", "@typescript-eslint/parser": "^7.2.0",
"concurrently": "^8.2.2",
"eslint": "^8.42.0", "eslint": "^8.42.0",
"eslint-config-prettier": "^9.0.0", "eslint-config-prettier": "^9.0.0",
"eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.6", "eslint-plugin-react-refresh": "^0.4.6",
"husky": "^9.0.11", "husky": "^9.0.11",
"lint-staged": "^15.2.2", "lint-staged": "^15.2.2",
"prettier": "3.2.5" "prettier": "3.2.5",
"rimraf": "^6.0.1",
"turbo": "^2.5.6",
"wait-on": "^7.2.0"
} }
}, },
"api": { "api": {
"version": "2.0.0-alpha-3", "version": "2.0.0-alpha",
"license": "UNLICENSED", "license": "UNLICENSED",
"dependencies": { "dependencies": {
"@azure/storage-blob": "^12.27.0", "@azure/storage-blob": "^12.27.0",
@@ -80,19 +91,17 @@
} }
}, },
"client": { "client": {
"version": "2.0.0-alpha-3", "version": "2.0.0-alpha",
"dependencies": { "dependencies": {
"@fortawesome/fontawesome-svg-core": "^7.1.0", "@fortawesome/fontawesome-svg-core": "^7.1.0",
"@fortawesome/free-solid-svg-icons": "^7.1.0", "@fortawesome/free-solid-svg-icons": "^7.1.0",
"@fortawesome/react-fontawesome": "^3.1.0", "@fortawesome/react-fontawesome": "^3.1.0",
"@heroui/react": "^2.8.5",
"@noahspan/noahspan-components": "^2.0.0-alpha-14", "@noahspan/noahspan-components": "^2.0.0-alpha-14",
"@tailwindcss/typography": "^0.5.19",
"@tailwindcss/vite": "^4.1.13", "@tailwindcss/vite": "^4.1.13",
"@tanstack/react-table": "^8.21.3", "@tanstack/react-table": "^8.21.3",
"axios": "^1.7.2", "axios": "^1.7.2",
"daisyui": "^5.1.10",
"dotenv": "^16.4.7", "dotenv": "^16.4.7",
"framer-motion": "^12.23.24",
"leaflet": "^1.9.4", "leaflet": "^1.9.4",
"oidc-spa": "^7.2.4", "oidc-spa": "^7.2.4",
"react": "^19.1.1", "react": "^19.1.1",
@@ -229,7 +238,6 @@
"version": "5.1.10", "version": "5.1.10",
"resolved": "https://registry.npmjs.org/daisyui/-/daisyui-5.1.10.tgz", "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-5.1.10.tgz",
"integrity": "sha512-p1J/HME2WmaSiy6u2alIbeP3gd5PNVft3+6Bdll0BRSm/UdI4084+pD01LxFug/5wGexNewWqbcEL6nB2n2o+Q==", "integrity": "sha512-p1J/HME2WmaSiy6u2alIbeP3gd5PNVft3+6Bdll0BRSm/UdI4084+pD01LxFug/5wGexNewWqbcEL6nB2n2o+Q==",
"peer": true,
"funding": { "funding": {
"url": "https://github.com/saadeghi/daisyui?sponsor=1" "url": "https://github.com/saadeghi/daisyui?sponsor=1"
} }
@@ -2541,6 +2549,23 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/@hapi/hoek": {
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
"integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==",
"dev": true,
"license": "BSD-3-Clause"
},
"node_modules/@hapi/topo": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz",
"integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"@hapi/hoek": "^9.0.0"
}
},
"node_modules/@heroui/accordion": { "node_modules/@heroui/accordion": {
"version": "2.2.24", "version": "2.2.24",
"resolved": "https://registry.npmjs.org/@heroui/accordion/-/accordion-2.2.24.tgz", "resolved": "https://registry.npmjs.org/@heroui/accordion/-/accordion-2.2.24.tgz",
@@ -4066,6 +4091,29 @@
"@swc/helpers": "^0.5.0" "@swc/helpers": "^0.5.0"
} }
}, },
"node_modules/@isaacs/balanced-match": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz",
"integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": "20 || >=22"
}
},
"node_modules/@isaacs/brace-expansion": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz",
"integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@isaacs/balanced-match": "^4.0.1"
},
"engines": {
"node": "20 || >=22"
}
},
"node_modules/@isaacs/cliui": { "node_modules/@isaacs/cliui": {
"version": "8.0.2", "version": "8.0.2",
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
@@ -7630,6 +7678,30 @@
"tslib": "^2.1.0" "tslib": "^2.1.0"
} }
}, },
"node_modules/@sideway/address": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz",
"integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"@hapi/hoek": "^9.0.0"
}
},
"node_modules/@sideway/formula": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz",
"integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==",
"dev": true,
"license": "BSD-3-Clause"
},
"node_modules/@sideway/pinpoint": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
"integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==",
"dev": true,
"license": "BSD-3-Clause"
},
"node_modules/@sinclair/typebox": { "node_modules/@sinclair/typebox": {
"version": "0.27.8", "version": "0.27.8",
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
@@ -8190,10 +8262,14 @@
"peer": true "peer": true
}, },
"node_modules/@tailwindcss/typography": { "node_modules/@tailwindcss/typography": {
"version": "0.5.19", "version": "0.5.16",
"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.19.tgz", "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.16.tgz",
"integrity": "sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg==", "integrity": "sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==",
"dev": true,
"dependencies": { "dependencies": {
"lodash.castarray": "^4.4.0",
"lodash.isplainobject": "^4.0.6",
"lodash.merge": "^4.6.2",
"postcss-selector-parser": "6.0.10" "postcss-selector-parser": "6.0.10"
}, },
"peerDependencies": { "peerDependencies": {
@@ -10661,6 +10737,34 @@
"typedarray": "^0.0.6" "typedarray": "^0.0.6"
} }
}, },
"node_modules/concurrently": {
"version": "8.2.2",
"resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.2.tgz",
"integrity": "sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==",
"dev": true,
"license": "MIT",
"dependencies": {
"chalk": "^4.1.2",
"date-fns": "^2.30.0",
"lodash": "^4.17.21",
"rxjs": "^7.8.1",
"shell-quote": "^1.8.1",
"spawn-command": "0.0.2",
"supports-color": "^8.1.1",
"tree-kill": "^1.2.2",
"yargs": "^17.7.2"
},
"bin": {
"conc": "dist/bin/concurrently.js",
"concurrently": "dist/bin/concurrently.js"
},
"engines": {
"node": "^14.13.0 || >=16.0.0"
},
"funding": {
"url": "https://github.com/open-cli-tools/concurrently?sponsor=1"
}
},
"node_modules/consola": { "node_modules/consola": {
"version": "3.4.2", "version": "3.4.2",
"resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz",
@@ -10830,6 +10934,7 @@
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
"dev": true,
"bin": { "bin": {
"cssesc": "bin/cssesc" "cssesc": "bin/cssesc"
}, },
@@ -10843,6 +10948,31 @@
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
"devOptional": true "devOptional": true
}, },
"node_modules/daisyui": {
"version": "5.1.31",
"resolved": "https://registry.npmjs.org/daisyui/-/daisyui-5.1.31.tgz",
"integrity": "sha512-p1zRMQ/eEfx1gpExFlyI62NksJ+UxyNC3kH4gYSK0JuL3qFXeo9R5lgkrIvos0V4ukaN+vMKMxGz7Gy6xg1hNg==",
"funding": {
"url": "https://github.com/saadeghi/daisyui?sponsor=1"
}
},
"node_modules/date-fns": {
"version": "2.30.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
"integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.21.0"
},
"engines": {
"node": ">=0.11"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/date-fns"
}
},
"node_modules/date-fns-jalali": { "node_modules/date-fns-jalali": {
"version": "4.1.0-0", "version": "4.1.0-0",
"resolved": "https://registry.npmjs.org/date-fns-jalali/-/date-fns-jalali-4.1.0-0.tgz", "resolved": "https://registry.npmjs.org/date-fns-jalali/-/date-fns-jalali-4.1.0-0.tgz",
@@ -12565,6 +12695,30 @@
"integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/glob": {
"version": "11.0.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz",
"integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==",
"dev": true,
"license": "ISC",
"dependencies": {
"foreground-child": "^3.3.1",
"jackspeak": "^4.1.1",
"minimatch": "^10.0.3",
"minipass": "^7.1.2",
"package-json-from-dist": "^1.0.0",
"path-scurry": "^2.0.0"
},
"bin": {
"glob": "dist/esm/bin.mjs"
},
"engines": {
"node": "20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/glob-parent": { "node_modules/glob-parent": {
"version": "6.0.2", "version": "6.0.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
@@ -12585,6 +12739,22 @@
"dev": true, "dev": true,
"license": "BSD-2-Clause" "license": "BSD-2-Clause"
}, },
"node_modules/glob/node_modules/minimatch": {
"version": "10.0.3",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz",
"integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==",
"dev": true,
"license": "ISC",
"dependencies": {
"@isaacs/brace-expansion": "^5.0.0"
},
"engines": {
"node": "20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/global-dirs": { "node_modules/global-dirs": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz",
@@ -13604,6 +13774,22 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/jackspeak": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz",
"integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"@isaacs/cliui": "^8.0.2"
},
"engines": {
"node": "20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/jest": { "node_modules/jest": {
"version": "29.7.0", "version": "29.7.0",
"resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz",
@@ -14437,6 +14623,20 @@
"jiti": "lib/jiti-cli.mjs" "jiti": "lib/jiti-cli.mjs"
} }
}, },
"node_modules/joi": {
"version": "17.13.3",
"resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz",
"integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"@hapi/hoek": "^9.3.0",
"@hapi/topo": "^5.1.0",
"@sideway/address": "^4.1.5",
"@sideway/formula": "^3.0.1",
"@sideway/pinpoint": "^2.0.0"
}
},
"node_modules/jose": { "node_modules/jose": {
"version": "4.15.9", "version": "4.15.9",
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz",
@@ -15097,6 +15297,12 @@
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/lodash.castarray": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz",
"integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==",
"dev": true
},
"node_modules/lodash.clonedeep": { "node_modules/lodash.clonedeep": {
"version": "4.5.0", "version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
@@ -15301,6 +15507,16 @@
"tslib": "^2.0.3" "tslib": "^2.0.3"
} }
}, },
"node_modules/lru-cache": {
"version": "11.2.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.1.tgz",
"integrity": "sha512-r8LA6i4LP4EeWOhqBaZZjDWwehd1xUJPCJd9Sv300H0ZmcUER4+JPh7bqqZeqs1o5pgtgvXm+d9UGrB5zZGDiQ==",
"dev": true,
"license": "ISC",
"engines": {
"node": "20 || >=22"
}
},
"node_modules/lru-memoizer": { "node_modules/lru-memoizer": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.3.0.tgz", "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.3.0.tgz",
@@ -16821,6 +17037,23 @@
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/path-scurry": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz",
"integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"lru-cache": "^11.0.0",
"minipass": "^7.1.2"
},
"engines": {
"node": "20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/path-to-regexp": { "node_modules/path-to-regexp": {
"version": "8.2.0", "version": "8.2.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz",
@@ -17060,6 +17293,7 @@
"version": "6.0.10", "version": "6.0.10",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
"integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
"dev": true,
"dependencies": { "dependencies": {
"cssesc": "^3.0.0", "cssesc": "^3.0.0",
"util-deprecate": "^1.0.2" "util-deprecate": "^1.0.2"
@@ -17942,6 +18176,26 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/rimraf": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz",
"integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==",
"dev": true,
"license": "ISC",
"dependencies": {
"glob": "^11.0.0",
"package-json-from-dist": "^1.0.0"
},
"bin": {
"rimraf": "dist/esm/bin.mjs"
},
"engines": {
"node": "20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/roarr": { "node_modules/roarr": {
"version": "7.21.1", "version": "7.21.1",
"resolved": "https://registry.npmjs.org/roarr/-/roarr-7.21.1.tgz", "resolved": "https://registry.npmjs.org/roarr/-/roarr-7.21.1.tgz",
@@ -18311,6 +18565,19 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/shell-quote": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz",
"integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel": { "node_modules/side-channel": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
@@ -18574,6 +18841,12 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/spawn-command": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz",
"integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==",
"dev": true
},
"node_modules/spdx-correct": { "node_modules/spdx-correct": {
"version": "3.2.0", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
@@ -19644,6 +19917,108 @@
"node": "*" "node": "*"
} }
}, },
"node_modules/turbo": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/turbo/-/turbo-2.5.6.tgz",
"integrity": "sha512-gxToHmi9oTBNB05UjUsrWf0OyN5ZXtD0apOarC1KIx232Vp3WimRNy3810QzeNSgyD5rsaIDXlxlbnOzlouo+w==",
"dev": true,
"license": "MIT",
"bin": {
"turbo": "bin/turbo"
},
"optionalDependencies": {
"turbo-darwin-64": "2.5.6",
"turbo-darwin-arm64": "2.5.6",
"turbo-linux-64": "2.5.6",
"turbo-linux-arm64": "2.5.6",
"turbo-windows-64": "2.5.6",
"turbo-windows-arm64": "2.5.6"
}
},
"node_modules/turbo-darwin-64": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/turbo-darwin-64/-/turbo-darwin-64-2.5.6.tgz",
"integrity": "sha512-3C1xEdo4aFwMJAPvtlPqz1Sw/+cddWIOmsalHFMrsqqydcptwBfu26WW2cDm3u93bUzMbBJ8k3zNKFqxJ9ei2A==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
]
},
"node_modules/turbo-darwin-arm64": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/turbo-darwin-arm64/-/turbo-darwin-arm64-2.5.6.tgz",
"integrity": "sha512-LyiG+rD7JhMfYwLqB6k3LZQtYn8CQQUePbpA8mF/hMLPAekXdJo1g0bUPw8RZLwQXUIU/3BU7tXENvhSGz5DPA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
]
},
"node_modules/turbo-linux-64": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/turbo-linux-64/-/turbo-linux-64-2.5.6.tgz",
"integrity": "sha512-GOcUTT0xiT/pSnHL4YD6Yr3HreUhU8pUcGqcI2ksIF9b2/r/kRHwGFcsHgpG3+vtZF/kwsP0MV8FTlTObxsYIA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/turbo-linux-arm64": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/turbo-linux-arm64/-/turbo-linux-arm64-2.5.6.tgz",
"integrity": "sha512-10Tm15bruJEA3m0V7iZcnQBpObGBcOgUcO+sY7/2vk1bweW34LMhkWi8svjV9iDF68+KJDThnYDlYE/bc7/zzQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/turbo-windows-64": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/turbo-windows-64/-/turbo-windows-64-2.5.6.tgz",
"integrity": "sha512-FyRsVpgaj76It0ludwZsNN40ytHN+17E4PFJyeliBEbxrGTc5BexlXVpufB7XlAaoaZVxbS6KT8RofLfDRyEPg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
]
},
"node_modules/turbo-windows-arm64": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/turbo-windows-arm64/-/turbo-windows-arm64-2.5.6.tgz",
"integrity": "sha512-j/tWu8cMeQ7HPpKri6jvKtyXg9K1gRyhdK4tKrrchH8GNHscPX/F71zax58yYtLRWTiK04zNzPcUJuoS0+v/+Q==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
]
},
"node_modules/type-check": { "node_modules/type-check": {
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -20672,6 +21047,26 @@
"@esbuild/win32-x64": "0.21.5" "@esbuild/win32-x64": "0.21.5"
} }
}, },
"node_modules/wait-on": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/wait-on/-/wait-on-7.2.0.tgz",
"integrity": "sha512-wCQcHkRazgjG5XoAq9jbTMLpNIjoSlZslrJ2+N9MxDsGEv1HnFoVjOCexL0ESva7Y9cu350j+DWADdk54s4AFQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"axios": "^1.6.1",
"joi": "^17.11.0",
"lodash": "^4.17.21",
"minimist": "^1.2.8",
"rxjs": "^7.8.1"
},
"bin": {
"wait-on": "bin/wait-on"
},
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/walker": { "node_modules/walker": {
"version": "1.0.8", "version": "1.0.8",
"resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",

View File

@@ -1,8 +1,8 @@
{ {
"name": "@noahspan/flying", "name": "@noahspan/flying",
"version": "2.0.0-alpha-3", "version": "2.0.0-alpha-1",
"scripts": { "scripts": {
"start": "node api/dist/main", "start": "concurrently 'npm run start:azure -w api' 'wait-on tcp:0.0.0.0:7071 && npm run dev -w app'",
"format": "prettier --write \"**/src/**/*.ts\" \"**/test/**/*.ts\"", "format": "prettier --write \"**/src/**/*.ts\" \"**/test/**/*.ts\"",
"lint": "npm run lint -w api && npm run lint -w app", "lint": "npm run lint -w api && npm run lint -w app",
"prepare": "husky || true", "prepare": "husky || true",
@@ -12,15 +12,20 @@
"build": "turbo run build" "build": "turbo run build"
}, },
"devDependencies": { "devDependencies": {
"@tailwindcss/typography": "^0.5.16",
"@typescript-eslint/eslint-plugin": "^7.2.0", "@typescript-eslint/eslint-plugin": "^7.2.0",
"@typescript-eslint/parser": "^7.2.0", "@typescript-eslint/parser": "^7.2.0",
"concurrently": "^8.2.2",
"eslint": "^8.42.0", "eslint": "^8.42.0",
"eslint-config-prettier": "^9.0.0", "eslint-config-prettier": "^9.0.0",
"eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.6", "eslint-plugin-react-refresh": "^0.4.6",
"husky": "^9.0.11", "husky": "^9.0.11",
"lint-staged": "^15.2.2", "lint-staged": "^15.2.2",
"prettier": "3.2.5" "prettier": "3.2.5",
"rimraf": "^6.0.1",
"turbo": "^2.5.6",
"wait-on": "^7.2.0"
}, },
"lint-staged": { "lint-staged": {
"**/*": "prettier --write \"**/src/**/*.ts\" \"**/test/**/*.ts\" --ignore-unknown" "**/*": "prettier --write \"**/src/**/*.ts\" \"**/test/**/*.ts\" --ignore-unknown"
@@ -30,5 +35,10 @@
"client", "client",
"tests" "tests"
], ],
"packageManager": "npm@9.8.1" "dependencies": {
"@heroui/react": "^2.8.5",
"@tanstack/react-table": "^8.21.3",
"daisyui": "^5.1.10",
"framer-motion": "^12.23.24"
}
} }