"add PartyEvent API endpoints with service layer and test cases"

This commit is contained in:
louiscklaw
2025-06-15 15:01:18 +08:00
parent 9ac13787aa
commit 9943283eff
23 changed files with 728 additions and 49 deletions

View File

@@ -5,6 +5,7 @@
"description": "Mock server & assets",
"private": true,
"scripts": {
"dev:check": "yarn tsc:w",
"dev": "next dev -p 7272 -H 0.0.0.0",
"start": "next start -p 7272 -H 0.0.0.0",
"build": "next build",
@@ -31,7 +32,9 @@
"db:push": "prisma db push --force-reset",
"db:push:w": "npx nodemon --delay 1 --watch prisma --ext \"ts,tsx,prisma\" --exec \"yarn db:push && yarn seed\"",
"db:studio": "prisma studio",
"db:studio:w": "npx nodemon --delay 1 --watch prisma --ext \"prisma\" --exec \"yarn db:studio\""
"db:studio:w": "npx nodemon --delay 1 --watch prisma --ext \"prisma\" --exec \"yarn db:studio\"",
"db:dev": "yarn db:push && yarn seed && yarn dev",
"db:dev:w": "npx nodemon --delay 1 --ext \"ts,tsx,prisma\" --exec \"yarn db:dev\""
},
"engines": {
"node": ">=20"
@@ -68,6 +71,7 @@
"@types/react": "^18.3.20",
"@types/react-dom": "^18.3.5",
"@typescript-eslint/parser": "^8.28.0",
"concurrently": "^9.1.2",
"eslint": "^9.23.0",
"eslint-import-resolver-typescript": "^4.2.2",
"eslint-plugin-import": "^2.31.0",

View File

@@ -1148,47 +1148,58 @@ model EventReview {
// mapped to IEventItem
// a.k.a. PartyEvent party-event
model EventItem {
id String @id @default(uuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
id String @id @default(uuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
//
available Int
category String
code String
colors String[]
coverUrl String
description String
gender String[]
images String[]
inventoryType String
name String
newLabel Json
price Float
priceSale Float?
publish String
quantity Int
ratings Json[]
saleLabel Json
sizes String[]
sku String
subDescription String
tags String[]
taxes Float
totalRatings Float
totalReviews Int
totalSold Int
available Int @default(99)
category String
code String @default("")
colors String[]
coverUrl String
description String
gender String[]
images String[]
inventoryType String @default("")
name String @default("")
newLabel Json @default("{}")
price Float @default(999.9)
priceSale Float? @default(111.1)
publish String @default("")
quantity Int @default(99)
ratings Json[]
saleLabel Json @default("{}")
sizes String[] @default([""])
sku String @default("")
subDescription String @default("")
tags String[] @default([""])
taxes Float @default(5.0)
totalRatings Float @default(5.0)
totalReviews Int @default(10)
totalSold Int @default(10)
//
ageBottom Float
ageTop Float
avatar String[]
currency String
duration_m Float
eventDate DateTime @default(now())
joinMembers Json[]
location String
title String
ageBottom Float @default(-1)
ageTop Float @default(-1)
avatar String[] @default([""])
currency String @default("HKD")
capacity Int @default(10)
duration_m Float @default(180)
endDate String? @default("")
eventDate DateTime @default(now())
isFeatured Boolean @default(false)
joinMembers Json[] @default([])
location String @default("HK")
organizer String @default("")
registrationDeadline String @default("")
requirements String @default("")
schedule String @default("")
speakers String[] @default([])
sponsors String[] @default([])
startDate String? @default("")
status String? @default("")
title String @default("")
//
reviews EventReview[]
reviews EventReview[]
}
model AppLog {

View File

@@ -5,13 +5,13 @@ yarn --dev
clear
while true; do
yarn db:push
yarn seed
# yarn db:push
# yarn seed
yarn db:studio &
yarn dev
npx nodemon --ext ts,tsx,prisma --exec "yarn dev"
# yarn dev
echo "restarting..."
sleep 1

View File

@@ -0,0 +1,11 @@
#!/usr/bin/env bash
yarn --dev
clear
while true; do
npx nodemon --ext prisma --exec "yarn db:push && yarn seed"
echo "restarting..."
sleep 1
done

View File

@@ -0,0 +1,40 @@
// src/app/api/party-event/create/route.ts
//
// PURPOSE:
// Create new party event in db
//
// RULES:
// T.B.A.
import type { NextRequest } from 'next/server';
import { STATUS, response, handleError } from 'src/utils/response';
import { isDev } from 'src/constants';
import { createEvent } from 'src/app/services/party-event.service';
// ----------------------------------------------------------------------
/** **************************************
* POST - Create PartyEvent
*************************************** */
export async function POST(req: NextRequest) {
const { partyEventData } = await req.json();
try {
if (isDev) {
console.log({ partyEventData });
}
const created = await createEvent(partyEventData);
if (isDev) {
console.log('Event created successfully');
}
return response(created, STATUS.OK);
} catch (error) {
console.error('Error creating event:', { partyEventData });
return handleError('PartyEvent - Create', error);
}
}

View File

@@ -0,0 +1,34 @@
###
POST http://localhost:7272/api/party-event/create
Content-Type: application/json
{
"partyEventData": {
"title": "Summer Music Festival",
"description": "Annual summer music festival featuring local bands and artists",
"startDate": "2024-07-15T18:00:00Z",
"endDate": "2024-07-15T23:00:00Z",
"location": "Central Park, Hong Kong",
"coverUrl": "",
"images": [
"data:image/png;base64,C",
"data:image/png;base64,C"
],
"tags": [
"Music",
"Festival"
],
"status": "upcoming",
"capacity": 500,
"price": 150.00,
"organizer": "HK Music Society",
"category": "Music",
"isFeatured": true,
"registrationDeadline": "2024-07-10T00:00:00Z",
"requirements": "Age 18+",
"schedule": "18:00 Doors open\n19:00 First performance\n21:00 Main act",
"speakers": ["DJ Lee", "Band XYZ"],
"sponsors": ["HK Radio", "Music Magazine"]
}
}

View File

@@ -0,0 +1,22 @@
import type { NextRequest } from 'next/server';
import { STATUS, response, handleError } from 'src/utils/response';
import { deleteEvent } from 'src/app/services/party-event.service';
/** **************************************
* PATCH - Delete PartyEvent
*************************************** */
export async function PATCH(req: NextRequest) {
try {
const { eventId } = await req.json();
if (!eventId) throw new Error('eventId cannot be null');
await deleteEvent(eventId);
return response({ eventId }, STATUS.OK);
} catch (error) {
return handleError('PartyEvent - Delete', error);
}
}

View File

@@ -0,0 +1,8 @@
###
PATCH http://localhost:7272/api/party-event/delete
Content-Type: application/json
{
"eventId": "e99f09a7-dd88-49d5-b1c8-1daf80c2d7b01"
}

View File

@@ -0,0 +1,56 @@
// src/app/api/party-event/details/route.ts
//
// PURPOSE:
// Get party event from db by id
//
// RULES:
// T.B.A.
import type { NextRequest } from 'next/server';
import { logger } from 'src/utils/logger';
import { STATUS, response, handleError } from 'src/utils/response';
import { L_INFO, L_ERROR } from 'src/constants';
import { getEvent } from 'src/app/services/party-event.service';
import { createAppLog } from 'src/app/services/app-log.service';
import { flattenNextjsRequest } from '../../auth/sign-in/flattenNextjsRequest';
// ----------------------------------------------------------------------
/**
**************************************
* GET PartyEvent detail
***************************************
*/
export async function GET(req: NextRequest) {
const debug = { 'req.headers': flattenNextjsRequest(req) };
try {
const { searchParams } = req.nextUrl;
// RULES: eventId must exist
const eventId = searchParams.get('eventId');
if (!eventId) {
return response({ message: 'Event ID is required!' }, STATUS.BAD_REQUEST);
}
// NOTE: eventId confirmed exist, run below
const event = await getEvent(eventId);
if (!event) {
return response({ message: 'Event not found!' }, STATUS.NOT_FOUND);
}
logger('[PartyEvent] details', event.id);
createAppLog(L_INFO, 'Get event detail OK', debug);
return response({ event }, STATUS.OK);
} catch (error) {
createAppLog(L_ERROR, 'event detail error', debug);
return handleError('PartyEvent - Get details', error);
}
}

View File

@@ -0,0 +1,9 @@
###
# Get details for a specific party event
GET http://localhost:7272/api/party-event/details?eventId=e99f09a7-dd88-49d5-b1c8-1daf80c2d7b01
###
# Alternative format with different ID
GET http://localhost:7272/api/party-event/details?eventId=evt_987654321

View File

@@ -0,0 +1,16 @@
import type { NextRequest, NextResponse } from 'next/server';
import { STATUS, response, handleError } from 'src/utils/response';
/**
***************************************
* GET - helloworld
***************************************
*/
export async function GET(req: NextRequest, res: NextResponse) {
try {
return response({ helloworld: 'party-event' }, STATUS.OK);
} catch (error) {
return handleError('Helloworld - Get all', error);
}
}

View File

@@ -0,0 +1,4 @@
###
GET /api/party-event/helloworld HTTP/1.1
Host: localhost:7272

View File

@@ -0,0 +1,38 @@
// src/app/api/party-event/list/route.ts
//
// PURPOSE:
// List all party events from db
//
// RULES:
// T.B.A.
import type { NextRequest } from 'next/server';
import { STATUS, response, handleError } from 'src/utils/response';
import { L_INFO, L_ERROR } from 'src/constants';
import { createAppLog } from 'src/app/services/app-log.service';
import { listEvents } from 'src/app/services/party-event.service';
import { flattenNextjsRequest } from '../../auth/sign-in/flattenNextjsRequest';
// ----------------------------------------------------------------------
/** **************************************
* GET - PartyEvents list
*************************************** */
export async function GET(req: NextRequest) {
const debug = { 'req.headers': flattenNextjsRequest(req) };
try {
const events = await listEvents();
createAppLog(L_INFO, 'party-event list ok', {});
return response({ events }, STATUS.OK);
} catch (error) {
createAppLog(L_ERROR, 'party-event list error', debug);
return handleError('PartyEvent - Get list', error);
}
}

View File

@@ -0,0 +1,14 @@
###
# Basic list all party events
GET http://localhost:7272/api/party-event/list
###
# List upcoming party events
GET http://localhost:7272/api/party-event/list?status=upcoming
###
# List featured party events
GET http://localhost:7272/api/party-event/list?isFeatured=true

View File

@@ -0,0 +1,75 @@
import type { NextRequest, NextResponse } from 'next/server';
import { STATUS, response, handleError } from 'src/utils/response';
import { listEvents, deleteEvent, updateEvent, createEvent } from 'src/app/services/party-event.service';
/**
**************************************
* GET - PartyEvent
***************************************
*/
export async function GET(req: NextRequest, res: NextResponse) {
try {
const events = await listEvents();
return response(events, STATUS.OK);
} catch (error) {
return handleError('PartyEvent - Get list', error);
}
}
/**
***************************************
* POST - Create PartyEvent
***************************************
*/
export async function POST(req: NextRequest) {
const OPERATION = 'PartyEvent - Create';
const { data } = await req.json();
try {
const event = await createEvent(data);
return response(OPERATION, STATUS.OK);
} catch (error) {
return handleError(OPERATION, error);
}
}
/**
***************************************
* PUT - Update PartyEvent
***************************************
*/
export async function PUT(req: NextRequest) {
const { searchParams } = req.nextUrl;
const eventId = searchParams.get('eventId');
const { data } = await req.json();
try {
if (!eventId) throw new Error('eventId cannot be null');
const result = await updateEvent(eventId, data);
return response(result, STATUS.OK);
} catch (error) {
return handleError('PartyEvent - Update', error);
}
}
/**
***************************************
* DELETE - Delete PartyEvent
***************************************
*/
export async function DELETE(req: NextRequest) {
const { searchParams } = req.nextUrl;
const eventId = searchParams.get('eventId');
try {
if (!eventId) throw new Error('eventId cannot be null');
await deleteEvent(eventId);
return response({ success: true }, STATUS.OK);
} catch (error) {
return handleError('PartyEvent - Delete', error);
}
}

View File

@@ -0,0 +1,34 @@
import type { NextRequest } from 'next/server';
import { logger } from 'src/utils/logger';
import { STATUS, response, handleError } from 'src/utils/response';
import { IEventItem } from '../update/route';
// import { searchEvents } from 'src/app/services/party-event.service';
// ----------------------------------------------------------------------
/** **************************************
* GET - Search PartyEvents
*************************************** */
export async function GET(req: NextRequest) {
try {
const { searchParams } = req.nextUrl;
const query = searchParams.get('query')?.trim().toLowerCase();
if (!query) {
return response({ results: [] }, STATUS.OK);
}
const results: IEventItem[] = [];
// TODO: search party event not implemented
console.log('search party event not implemented');
// const results = await searchEvents(query);
logger('[PartyEvent] search-results', results?.length);
return response({ results }, STATUS.OK);
} catch (error) {
return handleError('PartyEvent - Get search', error);
}
}

View File

@@ -0,0 +1,24 @@
###
# Search party events by title
GET http://localhost:7272/api/party-event/search?query=Music
###
# Search party events by location
GET http://localhost:7272/api/party-event/search?query=Central+Park
###
# Search party events by tag
GET http://localhost:7272/api/party-event/search?query=Festival
###
# Combined search with multiple parameters
GET http://localhost:7272/api/party-event/search?query=Summer&location=Hong+Kong&category=Music
###
# No results expected
GET http://localhost:7272/api/party-event/search?query=zzzzzz

View File

@@ -0,0 +1,57 @@
// src/app/api/party-event/update/route.ts
//
// PURPOSE:
// Update party event in db by id
//
// RULES:
// T.B.A.
import type { NextRequest } from 'next/server';
import { STATUS, response, handleError } from 'src/utils/response';
import { updateEvent } from 'src/app/services/party-event.service';
// ----------------------------------------------------------------------
/** **************************************
* PUT - Update PartyEvent
*************************************** */
export async function PUT(req: NextRequest) {
const { partyEventData } = await req.json();
const { id } = partyEventData;
if (!id) return response({ message: 'id not found' }, STATUS.ERROR);
try {
const result = await updateEvent(id, partyEventData);
return response({ result }, STATUS.OK);
} catch (error) {
console.error('Error updating event:', { partyEventData });
return handleError('PartyEvent - Update', error);
}
}
export type IEventItem = {
id: string;
title: string;
description: string;
startDate: Date;
endDate: Date;
location: string;
coverUrl: string;
images: string[];
tags: string[];
status: string;
capacity: number;
price: number;
organizer: string;
category: string;
isFeatured: boolean;
registrationDeadline: Date;
requirements: string[];
schedule: string;
speakers: string[];
sponsors: string[];
};

View File

@@ -0,0 +1,35 @@
###
PUT http://localhost:7272/api/party-event/update
Content-Type: application/json
{
"partyEventData": {
"id":"e99f09a7-dd88-49d5-b1c8-1daf80c2d7b01",
"title": "Summer Music Festival",
"description": "Annual summer music festival featuring local bands and artists",
"startDate": "2024-07-15T18:00:00Z",
"endDate": "2024-07-15T23:00:00Z",
"location": "Central Park, Hong Kong",
"coverUrl": "",
"images": [
"data:image/png;base64,C",
"data:image/png;base64,C"
],
"tags": [
"Music",
"Festival"
],
"status": "upcoming",
"capacity": 500,
"price": 150.00,
"organizer": "HK Music Society",
"category": "Music",
"isFeatured": true,
"registrationDeadline": "2024-07-10T00:00:00Z",
"requirements": "Age 18+",
"schedule": "18:00 Doors open\n19:00 First performance\n21:00 Main act",
"speakers": ["DJ Lee", "Band XYZ"],
"sponsors": ["HK Radio", "Music Magazine"]
}
}

View File

@@ -0,0 +1,92 @@
// src/app/services/party-event.service.ts
//
// PURPOSE:
// - Service for handling EventItem (PartyEvent) Record
//
import type { EventItem } from '@prisma/client';
import prisma from '../lib/prisma';
type CreateEvent = {
name: string;
title: string;
eventDate: Date;
location: string;
duration_m: number;
ageBottom?: number;
ageTop?: number;
currency?: string;
price?: number;
priceSale?: number;
coverUrl?: string;
images?: string[];
description?: string;
subDescription?: string;
publish?: string;
category?: string;
tags?: string[];
joinMembers?: any[];
};
type UpdateEvent = {
name?: string;
title?: string;
eventDate?: Date;
location?: string;
duration_m?: number;
ageBottom?: number;
ageTop?: number;
currency?: string;
price?: number;
priceSale?: number;
coverUrl?: string;
images?: string[];
description?: string;
subDescription?: string;
publish?: string;
category?: string;
tags?: string[];
joinMembers?: any[];
};
async function listEvents(): Promise<EventItem[]> {
return prisma.eventItem.findMany({
include: { reviews: true },
});
}
async function getEvent(eventId: string): Promise<EventItem | null> {
return prisma.eventItem.findUnique({
where: { id: eventId },
include: { reviews: true },
});
}
async function getEventByNameOrTitle(searchText: string): Promise<EventItem[] | null> {
return prisma.eventItem.findMany({
where: {
OR: [{ name: { contains: searchText, mode: 'insensitive' } }, { title: { contains: searchText, mode: 'insensitive' } }],
},
include: { reviews: true },
});
}
async function createEvent(eventData: any) {
return await prisma.eventItem.create({ data: eventData });
}
async function updateEvent(eventId: string, updateForm: UpdateEvent) {
return prisma.eventItem.update({
where: { id: eventId },
data: updateForm,
});
}
async function deleteEvent(eventId: string) {
return prisma.eventItem.delete({
where: { id: eventId },
});
}
export { getEvent, listEvents, createEvent, updateEvent, deleteEvent, getEventByNameOrTitle, type CreateEvent, type UpdateEvent };

View File

@@ -1021,7 +1021,7 @@ ansi-regex@^5.0.1:
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
ansi-styles@^4.1.0:
ansi-styles@^4.0.0, ansi-styles@^4.1.0:
version "4.3.0"
resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz"
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
@@ -1239,7 +1239,7 @@ caniuse-lite@^1.0.30001579:
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001707.tgz"
integrity sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==
chalk@^4.0.0:
chalk@^4.0.0, chalk@^4.1.2:
version "4.1.2"
resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz"
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
@@ -1257,6 +1257,15 @@ client-only@0.0.1:
resolved "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz"
integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==
cliui@^8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa"
integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==
dependencies:
string-width "^4.2.0"
strip-ansi "^6.0.1"
wrap-ansi "^7.0.0"
clsx@^2.1.1:
version "2.1.1"
resolved "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz"
@@ -1284,6 +1293,19 @@ concat-map@0.0.1:
resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
concurrently@^9.1.2:
version "9.1.2"
resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-9.1.2.tgz#22d9109296961eaee773e12bfb1ce9a66bc9836c"
integrity sha512-H9MWcoPsYddwbOGM6difjVwVZHl63nwMEwDJG/L7VGtuaJhb12h2caPG2tVPWs7emuYix252iGfqOyrz1GczTQ==
dependencies:
chalk "^4.1.2"
lodash "^4.17.21"
rxjs "^7.8.1"
shell-quote "^1.8.1"
supports-color "^8.1.1"
tree-kill "^1.2.2"
yargs "^17.7.2"
console-control-strings@^1.0.0, console-control-strings@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
@@ -1614,6 +1636,11 @@ esbuild@~0.25.0:
"@esbuild/win32-ia32" "0.25.5"
"@esbuild/win32-x64" "0.25.5"
escalade@^3.1.1:
version "3.2.0"
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5"
integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==
escape-string-regexp@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz"
@@ -1945,6 +1972,11 @@ gauge@^3.0.0:
strip-ansi "^6.0.1"
wide-align "^1.1.2"
get-caller-file@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
get-intrinsic@^1.2.4, get-intrinsic@^1.2.5, get-intrinsic@^1.2.6, get-intrinsic@^1.2.7, get-intrinsic@^1.3.0:
version "1.3.0"
resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz"
@@ -2985,6 +3017,11 @@ regexp.prototype.flags@^1.5.3:
gopd "^1.2.0"
set-function-name "^2.0.2"
require-directory@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
resolve-from@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz"
@@ -3049,6 +3086,13 @@ run-parallel@^1.1.9:
dependencies:
queue-microtask "^1.2.2"
rxjs@^7.8.1:
version "7.8.2"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.2.tgz#955bc473ed8af11a002a2be52071bf475638607b"
integrity sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==
dependencies:
tslib "^2.1.0"
safe-array-concat@^1.1.3:
version "1.1.3"
resolved "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz"
@@ -3152,6 +3196,11 @@ shebang-regex@^3.0.0:
resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
shell-quote@^1.8.1:
version "1.8.3"
resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.3.tgz#55e40ef33cf5c689902353a3d8cd1a6725f08b4b"
integrity sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==
side-channel-list@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz"
@@ -3222,7 +3271,7 @@ streamsearch@^1.1.0:
resolved "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz"
integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==
"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.2.3:
"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -3297,7 +3346,7 @@ string_decoder@^1.1.1:
dependencies:
safe-buffer "~5.2.0"
strip-ansi@^6.0.1:
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -3333,6 +3382,13 @@ supports-color@^7.1.0:
dependencies:
has-flag "^4.0.0"
supports-color@^8.1.1:
version "8.1.1"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
dependencies:
has-flag "^4.0.0"
supports-preserve-symlinks-flag@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz"
@@ -3370,6 +3426,11 @@ tr46@~0.0.3:
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
tree-kill@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc"
integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==
ts-api-utils@^2.0.1:
version "2.1.0"
resolved "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz"
@@ -3404,7 +3465,7 @@ tsconfig-paths@^3.15.0:
minimist "^1.2.6"
strip-bom "^3.0.0"
tslib@^2.4.0:
tslib@^2.1.0, tslib@^2.4.0:
version "2.8.1"
resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz"
integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
@@ -3612,6 +3673,15 @@ word-wrap@^1.2.5:
resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz"
integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==
wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
@@ -3622,6 +3692,11 @@ xtend@^4.0.0:
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
y18n@^5.0.5:
version "5.0.8"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
yallist@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
@@ -3632,6 +3707,24 @@ yaml@^1.10.0:
resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz"
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
yargs-parser@^21.1.1:
version "21.1.1"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
yargs@^17.7.2:
version "17.7.2"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269"
integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==
dependencies:
cliui "^8.0.1"
escalade "^3.1.1"
get-caller-file "^2.0.5"
require-directory "^2.1.1"
string-width "^4.2.3"
y18n "^5.0.5"
yargs-parser "^21.1.1"
yn@3.1.1:
version "3.1.1"
resolved "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz"

View File

@@ -6,6 +6,7 @@
"private": true,
"type": "module",
"scripts": {
"dev:check": "yarn tsc:w",
"dev": "vite",
"start": "vite preview",
"build": "tsc && vite build",

View File

@@ -79,6 +79,7 @@
"name": "ionic-react-conference-app",
"private": true,
"scripts": {
"dev:check": "yarn tsc:w",
"build": "tsc && vite build --force",
"build:w": "npx nodemon --ext \"ts,tsx\" --exec \"npm run tsc && npm run build\"",
"dev": "vite --force --host 0.0.0.0 --cors",
@@ -94,4 +95,4 @@
"tsc": "tsc --noEmit"
},
"version": "0.0.1"
}
}