Compare commits
56 Commits
userReport
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| c90f8cb1fa | |||
| 71ccea85d2 | |||
| e2706118d1 | |||
| 4e322503cc | |||
| e9685193a4 | |||
| ad3eba48b0 | |||
| 0ccf59344e | |||
| 42122ac341 | |||
| 4dd2ed5839 | |||
| f9a588fcd6 | |||
| 9330f4fd05 | |||
| d6683e6e5e | |||
| bac7df33e8 | |||
| 178ad3fa90 | |||
| ef9f39e564 | |||
| 73218402f6 | |||
| c877577fba | |||
| e119f0923c | |||
| a65b3cac08 | |||
| 0825bb3d65 | |||
| 6740dcb18f | |||
| 12d6c07186 | |||
| 5010a579d6 | |||
| 2cff8eafbd | |||
| 275248fc35 | |||
| 4c2e97b66d | |||
| 21afb085e3 | |||
| ca64a100b6 | |||
| 3c3dfb6cd6 | |||
| 871f33bf5a | |||
| c5dde63355 | |||
| cd13333b52 | |||
| a620921202 | |||
| ed14c57749 | |||
| 7ada05da6a | |||
| 50ece15089 | |||
| 091cb5ba85 | |||
| ebfd633a11 | |||
| 1f4800c055 | |||
| 0ddac10c59 | |||
| 573690ab02 | |||
| efbfa58c10 | |||
| 7ad1e5133e | |||
| 9c3d3f5b72 | |||
| ff9f3d582a | |||
| 60d7a7963d | |||
| 0eede3fa91 | |||
| b1f84722af | |||
| 34e88bdde5 | |||
| aa662a9b74 | |||
| 80110acbf7 | |||
| c36cad9c54 | |||
| 2ecb8a3515 | |||
| 8275da687b | |||
| 10b58245f5 | |||
| 272c9b36dd |
Binary file not shown.
@ -5,6 +5,7 @@ import { ensureUserSynced } from "@/lib/sync-user";
|
|||||||
import { successResponse } from "@/lib/api/responses";
|
import { successResponse } from "@/lib/api/responses";
|
||||||
import { db as rawDb, sql } from "@fitai/database";
|
import { db as rawDb, sql } from "@fitai/database";
|
||||||
import { getUsersByGym, getClientsByGym } from "@/lib/gym-context";
|
import { getUsersByGym, getClientsByGym } from "@/lib/gym-context";
|
||||||
|
import log from "@/lib/logger";
|
||||||
|
|
||||||
interface UserGrowthPoint {
|
interface UserGrowthPoint {
|
||||||
label: string;
|
label: string;
|
||||||
@ -158,7 +159,7 @@ export async function GET(req: NextRequest) {
|
|||||||
|
|
||||||
return successResponse({ analytics: analyticsData });
|
return successResponse({ analytics: analyticsData });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Analytics error:", error);
|
log.error("Analytics error", error);
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ error: "Internal server error" },
|
{ error: "Internal server error" },
|
||||||
{ status: 500 },
|
{ status: 500 },
|
||||||
|
|||||||
103
apps/admin/src/app/api/admin/set-role/__tests__/route.test.ts
Normal file
103
apps/admin/src/app/api/admin/set-role/__tests__/route.test.ts
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/**
|
||||||
|
* @jest-environment node
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { NextRequest } from "next/server";
|
||||||
|
import { POST } from "../route";
|
||||||
|
|
||||||
|
jest.mock("@clerk/nextjs/server", () => ({
|
||||||
|
auth: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/lib/database", () => ({
|
||||||
|
getDatabase: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/lib/sync-user", () => ({
|
||||||
|
ensureUserSynced: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/lib/clerk-helpers", () => ({
|
||||||
|
setUserRole: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("POST /api/admin/set-role", () => {
|
||||||
|
const mockAuth = require("@clerk/nextjs/server").auth as jest.Mock;
|
||||||
|
const mockGetDatabase = require("@/lib/database").getDatabase as jest.Mock;
|
||||||
|
const mockEnsureUserSynced = require("@/lib/sync-user")
|
||||||
|
.ensureUserSynced as jest.Mock;
|
||||||
|
const mockSetUserRole = require("@/lib/clerk-helpers")
|
||||||
|
.setUserRole as jest.Mock;
|
||||||
|
|
||||||
|
const mockDb = {
|
||||||
|
getUserById: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
mockGetDatabase.mockResolvedValue(mockDb);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns 403 when admin tries to assign role across gyms", async () => {
|
||||||
|
mockAuth.mockResolvedValue({ userId: "admin_1" });
|
||||||
|
mockEnsureUserSynced.mockResolvedValue({
|
||||||
|
id: "admin_1",
|
||||||
|
role: "admin",
|
||||||
|
gymId: "gym_a",
|
||||||
|
});
|
||||||
|
mockDb.getUserById.mockResolvedValue({
|
||||||
|
id: "user_2",
|
||||||
|
role: "client",
|
||||||
|
gymId: "gym_b",
|
||||||
|
});
|
||||||
|
|
||||||
|
const request = new NextRequest("http://localhost/api/admin/set-role", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
targetUserId: "user_2",
|
||||||
|
role: "trainer",
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await POST(request);
|
||||||
|
|
||||||
|
expect(response.status).toBe(403);
|
||||||
|
expect(mockSetUserRole).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("allows superAdmin to assign roles across gyms", async () => {
|
||||||
|
mockAuth.mockResolvedValue({ userId: "super_1" });
|
||||||
|
mockEnsureUserSynced.mockResolvedValue({
|
||||||
|
id: "super_1",
|
||||||
|
role: "superAdmin",
|
||||||
|
gymId: null,
|
||||||
|
});
|
||||||
|
mockDb.getUserById.mockResolvedValue({
|
||||||
|
id: "user_2",
|
||||||
|
role: "client",
|
||||||
|
gymId: "gym_b",
|
||||||
|
});
|
||||||
|
mockSetUserRole.mockResolvedValue({
|
||||||
|
id: "user_2",
|
||||||
|
emailAddresses: [{ emailAddress: "user2@example.com" }],
|
||||||
|
firstName: "User",
|
||||||
|
lastName: "Two",
|
||||||
|
publicMetadata: { role: "admin" },
|
||||||
|
});
|
||||||
|
|
||||||
|
const request = new NextRequest("http://localhost/api/admin/set-role", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
targetUserId: "user_2",
|
||||||
|
role: "admin",
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await POST(request);
|
||||||
|
const payload = await response.json();
|
||||||
|
|
||||||
|
expect(response.status).toBe(200);
|
||||||
|
expect(payload.success).toBe(true);
|
||||||
|
expect(mockSetUserRole).toHaveBeenCalledWith("user_2", "admin");
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -1,6 +1,9 @@
|
|||||||
import { auth } from '@clerk/nextjs/server';
|
import { auth } from "@clerk/nextjs/server";
|
||||||
import { NextResponse } from 'next/server';
|
import { NextResponse } from "next/server";
|
||||||
import { setUserRole, isAdmin, type UserRole } from '@/lib/clerk-helpers';
|
import { USER_ROLES, type UserRole } from "@fitai/shared";
|
||||||
|
import { setUserRole } from "@/lib/clerk-helpers";
|
||||||
|
import { getDatabase } from "@/lib/database";
|
||||||
|
import { ensureUserSynced } from "@/lib/sync-user";
|
||||||
|
|
||||||
export async function POST(req: Request) {
|
export async function POST(req: Request) {
|
||||||
try {
|
try {
|
||||||
@ -8,16 +11,27 @@ export async function POST(req: Request) {
|
|||||||
const { userId } = await auth();
|
const { userId } = await auth();
|
||||||
|
|
||||||
if (!userId) {
|
if (!userId) {
|
||||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const db = await getDatabase();
|
||||||
|
const currentUser = await ensureUserSynced(userId, db);
|
||||||
|
|
||||||
|
if (!currentUser) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Forbidden: user not found" },
|
||||||
|
{ status: 403 },
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the requesting user is an admin
|
// Check if the requesting user is an admin
|
||||||
const requestingUserIsAdmin = await isAdmin(userId);
|
const requestingUserIsAdmin =
|
||||||
|
currentUser.role === "admin" || currentUser.role === "superAdmin";
|
||||||
|
|
||||||
if (!requestingUserIsAdmin) {
|
if (!requestingUserIsAdmin) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ error: 'Forbidden: Admin access required' },
|
{ error: "Forbidden: Admin access required" },
|
||||||
{ status: 403 }
|
{ status: 403 },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,25 +40,57 @@ export async function POST(req: Request) {
|
|||||||
const { targetUserId, role } = body;
|
const { targetUserId, role } = body;
|
||||||
|
|
||||||
// Validate inputs
|
// Validate inputs
|
||||||
if (!targetUserId || typeof targetUserId !== 'string') {
|
if (!targetUserId || typeof targetUserId !== "string") {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ error: 'Invalid or missing targetUserId' },
|
{ error: "Invalid or missing targetUserId" },
|
||||||
{ status: 400 }
|
{ status: 400 },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!role || !['admin', 'trainer', 'client'].includes(role)) {
|
if (!role || !USER_ROLES.includes(role as UserRole)) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ error: 'Invalid role. Must be admin, trainer, or client' },
|
{
|
||||||
{ status: 400 }
|
error: `Invalid role. Must be one of: ${USER_ROLES.join(", ")}`,
|
||||||
|
},
|
||||||
|
{ status: 400 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const allowedRolesByRequester: Record<UserRole, UserRole[]> = {
|
||||||
|
superAdmin: ["superAdmin", "admin", "trainer", "client"],
|
||||||
|
admin: ["admin", "trainer", "client"],
|
||||||
|
trainer: [],
|
||||||
|
client: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const allowedTargetRoles = allowedRolesByRequester[currentUser.role];
|
||||||
|
if (!allowedTargetRoles.includes(role as UserRole)) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: `Forbidden: cannot assign role '${role}'` },
|
||||||
|
{ status: 403 },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prevent admin from changing their own role
|
// Prevent admin from changing their own role
|
||||||
if (userId === targetUserId) {
|
if (userId === targetUserId) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ error: 'Cannot change your own role' },
|
{ error: "Cannot change your own role" },
|
||||||
{ status: 400 }
|
{ status: 400 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const targetUser = await db.getUserById(targetUserId);
|
||||||
|
if (!targetUser) {
|
||||||
|
return NextResponse.json({ error: "User not found" }, { status: 404 });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
currentUser.role !== "superAdmin" &&
|
||||||
|
(!currentUser.gymId || targetUser.gymId !== currentUser.gymId)
|
||||||
|
) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Cannot change roles for users from other gyms" },
|
||||||
|
{ status: 403 },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,15 +109,15 @@ export async function POST(req: Request) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error setting user role:', error);
|
console.error("Error setting user role:", error);
|
||||||
|
|
||||||
if (error instanceof Error && error.message.includes('not found')) {
|
if (error instanceof Error && error.message.includes("not found")) {
|
||||||
return NextResponse.json({ error: 'User not found' }, { status: 404 });
|
return NextResponse.json({ error: "User not found" }, { status: 404 });
|
||||||
}
|
}
|
||||||
|
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ error: 'Internal server error' },
|
{ error: "Internal server error" },
|
||||||
{ status: 500 }
|
{ status: 500 },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,20 +3,26 @@ import { NextResponse } from "next/server";
|
|||||||
import { getDatabase } from "@/lib/database";
|
import { getDatabase } from "@/lib/database";
|
||||||
import { ensureUserSynced } from "@/lib/sync-user";
|
import { ensureUserSynced } from "@/lib/sync-user";
|
||||||
import { successResponse } from "@/lib/api/responses";
|
import { successResponse } from "@/lib/api/responses";
|
||||||
|
import log from "@/lib/logger";
|
||||||
|
|
||||||
export async function GET(req: Request) {
|
export async function GET(req: Request) {
|
||||||
try {
|
try {
|
||||||
const { userId } = await auth();
|
const { userId } = await auth();
|
||||||
if (!userId) return new NextResponse("Unauthorized", { status: 401 });
|
if (!userId) {
|
||||||
|
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
const db = await getDatabase();
|
const db = await getDatabase();
|
||||||
const user = await ensureUserSynced(userId, db);
|
const user = await ensureUserSynced(userId, db);
|
||||||
|
|
||||||
if (!user || (user.role !== "admin" && user.role !== "superAdmin")) {
|
if (!user || (user.role !== "admin" && user.role !== "superAdmin")) {
|
||||||
return new NextResponse("Forbidden", { status: 403 });
|
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
|
||||||
}
|
}
|
||||||
if (user.role === "admin" && !user.gymId) {
|
if (user.role === "admin" && !user.gymId) {
|
||||||
return new NextResponse("Admin gymId not set", { status: 400 });
|
return NextResponse.json(
|
||||||
|
{ error: "Admin gymId not set" },
|
||||||
|
{ status: 400 },
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = new URL(req.url);
|
const url = new URL(req.url);
|
||||||
@ -54,7 +60,10 @@ export async function GET(req: Request) {
|
|||||||
|
|
||||||
return successResponse({ stats });
|
return successResponse({ stats });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Dashboard stats error:", error);
|
log.error("Dashboard stats error", error);
|
||||||
return new NextResponse("Internal Server Error", { status: 500 });
|
return NextResponse.json(
|
||||||
|
{ error: "Internal server error" },
|
||||||
|
{ status: 500 },
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,46 @@
|
|||||||
/**
|
/**
|
||||||
* @jest-environment node
|
* @jest-environment node
|
||||||
*/
|
*/
|
||||||
import { POST as checkIn } from '../check-in/route'
|
import { POST as checkIn } from "../check-in/route";
|
||||||
import { POST as checkOut } from '../check-out/route'
|
import { POST as checkOut } from "../check-out/route";
|
||||||
import { GET as history } from '../history/route'
|
import { GET as history } from "../history/route";
|
||||||
import { NextRequest } from 'next/server'
|
import { NextRequest } from "next/server";
|
||||||
|
|
||||||
// Mock dependencies
|
// Mock dependencies
|
||||||
jest.mock('@clerk/nextjs/server', () => ({
|
jest.mock("@clerk/nextjs/server", () => ({
|
||||||
auth: jest.fn(() => Promise.resolve({ userId: 'test_user_id' })),
|
auth: jest.fn(() => Promise.resolve({ userId: "test_user_id" })),
|
||||||
currentUser: jest.fn(() => Promise.resolve({ id: 'test_user_id', emailAddresses: [{ emailAddress: 'test@example.com' }] }))
|
currentUser: jest.fn(() =>
|
||||||
}))
|
Promise.resolve({
|
||||||
|
id: "test_user_id",
|
||||||
|
emailAddresses: [{ emailAddress: "test@example.com" }],
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
}));
|
||||||
|
|
||||||
jest.mock('@/lib/sync-user', () => ({
|
jest.mock("@/lib/sync-user", () => ({
|
||||||
ensureUserSynced: jest.fn()
|
ensureUserSynced: jest.fn(),
|
||||||
}))
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/lib/geofence", () => ({
|
||||||
|
getUserGymGeofence: jest.fn(() =>
|
||||||
|
Promise.resolve({
|
||||||
|
id: "gym_1",
|
||||||
|
name: "Test Gym",
|
||||||
|
latitude: 1,
|
||||||
|
longitude: 1,
|
||||||
|
geofenceRadiusMeters: 30,
|
||||||
|
geofenceEnabled: true,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
parseUserLocation: jest.fn(() => ({
|
||||||
|
latitude: 1,
|
||||||
|
longitude: 1,
|
||||||
|
accuracy: 10,
|
||||||
|
})),
|
||||||
|
validateGeofence: jest.fn(() => ({ ok: true })),
|
||||||
|
validateGeofenceWithFallback: jest.fn(() => ({ ok: true })),
|
||||||
|
validateCheckInGeofence: jest.fn(() => ({ ok: true })),
|
||||||
|
}));
|
||||||
|
|
||||||
const mockDb = {
|
const mockDb = {
|
||||||
checkIn: jest.fn(),
|
checkIn: jest.fn(),
|
||||||
@ -27,111 +53,128 @@ const mockDb = {
|
|||||||
createClient: jest.fn(),
|
createClient: jest.fn(),
|
||||||
getFitnessProfileByUserId: jest.fn(),
|
getFitnessProfileByUserId: jest.fn(),
|
||||||
createFitnessProfile: jest.fn(),
|
createFitnessProfile: jest.fn(),
|
||||||
}
|
};
|
||||||
|
|
||||||
jest.mock('@/lib/database', () => ({
|
jest.mock("@/lib/database", () => ({
|
||||||
getDatabase: jest.fn(() => Promise.resolve(mockDb))
|
getDatabase: jest.fn(() => Promise.resolve(mockDb)),
|
||||||
}))
|
}));
|
||||||
|
|
||||||
describe('Attendance API', () => {
|
describe("Attendance API", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks()
|
jest.clearAllMocks();
|
||||||
})
|
});
|
||||||
|
|
||||||
describe('POST /api/attendance/check-in', () => {
|
describe("POST /api/attendance/check-in", () => {
|
||||||
it('should successfully check in', async () => {
|
it("should successfully check in", async () => {
|
||||||
mockDb.getUserById.mockResolvedValue({ id: 'test_user_id' })
|
mockDb.getUserById.mockResolvedValue({ id: "test_user_id" });
|
||||||
mockDb.getActiveCheckIn.mockResolvedValue(null)
|
mockDb.getActiveCheckIn.mockResolvedValue(null);
|
||||||
mockDb.checkIn.mockResolvedValue({
|
mockDb.checkIn.mockResolvedValue({
|
||||||
id: 'attendance_id',
|
id: "attendance_id",
|
||||||
userId: 'test_user_id',
|
userId: "test_user_id",
|
||||||
checkInTime: new Date(),
|
checkInTime: new Date(),
|
||||||
type: 'gym'
|
type: "gym",
|
||||||
})
|
});
|
||||||
|
|
||||||
const req = new NextRequest('http://localhost/api/attendance/check-in', {
|
const req = new NextRequest("http://localhost/api/attendance/check-in", {
|
||||||
method: 'POST',
|
method: "POST",
|
||||||
body: JSON.stringify({ type: 'gym', notes: 'Test check-in' })
|
body: JSON.stringify({
|
||||||
})
|
type: "gym",
|
||||||
|
notes: "Test check-in",
|
||||||
|
location: { latitude: 1, longitude: 1, accuracy: 10 },
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
const res = await checkIn(req)
|
const res = await checkIn(req);
|
||||||
const data = await res.json()
|
const data = await res.json();
|
||||||
|
|
||||||
expect(res.status).toBe(200)
|
expect(res.status).toBe(200);
|
||||||
expect(data.id).toBe('attendance_id')
|
expect(data.id).toBe("attendance_id");
|
||||||
expect(data.userId).toBe('test_user_id')
|
expect(data.userId).toBe("test_user_id");
|
||||||
expect(mockDb.checkIn).toHaveBeenCalledWith('test_user_id', 'gym', 'Test check-in')
|
expect(mockDb.checkIn).toHaveBeenCalledWith(
|
||||||
})
|
"test_user_id",
|
||||||
|
"gym",
|
||||||
|
"Test check-in",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('should fail if already checked in', async () => {
|
it("should fail if already checked in", async () => {
|
||||||
mockDb.getUserById.mockResolvedValue({ id: 'test_user_id' })
|
mockDb.getUserById.mockResolvedValue({ id: "test_user_id" });
|
||||||
mockDb.getActiveCheckIn.mockResolvedValue({ id: 'existing_id' })
|
mockDb.getActiveCheckIn.mockResolvedValue({ id: "existing_id" });
|
||||||
|
|
||||||
const req = new NextRequest('http://localhost/api/attendance/check-in', {
|
const req = new NextRequest("http://localhost/api/attendance/check-in", {
|
||||||
method: 'POST',
|
method: "POST",
|
||||||
body: JSON.stringify({ type: 'gym' })
|
body: JSON.stringify({
|
||||||
})
|
type: "gym",
|
||||||
|
location: { latitude: 1, longitude: 1, accuracy: 10 },
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
const res = await checkIn(req)
|
const res = await checkIn(req);
|
||||||
const text = await res.text()
|
const text = await res.text();
|
||||||
|
|
||||||
expect(res.status).toBe(400)
|
expect(res.status).toBe(400);
|
||||||
expect(text).toBe('Already checked in')
|
expect(text).toBe("Already checked in");
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
describe('POST /api/attendance/check-out', () => {
|
describe("POST /api/attendance/check-out", () => {
|
||||||
it('should successfully check out', async () => {
|
it("should successfully check out", async () => {
|
||||||
mockDb.getActiveCheckIn.mockResolvedValue({ id: 'attendance_id' })
|
mockDb.getActiveCheckIn.mockResolvedValue({ id: "attendance_id" });
|
||||||
mockDb.checkOut.mockResolvedValue({
|
mockDb.checkOut.mockResolvedValue({
|
||||||
id: 'attendance_id',
|
id: "attendance_id",
|
||||||
checkOutTime: new Date()
|
checkOutTime: new Date(),
|
||||||
})
|
});
|
||||||
|
|
||||||
const req = new NextRequest('http://localhost/api/attendance/check-out', {
|
const req = new NextRequest("http://localhost/api/attendance/check-out", {
|
||||||
method: 'POST'
|
method: "POST",
|
||||||
})
|
body: JSON.stringify({
|
||||||
|
location: { latitude: 1, longitude: 1, accuracy: 10 },
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
const res = await checkOut(req)
|
const res = await checkOut(req);
|
||||||
const data = await res.json()
|
const data = await res.json();
|
||||||
|
|
||||||
expect(res.status).toBe(200)
|
expect(res.status).toBe(200);
|
||||||
expect(data.id).toBe('attendance_id')
|
expect(data.id).toBe("attendance_id");
|
||||||
expect(data.checkOutTime).toBeDefined()
|
expect(data.checkOutTime).toBeDefined();
|
||||||
expect(mockDb.checkOut).toHaveBeenCalledWith('attendance_id')
|
expect(mockDb.checkOut).toHaveBeenCalledWith("attendance_id");
|
||||||
})
|
});
|
||||||
|
|
||||||
it('should fail if not checked in', async () => {
|
it("should fail if not checked in", async () => {
|
||||||
mockDb.getActiveCheckIn.mockResolvedValue(null)
|
mockDb.getActiveCheckIn.mockResolvedValue(null);
|
||||||
|
|
||||||
const req = new NextRequest('http://localhost/api/attendance/check-out', {
|
const req = new NextRequest("http://localhost/api/attendance/check-out", {
|
||||||
method: 'POST'
|
method: "POST",
|
||||||
})
|
body: JSON.stringify({
|
||||||
|
location: { latitude: 1, longitude: 1, accuracy: 10 },
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
const res = await checkOut(req)
|
const res = await checkOut(req);
|
||||||
const text = await res.text()
|
const text = await res.text();
|
||||||
|
|
||||||
expect(res.status).toBe(404)
|
expect(res.status).toBe(404);
|
||||||
expect(text).toBe('No active check-in found')
|
expect(text).toBe("No active check-in found");
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
describe('GET /api/attendance/history', () => {
|
describe("GET /api/attendance/history", () => {
|
||||||
it('should return attendance history', async () => {
|
it("should return attendance history", async () => {
|
||||||
const historyData = [
|
const historyData = [
|
||||||
{ id: '1', checkInTime: new Date() },
|
{ id: "1", checkInTime: new Date() },
|
||||||
{ id: '2', checkInTime: new Date() }
|
{ id: "2", checkInTime: new Date() },
|
||||||
]
|
];
|
||||||
mockDb.getUserById.mockResolvedValue({ id: 'test_user_id' })
|
mockDb.getUserById.mockResolvedValue({ id: "test_user_id" });
|
||||||
mockDb.getAttendanceHistory.mockResolvedValue(historyData)
|
mockDb.getAttendanceHistory.mockResolvedValue(historyData);
|
||||||
|
|
||||||
const req = new NextRequest('http://localhost/api/attendance/history')
|
const req = new NextRequest("http://localhost/api/attendance/history");
|
||||||
const res = await history(req)
|
const res = await history(req);
|
||||||
const data = await res.json()
|
const data = await res.json();
|
||||||
|
|
||||||
expect(res.status).toBe(200)
|
expect(res.status).toBe(200);
|
||||||
expect(data).toEqual(JSON.parse(JSON.stringify(historyData))) // Handle date serialization
|
expect(data).toEqual(JSON.parse(JSON.stringify(historyData))); // Handle date serialization
|
||||||
expect(mockDb.getAttendanceHistory).toHaveBeenCalledWith('test_user_id')
|
expect(mockDb.getAttendanceHistory).toHaveBeenCalledWith("test_user_id");
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|||||||
@ -2,12 +2,12 @@ import { auth } from "@clerk/nextjs/server";
|
|||||||
import { NextRequest, NextResponse } from "next/server";
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
import { getDatabase } from "@/lib/database";
|
import { getDatabase } from "@/lib/database";
|
||||||
import { ensureUserSynced } from "@/lib/sync-user";
|
import { ensureUserSynced } from "@/lib/sync-user";
|
||||||
import log from "@/lib/logger";
|
|
||||||
import { checkInSchema } from "@/lib/validation/schemas";
|
|
||||||
import {
|
import {
|
||||||
validateRequestBody,
|
getUserGymGeofence,
|
||||||
validationErrorResponse,
|
parseUserLocation,
|
||||||
} from "@/lib/validation/helpers";
|
validateCheckInGeofence,
|
||||||
|
} from "@/lib/geofence";
|
||||||
|
import log from "@/lib/logger";
|
||||||
|
|
||||||
export async function POST(req: NextRequest) {
|
export async function POST(req: NextRequest) {
|
||||||
try {
|
try {
|
||||||
@ -25,8 +25,26 @@ export async function POST(req: NextRequest) {
|
|||||||
return new NextResponse("Already checked in", { status: 400 });
|
return new NextResponse("Already checked in", { status: 400 });
|
||||||
}
|
}
|
||||||
|
|
||||||
const body = await req.json();
|
const body = await req.json().catch(() => ({}));
|
||||||
const { type = "gym", notes } = body;
|
const { type = "gym", notes } = body;
|
||||||
|
const fallbackRequested = Boolean(body.fallbackRequested);
|
||||||
|
|
||||||
|
const gym = await getUserGymGeofence(userId);
|
||||||
|
if (!gym) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "No gym assigned for this user" },
|
||||||
|
{ status: 400 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const location = parseUserLocation(body.location);
|
||||||
|
const geofence = validateCheckInGeofence(gym, location, fallbackRequested);
|
||||||
|
if (!geofence.ok) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: geofence.error },
|
||||||
|
{ status: geofence.status },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const attendance = await db.checkIn(userId, type, notes);
|
const attendance = await db.checkIn(userId, type, notes);
|
||||||
return NextResponse.json(attendance);
|
return NextResponse.json(attendance);
|
||||||
|
|||||||
@ -1,6 +1,11 @@
|
|||||||
import { auth } from "@clerk/nextjs/server";
|
import { auth } from "@clerk/nextjs/server";
|
||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
import { getDatabase } from "@/lib/database";
|
import { getDatabase } from "@/lib/database";
|
||||||
|
import {
|
||||||
|
getUserGymGeofence,
|
||||||
|
parseUserLocation,
|
||||||
|
validateGeofenceWithFallback,
|
||||||
|
} from "@/lib/geofence";
|
||||||
import log from "@/lib/logger";
|
import log from "@/lib/logger";
|
||||||
|
|
||||||
export async function POST(req: Request) {
|
export async function POST(req: Request) {
|
||||||
@ -15,6 +20,30 @@ export async function POST(req: Request) {
|
|||||||
return new NextResponse("No active check-in found", { status: 404 });
|
return new NextResponse("No active check-in found", { status: 404 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const body = await req.json().catch(() => ({}));
|
||||||
|
const fallbackRequested = Boolean(body.fallbackRequested);
|
||||||
|
|
||||||
|
const gym = await getUserGymGeofence(userId);
|
||||||
|
if (!gym) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "No gym assigned for this user" },
|
||||||
|
{ status: 400 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const location = parseUserLocation(body.location);
|
||||||
|
const geofence = validateGeofenceWithFallback(
|
||||||
|
gym,
|
||||||
|
location,
|
||||||
|
fallbackRequested,
|
||||||
|
);
|
||||||
|
if (!geofence.ok) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: geofence.error },
|
||||||
|
{ status: geofence.status },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const attendance = await db.checkOut(activeCheckIn.id);
|
const attendance = await db.checkOut(activeCheckIn.id);
|
||||||
return NextResponse.json(attendance);
|
return NextResponse.json(attendance);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { NextRequest, NextResponse } from "next/server";
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
import bcrypt from "bcryptjs";
|
import bcrypt from "bcryptjs";
|
||||||
|
import { auth } from "@clerk/nextjs/server";
|
||||||
import { getDatabase } from "../../../../lib/database/index";
|
import { getDatabase } from "../../../../lib/database/index";
|
||||||
import log from "@/lib/logger";
|
import log from "@/lib/logger";
|
||||||
import { userSchema } from "@/lib/validation/schemas";
|
import { userSchema } from "@/lib/validation/schemas";
|
||||||
@ -7,6 +8,8 @@ import {
|
|||||||
validateRequestBody,
|
validateRequestBody,
|
||||||
validationErrorResponse,
|
validationErrorResponse,
|
||||||
} from "@/lib/validation/helpers";
|
} from "@/lib/validation/helpers";
|
||||||
|
import { ensureUserSynced } from "@/lib/sync-user";
|
||||||
|
import { getUsersByGym } from "@/lib/gym-context";
|
||||||
|
|
||||||
export async function POST(request: NextRequest) {
|
export async function POST(request: NextRequest) {
|
||||||
try {
|
try {
|
||||||
@ -68,8 +71,31 @@ export async function POST(request: NextRequest) {
|
|||||||
|
|
||||||
export async function GET() {
|
export async function GET() {
|
||||||
try {
|
try {
|
||||||
|
const { userId: clerkUserId } = await auth();
|
||||||
|
if (!clerkUserId) {
|
||||||
|
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
const db = await getDatabase();
|
const db = await getDatabase();
|
||||||
const allUsers = await db.getAllUsers();
|
const currentUser = await ensureUserSynced(clerkUserId, db);
|
||||||
|
|
||||||
|
if (!currentUser) {
|
||||||
|
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const canViewUsers =
|
||||||
|
currentUser.role === "superAdmin" || currentUser.role === "admin";
|
||||||
|
if (!canViewUsers) {
|
||||||
|
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const allUsers =
|
||||||
|
currentUser.role === "superAdmin"
|
||||||
|
? await db.getAllUsers()
|
||||||
|
: currentUser.gymId
|
||||||
|
? await getUsersByGym(currentUser.gymId)
|
||||||
|
: [];
|
||||||
|
|
||||||
const usersWithoutPassword = allUsers.map(
|
const usersWithoutPassword = allUsers.map(
|
||||||
({ password: _, ...user }) => user,
|
({ password: _, ...user }) => user,
|
||||||
);
|
);
|
||||||
|
|||||||
156
apps/admin/src/app/api/food/barcode/[code]/route.ts
Normal file
156
apps/admin/src/app/api/food/barcode/[code]/route.ts
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import { auth } from "@clerk/nextjs/server";
|
||||||
|
import { getUserMembershipContext } from "@/lib/membership/access";
|
||||||
|
import log from "@/lib/logger";
|
||||||
|
|
||||||
|
interface OpenFoodFactsProduct {
|
||||||
|
product_name?: string;
|
||||||
|
product_name_en?: string;
|
||||||
|
brands?: string;
|
||||||
|
image_url?: string;
|
||||||
|
image_front_url?: string;
|
||||||
|
serving_size?: string;
|
||||||
|
nutriments?: {
|
||||||
|
[key: string]: number | string | undefined;
|
||||||
|
"energy-kcal_serving"?: number;
|
||||||
|
"energy-kcal_100g"?: number;
|
||||||
|
proteins_serving?: number;
|
||||||
|
proteins_100g?: number;
|
||||||
|
carbohydrates_serving?: number;
|
||||||
|
carbohydrates_100g?: number;
|
||||||
|
fat_serving?: number;
|
||||||
|
fat_100g?: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface OpenFoodFactsResponse {
|
||||||
|
status: number;
|
||||||
|
code: string;
|
||||||
|
product?: OpenFoodFactsProduct;
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeBarcode(rawCode: string): string {
|
||||||
|
return rawCode.replace(/\D/g, "").trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
function isSupportedBarcode(code: string): boolean {
|
||||||
|
return [8, 12, 13].includes(code.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNumber(value: unknown): number | undefined {
|
||||||
|
if (typeof value === "number" && Number.isFinite(value)) return value;
|
||||||
|
if (typeof value === "string") {
|
||||||
|
const parsed = Number(value);
|
||||||
|
if (Number.isFinite(parsed)) return parsed;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildProductPayload(code: string, product: OpenFoodFactsProduct) {
|
||||||
|
const caloriesPerServing =
|
||||||
|
getNumber(product.nutriments?.["energy-kcal_serving"]) ??
|
||||||
|
getNumber(product.nutriments?.["energy-kcal_100g"]) ??
|
||||||
|
0;
|
||||||
|
|
||||||
|
const protein =
|
||||||
|
getNumber(product.nutriments?.proteins_serving) ??
|
||||||
|
getNumber(product.nutriments?.proteins_100g);
|
||||||
|
const carbs =
|
||||||
|
getNumber(product.nutriments?.carbohydrates_serving) ??
|
||||||
|
getNumber(product.nutriments?.carbohydrates_100g);
|
||||||
|
const fat =
|
||||||
|
getNumber(product.nutriments?.fat_serving) ??
|
||||||
|
getNumber(product.nutriments?.fat_100g);
|
||||||
|
|
||||||
|
return {
|
||||||
|
barcode: code,
|
||||||
|
name: product.product_name || product.product_name_en || "Unknown Product",
|
||||||
|
brand: product.brands || null,
|
||||||
|
imageUrl: product.image_url || product.image_front_url || null,
|
||||||
|
servingSize: product.serving_size || "1 serving",
|
||||||
|
caloriesPerServing: Math.max(0, Math.round(caloriesPerServing)),
|
||||||
|
macros: {
|
||||||
|
protein: protein ?? null,
|
||||||
|
carbs: carbs ?? null,
|
||||||
|
fat: fat ?? null,
|
||||||
|
},
|
||||||
|
source: "openfoodfacts" as const,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function GET(
|
||||||
|
_request: Request,
|
||||||
|
{ params }: { params: Promise<{ code: string }> },
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const { userId } = await auth();
|
||||||
|
if (!userId) {
|
||||||
|
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const { features, membershipType } = await getUserMembershipContext(userId);
|
||||||
|
if (!features.nutritionTracking) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error:
|
||||||
|
"Barcode food scan is available on Premium and VIP memberships",
|
||||||
|
membershipType,
|
||||||
|
},
|
||||||
|
{ status: 403 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { code: rawCode } = await params;
|
||||||
|
const code = normalizeBarcode(rawCode);
|
||||||
|
|
||||||
|
if (!isSupportedBarcode(code)) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Invalid barcode. Use EAN-8, UPC-A, or EAN-13 formats." },
|
||||||
|
{ status: 400 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch(
|
||||||
|
`https://world.openfoodfacts.org/api/v2/product/${code}.json`,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"User-Agent": "FitAI/1.0 (fitai.app)",
|
||||||
|
},
|
||||||
|
cache: "no-store",
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
log.warn("OpenFoodFacts lookup failed", {
|
||||||
|
status: response.status,
|
||||||
|
barcode: code,
|
||||||
|
});
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Food lookup service unavailable. Please try again." },
|
||||||
|
{ status: 503 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const payload = (await response.json()) as OpenFoodFactsResponse;
|
||||||
|
if (payload.status !== 1 || !payload.product) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Product not found in OpenFoodFacts" },
|
||||||
|
{ status: 404 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
success: true,
|
||||||
|
data: buildProductPayload(code, payload.product),
|
||||||
|
meta: {
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
log.error("Failed barcode food lookup", error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Failed to lookup food barcode" },
|
||||||
|
{ status: 500 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,6 +3,7 @@ import { auth } from "@clerk/nextjs/server";
|
|||||||
import { eq, sql } from "@fitai/database";
|
import { eq, sql } from "@fitai/database";
|
||||||
import { db, users as usersTable, gyms as gymsTable } from "@fitai/database";
|
import { db, users as usersTable, gyms as gymsTable } from "@fitai/database";
|
||||||
import { ensureUserSynced } from "@/lib/sync-user";
|
import { ensureUserSynced } from "@/lib/sync-user";
|
||||||
|
import { getDatabase } from "@/lib/database";
|
||||||
import log from "@/lib/logger";
|
import log from "@/lib/logger";
|
||||||
|
|
||||||
async function ensureGymsTable() {
|
async function ensureGymsTable() {
|
||||||
@ -17,6 +18,178 @@ async function ensureGymsTable() {
|
|||||||
updated_at INTEGER NOT NULL
|
updated_at INTEGER NOT NULL
|
||||||
)
|
)
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
const columns = await db.all(sql`PRAGMA table_info('gyms')`);
|
||||||
|
const columnNames = new Set(
|
||||||
|
(columns as Array<{ name?: string }>)
|
||||||
|
.map((col) => col.name)
|
||||||
|
.filter(Boolean),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!columnNames.has("latitude")) {
|
||||||
|
await db.run(sql`ALTER TABLE gyms ADD COLUMN latitude REAL`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!columnNames.has("longitude")) {
|
||||||
|
await db.run(sql`ALTER TABLE gyms ADD COLUMN longitude REAL`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!columnNames.has("geofence_radius_meters")) {
|
||||||
|
await db.run(
|
||||||
|
sql`ALTER TABLE gyms ADD COLUMN geofence_radius_meters REAL NOT NULL DEFAULT 30`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!columnNames.has("geofence_enabled")) {
|
||||||
|
await db.run(
|
||||||
|
sql`ALTER TABLE gyms ADD COLUMN geofence_enabled INTEGER NOT NULL DEFAULT 1`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PATCH /api/gyms/[id]
|
||||||
|
// Update gym details and geofence configuration
|
||||||
|
export async function PATCH(
|
||||||
|
request: Request,
|
||||||
|
{ params }: { params: Promise<{ id: string }> },
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const { id: gymId } = await params;
|
||||||
|
const { userId } = await auth();
|
||||||
|
|
||||||
|
if (!userId) {
|
||||||
|
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const appDb = await getDatabase();
|
||||||
|
const currentUser = await ensureUserSynced(userId, appDb);
|
||||||
|
|
||||||
|
if (
|
||||||
|
!currentUser ||
|
||||||
|
(currentUser.role !== "superAdmin" && currentUser.role !== "admin")
|
||||||
|
) {
|
||||||
|
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
|
||||||
|
}
|
||||||
|
|
||||||
|
await ensureGymsTable();
|
||||||
|
|
||||||
|
const existingGym = await db
|
||||||
|
.select()
|
||||||
|
.from(gymsTable)
|
||||||
|
.where(eq(gymsTable.id, gymId))
|
||||||
|
.get();
|
||||||
|
|
||||||
|
if (!existingGym) {
|
||||||
|
return NextResponse.json({ error: "Gym not found" }, { status: 404 });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
currentUser.role === "admin" &&
|
||||||
|
currentUser.gymId &&
|
||||||
|
currentUser.gymId !== gymId
|
||||||
|
) {
|
||||||
|
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const body = await request.json().catch(() => null);
|
||||||
|
if (!body || typeof body !== "object") {
|
||||||
|
return NextResponse.json({ error: "Invalid body" }, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const latitude =
|
||||||
|
body.latitude === undefined || body.latitude === null
|
||||||
|
? null
|
||||||
|
: Number(body.latitude);
|
||||||
|
const longitude =
|
||||||
|
body.longitude === undefined || body.longitude === null
|
||||||
|
? null
|
||||||
|
: Number(body.longitude);
|
||||||
|
const geofenceRadiusMeters =
|
||||||
|
body.geofenceRadiusMeters === undefined ||
|
||||||
|
body.geofenceRadiusMeters === null
|
||||||
|
? 30
|
||||||
|
: Number(body.geofenceRadiusMeters);
|
||||||
|
const geofenceEnabled =
|
||||||
|
body.geofenceEnabled === undefined ? true : Boolean(body.geofenceEnabled);
|
||||||
|
|
||||||
|
if (
|
||||||
|
latitude !== null &&
|
||||||
|
(!Number.isFinite(latitude) || latitude < -90 || latitude > 90)
|
||||||
|
) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "latitude must be between -90 and 90" },
|
||||||
|
{ status: 400 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
longitude !== null &&
|
||||||
|
(!Number.isFinite(longitude) || longitude < -180 || longitude > 180)
|
||||||
|
) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "longitude must be between -180 and 180" },
|
||||||
|
{ status: 400 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Number.isFinite(geofenceRadiusMeters) || geofenceRadiusMeters <= 0) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "geofenceRadiusMeters must be a positive number" },
|
||||||
|
{ status: 400 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await db.run(sql`
|
||||||
|
UPDATE gyms
|
||||||
|
SET
|
||||||
|
latitude = ${latitude},
|
||||||
|
longitude = ${longitude},
|
||||||
|
geofence_radius_meters = ${geofenceRadiusMeters},
|
||||||
|
geofence_enabled = ${geofenceEnabled ? 1 : 0},
|
||||||
|
updated_at = ${Math.floor(Date.now() / 1000)}
|
||||||
|
WHERE id = ${gymId}
|
||||||
|
`);
|
||||||
|
|
||||||
|
const updatedRows = await db.all(sql`
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
location,
|
||||||
|
latitude,
|
||||||
|
longitude,
|
||||||
|
geofence_radius_meters as geofenceRadiusMeters,
|
||||||
|
geofence_enabled as geofenceEnabled,
|
||||||
|
status,
|
||||||
|
admin_user_id as adminUserId,
|
||||||
|
created_at as createdAt,
|
||||||
|
updated_at as updatedAt
|
||||||
|
FROM gyms
|
||||||
|
WHERE id = ${gymId}
|
||||||
|
LIMIT 1
|
||||||
|
`);
|
||||||
|
|
||||||
|
const updated = updatedRows?.[0]
|
||||||
|
? {
|
||||||
|
...updatedRows[0],
|
||||||
|
geofenceEnabled:
|
||||||
|
typeof (updatedRows[0] as { geofenceEnabled?: unknown })
|
||||||
|
.geofenceEnabled === "boolean"
|
||||||
|
? (updatedRows[0] as { geofenceEnabled: boolean }).geofenceEnabled
|
||||||
|
: Boolean(
|
||||||
|
(updatedRows[0] as { geofenceEnabled?: unknown })
|
||||||
|
.geofenceEnabled,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
: null;
|
||||||
|
|
||||||
|
return NextResponse.json(updated);
|
||||||
|
} catch (error) {
|
||||||
|
log.error("Failed to update gym", error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Internal Server Error" },
|
||||||
|
{ status: 500 },
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DELETE /api/gyms/[id]
|
// DELETE /api/gyms/[id]
|
||||||
@ -33,30 +206,8 @@ export async function DELETE(
|
|||||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure user is synced
|
const appDb = await getDatabase();
|
||||||
const currentUser = await ensureUserSynced(userId, {
|
const currentUser = await ensureUserSynced(userId, appDb);
|
||||||
getUserById: async (id: string) => {
|
|
||||||
const row = await db
|
|
||||||
.select()
|
|
||||||
.from(usersTable)
|
|
||||||
.where(eq(usersTable.id, id))
|
|
||||||
.get();
|
|
||||||
return row
|
|
||||||
? {
|
|
||||||
id: row.id,
|
|
||||||
email: row.email,
|
|
||||||
firstName: row.firstName,
|
|
||||||
lastName: row.lastName,
|
|
||||||
password: row.password ?? "",
|
|
||||||
phone: row.phone ?? undefined,
|
|
||||||
role: row.role,
|
|
||||||
imageUrl: undefined,
|
|
||||||
createdAt: new Date(row.createdAt),
|
|
||||||
updatedAt: new Date(row.updatedAt),
|
|
||||||
}
|
|
||||||
: null;
|
|
||||||
},
|
|
||||||
} as any);
|
|
||||||
|
|
||||||
// Only superAdmin can delete gyms
|
// Only superAdmin can delete gyms
|
||||||
if (!currentUser || currentUser.role !== "superAdmin") {
|
if (!currentUser || currentUser.role !== "superAdmin") {
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
|
import { auth } from "@clerk/nextjs/server";
|
||||||
import { eq, sql } from "@fitai/database";
|
import { eq, sql } from "@fitai/database";
|
||||||
import { db, gyms as gymsTable } from "@fitai/database";
|
import { db, gyms as gymsTable } from "@fitai/database";
|
||||||
import log from "@/lib/logger";
|
import log from "@/lib/logger";
|
||||||
|
import { getDatabase } from "@/lib/database";
|
||||||
|
import { ensureUserSynced } from "@/lib/sync-user";
|
||||||
|
|
||||||
async function ensureGymsTable() {
|
async function ensureGymsTable() {
|
||||||
await db.run(sql`
|
await db.run(sql`
|
||||||
@ -24,7 +27,33 @@ export async function GET(
|
|||||||
{ params }: { params: Promise<{ id: string }> },
|
{ params }: { params: Promise<{ id: string }> },
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
|
const { userId: clerkUserId } = await auth();
|
||||||
|
if (!clerkUserId) {
|
||||||
|
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const appDb = await getDatabase();
|
||||||
|
const currentUser = await ensureUserSynced(clerkUserId, appDb);
|
||||||
|
|
||||||
|
if (!currentUser) {
|
||||||
|
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
|
||||||
|
}
|
||||||
|
|
||||||
const { id: gymId } = await params;
|
const { id: gymId } = await params;
|
||||||
|
|
||||||
|
const canViewGymStats =
|
||||||
|
currentUser.role === "superAdmin" || currentUser.role === "admin";
|
||||||
|
if (!canViewGymStats) {
|
||||||
|
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentUser.role !== "superAdmin" && currentUser.gymId !== gymId) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Forbidden - Cannot access other gym's data" },
|
||||||
|
{ status: 403 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
await ensureGymsTable();
|
await ensureGymsTable();
|
||||||
|
|
||||||
// Get gym info using Drizzle ORM
|
// Get gym info using Drizzle ORM
|
||||||
|
|||||||
88
apps/admin/src/app/api/gyms/__tests__/route-authz.test.ts
Normal file
88
apps/admin/src/app/api/gyms/__tests__/route-authz.test.ts
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
/**
|
||||||
|
* @jest-environment node
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { GET } from "../route";
|
||||||
|
|
||||||
|
jest.mock("@clerk/nextjs/server", () => ({
|
||||||
|
auth: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/lib/database", () => ({
|
||||||
|
getDatabase: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/lib/sync-user", () => ({
|
||||||
|
ensureUserSynced: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@fitai/database", () => ({
|
||||||
|
eq: jest.fn(() => ({})),
|
||||||
|
sql: jest.fn((strings: TemplateStringsArray) => strings.join("")),
|
||||||
|
db: {
|
||||||
|
run: jest.fn(),
|
||||||
|
select: jest.fn(() => ({
|
||||||
|
from: jest.fn(() => ({
|
||||||
|
where: jest.fn(() => ({
|
||||||
|
orderBy: jest.fn(() => ({
|
||||||
|
all: jest.fn().mockResolvedValue([
|
||||||
|
{ id: "gym_a", status: "active", name: "Gym A" },
|
||||||
|
{ id: "gym_b", status: "active", name: "Gym B" },
|
||||||
|
]),
|
||||||
|
})),
|
||||||
|
})),
|
||||||
|
})),
|
||||||
|
})),
|
||||||
|
gyms: {
|
||||||
|
status: "active",
|
||||||
|
},
|
||||||
|
users: {},
|
||||||
|
},
|
||||||
|
gyms: {
|
||||||
|
status: "active",
|
||||||
|
},
|
||||||
|
users: {},
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("GET /api/gyms authz", () => {
|
||||||
|
const mockAuth = require("@clerk/nextjs/server").auth as jest.Mock;
|
||||||
|
const mockGetDatabase = require("@/lib/database").getDatabase as jest.Mock;
|
||||||
|
const mockEnsureUserSynced = require("@/lib/sync-user")
|
||||||
|
.ensureUserSynced as jest.Mock;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
mockGetDatabase.mockResolvedValue({});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns only own gym for admin", async () => {
|
||||||
|
mockAuth.mockResolvedValue({ userId: "admin_1" });
|
||||||
|
mockEnsureUserSynced.mockResolvedValue({
|
||||||
|
id: "admin_1",
|
||||||
|
role: "admin",
|
||||||
|
gymId: "gym_a",
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await GET();
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
expect(response.status).toBe(200);
|
||||||
|
expect(data).toHaveLength(1);
|
||||||
|
expect(data[0].id).toBe("gym_a");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns all gyms for superAdmin", async () => {
|
||||||
|
mockAuth.mockResolvedValue({ userId: "super_1" });
|
||||||
|
mockEnsureUserSynced.mockResolvedValue({
|
||||||
|
id: "super_1",
|
||||||
|
role: "superAdmin",
|
||||||
|
gymId: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await GET();
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
expect(response.status).toBe(200);
|
||||||
|
expect(data).toHaveLength(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -3,6 +3,7 @@ import { auth } from "@clerk/nextjs/server";
|
|||||||
import { eq, sql } from "@fitai/database";
|
import { eq, sql } from "@fitai/database";
|
||||||
import { db, users as usersTable, gyms as gymsTable } from "@fitai/database";
|
import { db, users as usersTable, gyms as gymsTable } from "@fitai/database";
|
||||||
import { ensureUserSynced } from "@/lib/sync-user";
|
import { ensureUserSynced } from "@/lib/sync-user";
|
||||||
|
import { getDatabase } from "@/lib/database";
|
||||||
import log from "@/lib/logger";
|
import log from "@/lib/logger";
|
||||||
|
|
||||||
async function ensureGymsTable() {
|
async function ensureGymsTable() {
|
||||||
@ -17,21 +18,102 @@ async function ensureGymsTable() {
|
|||||||
updated_at INTEGER NOT NULL
|
updated_at INTEGER NOT NULL
|
||||||
)
|
)
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
const columns = await db.all(sql`PRAGMA table_info('gyms')`);
|
||||||
|
const columnNames = new Set(
|
||||||
|
(columns as Array<{ name?: string }>)
|
||||||
|
.map((col) => col.name)
|
||||||
|
.filter(Boolean),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!columnNames.has("latitude")) {
|
||||||
|
await db.run(sql`ALTER TABLE gyms ADD COLUMN latitude REAL`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!columnNames.has("longitude")) {
|
||||||
|
await db.run(sql`ALTER TABLE gyms ADD COLUMN longitude REAL`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!columnNames.has("geofence_radius_meters")) {
|
||||||
|
await db.run(
|
||||||
|
sql`ALTER TABLE gyms ADD COLUMN geofence_radius_meters REAL NOT NULL DEFAULT 30`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!columnNames.has("geofence_enabled")) {
|
||||||
|
await db.run(
|
||||||
|
sql`ALTER TABLE gyms ADD COLUMN geofence_enabled INTEGER NOT NULL DEFAULT 1`,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET /api/gyms
|
// GET /api/gyms
|
||||||
// Lists active gyms for selection (grid)
|
// Lists active gyms for selection (grid)
|
||||||
export async function GET() {
|
export async function GET() {
|
||||||
try {
|
try {
|
||||||
await ensureGymsTable();
|
const { userId } = await auth();
|
||||||
const rows = await db
|
if (!userId) {
|
||||||
.select()
|
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||||
.from(gymsTable)
|
}
|
||||||
.where(eq(gymsTable.status, "active"))
|
|
||||||
.orderBy(sql`created_at DESC`)
|
|
||||||
.all();
|
|
||||||
|
|
||||||
return NextResponse.json(rows);
|
const appDb = await getDatabase();
|
||||||
|
const currentUser = await ensureUserSynced(userId, appDb);
|
||||||
|
|
||||||
|
if (!currentUser) {
|
||||||
|
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentUser.role !== "admin" && currentUser.role !== "superAdmin") {
|
||||||
|
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
|
||||||
|
}
|
||||||
|
|
||||||
|
await ensureGymsTable();
|
||||||
|
let rows = (await db.all(sql`
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
location,
|
||||||
|
latitude,
|
||||||
|
longitude,
|
||||||
|
geofence_radius_meters as geofenceRadiusMeters,
|
||||||
|
geofence_enabled as geofenceEnabled,
|
||||||
|
status,
|
||||||
|
admin_user_id as adminUserId,
|
||||||
|
created_at as createdAt,
|
||||||
|
updated_at as updatedAt
|
||||||
|
FROM gyms
|
||||||
|
WHERE status = 'active'
|
||||||
|
ORDER BY created_at DESC
|
||||||
|
`)) as Array<{
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
location: string | null;
|
||||||
|
latitude: number | null;
|
||||||
|
longitude: number | null;
|
||||||
|
geofenceRadiusMeters: number | null;
|
||||||
|
geofenceEnabled: number | boolean | null;
|
||||||
|
status: "active" | "inactive";
|
||||||
|
adminUserId: string;
|
||||||
|
createdAt: number;
|
||||||
|
updatedAt: number;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
if (currentUser.role !== "superAdmin") {
|
||||||
|
if (!currentUser.gymId) {
|
||||||
|
return NextResponse.json({ error: "No gym assigned" }, { status: 403 });
|
||||||
|
}
|
||||||
|
rows = rows.filter((row) => row.id === currentUser.gymId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
rows.map((row) => ({
|
||||||
|
...row,
|
||||||
|
geofenceEnabled:
|
||||||
|
typeof row.geofenceEnabled === "boolean"
|
||||||
|
? row.geofenceEnabled
|
||||||
|
: Boolean(row.geofenceEnabled),
|
||||||
|
})),
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error("Failed to get gyms", error);
|
log.error("Failed to get gyms", error);
|
||||||
return new NextResponse("Internal Server Error", { status: 500 });
|
return new NextResponse("Internal Server Error", { status: 500 });
|
||||||
@ -48,60 +130,8 @@ export async function POST(req: Request) {
|
|||||||
const { userId } = await auth();
|
const { userId } = await auth();
|
||||||
if (!userId) return new NextResponse("Unauthorized", { status: 401 });
|
if (!userId) return new NextResponse("Unauthorized", { status: 401 });
|
||||||
|
|
||||||
// Ensure our local DB has the user synced (role, etc.)
|
const appDb = await getDatabase();
|
||||||
const currentUser = await ensureUserSynced(userId, {
|
const currentUser = await ensureUserSynced(userId, appDb);
|
||||||
// minimal facade for ensureUserSynced to work: it expects an object implementing part of IDatabase
|
|
||||||
getUserById: async (id: string) => {
|
|
||||||
const row = await db
|
|
||||||
.select()
|
|
||||||
.from(usersTable)
|
|
||||||
.where(eq(usersTable.id, id))
|
|
||||||
.get();
|
|
||||||
return row
|
|
||||||
? {
|
|
||||||
id: row.id,
|
|
||||||
email: row.email,
|
|
||||||
firstName: row.firstName,
|
|
||||||
lastName: row.lastName,
|
|
||||||
password: row.password ?? "",
|
|
||||||
phone: row.phone ?? undefined,
|
|
||||||
role: row.role,
|
|
||||||
imageUrl: undefined,
|
|
||||||
createdAt: new Date(row.createdAt),
|
|
||||||
updatedAt: new Date(row.updatedAt),
|
|
||||||
}
|
|
||||||
: null;
|
|
||||||
},
|
|
||||||
updateUser: async (id: string, updates: any) => {
|
|
||||||
await db
|
|
||||||
.update(usersTable)
|
|
||||||
.set({
|
|
||||||
...updates,
|
|
||||||
updatedAt: new Date(),
|
|
||||||
})
|
|
||||||
.where(eq(usersTable.id, id))
|
|
||||||
.run();
|
|
||||||
const row = await db
|
|
||||||
.select()
|
|
||||||
.from(usersTable)
|
|
||||||
.where(eq(usersTable.id, id))
|
|
||||||
.get();
|
|
||||||
return row
|
|
||||||
? {
|
|
||||||
id: row.id,
|
|
||||||
email: row.email,
|
|
||||||
firstName: row.firstName,
|
|
||||||
lastName: row.lastName,
|
|
||||||
password: row.password ?? "",
|
|
||||||
phone: row.phone ?? undefined,
|
|
||||||
role: row.role,
|
|
||||||
imageUrl: undefined,
|
|
||||||
createdAt: new Date(row.createdAt),
|
|
||||||
updatedAt: new Date(row.updatedAt),
|
|
||||||
}
|
|
||||||
: null;
|
|
||||||
},
|
|
||||||
} as any);
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!currentUser ||
|
!currentUser ||
|
||||||
@ -117,6 +147,21 @@ export async function POST(req: Request) {
|
|||||||
|
|
||||||
const name = String(body.name ?? "").trim();
|
const name = String(body.name ?? "").trim();
|
||||||
const location = body.location ? String(body.location).trim() : null;
|
const location = body.location ? String(body.location).trim() : null;
|
||||||
|
const latitude =
|
||||||
|
body.latitude === undefined || body.latitude === null
|
||||||
|
? null
|
||||||
|
: Number(body.latitude);
|
||||||
|
const longitude =
|
||||||
|
body.longitude === undefined || body.longitude === null
|
||||||
|
? null
|
||||||
|
: Number(body.longitude);
|
||||||
|
const geofenceRadiusMeters =
|
||||||
|
body.geofenceRadiusMeters === undefined ||
|
||||||
|
body.geofenceRadiusMeters === null
|
||||||
|
? 30
|
||||||
|
: Number(body.geofenceRadiusMeters);
|
||||||
|
const geofenceEnabled =
|
||||||
|
body.geofenceEnabled === undefined ? true : Boolean(body.geofenceEnabled);
|
||||||
let adminUserId: string | null = body.adminUserId
|
let adminUserId: string | null = body.adminUserId
|
||||||
? String(body.adminUserId)
|
? String(body.adminUserId)
|
||||||
: null;
|
: null;
|
||||||
@ -125,6 +170,33 @@ export async function POST(req: Request) {
|
|||||||
return NextResponse.json({ error: "name is required" }, { status: 400 });
|
return NextResponse.json({ error: "name is required" }, { status: 400 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
latitude !== null &&
|
||||||
|
(!Number.isFinite(latitude) || latitude < -90 || latitude > 90)
|
||||||
|
) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "latitude must be between -90 and 90" },
|
||||||
|
{ status: 400 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
longitude !== null &&
|
||||||
|
(!Number.isFinite(longitude) || longitude < -180 || longitude > 180)
|
||||||
|
) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "longitude must be between -180 and 180" },
|
||||||
|
{ status: 400 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Number.isFinite(geofenceRadiusMeters) || geofenceRadiusMeters <= 0) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "geofenceRadiusMeters must be a positive number" },
|
||||||
|
{ status: 400 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Enforce admin ownership rules
|
// Enforce admin ownership rules
|
||||||
if (currentUser.role === "admin") {
|
if (currentUser.role === "admin") {
|
||||||
adminUserId = currentUser.id;
|
adminUserId = currentUser.id;
|
||||||
@ -152,15 +224,33 @@ export async function POST(req: Request) {
|
|||||||
const nowTs = new Date();
|
const nowTs = new Date();
|
||||||
|
|
||||||
// Use Drizzle's insert method instead of raw SQL
|
// Use Drizzle's insert method instead of raw SQL
|
||||||
await db.insert(gymsTable).values({
|
await db.run(sql`
|
||||||
|
INSERT INTO gyms (
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
location: location ?? null,
|
location,
|
||||||
status: "active",
|
latitude,
|
||||||
adminUserId: adminUserId!,
|
longitude,
|
||||||
createdAt: nowTs,
|
geofence_radius_meters,
|
||||||
updatedAt: nowTs,
|
geofence_enabled,
|
||||||
});
|
status,
|
||||||
|
admin_user_id,
|
||||||
|
created_at,
|
||||||
|
updated_at
|
||||||
|
) VALUES (
|
||||||
|
${id},
|
||||||
|
${name},
|
||||||
|
${location ?? null},
|
||||||
|
${latitude},
|
||||||
|
${longitude},
|
||||||
|
${geofenceRadiusMeters},
|
||||||
|
${geofenceEnabled ? 1 : 0},
|
||||||
|
${"active"},
|
||||||
|
${adminUserId!},
|
||||||
|
${Math.floor(nowTs.getTime() / 1000)},
|
||||||
|
${Math.floor(nowTs.getTime() / 1000)}
|
||||||
|
)
|
||||||
|
`);
|
||||||
|
|
||||||
// Assign the admin to this gym immediately after creation
|
// Assign the admin to this gym immediately after creation
|
||||||
await db
|
await db
|
||||||
@ -168,11 +258,36 @@ export async function POST(req: Request) {
|
|||||||
.set({ gymId: id, updatedAt: nowTs })
|
.set({ gymId: id, updatedAt: nowTs })
|
||||||
.where(eq(usersTable.id, adminUserId!));
|
.where(eq(usersTable.id, adminUserId!));
|
||||||
|
|
||||||
const created = await db
|
const rowsCreated = await db.all(sql`
|
||||||
.select()
|
SELECT
|
||||||
.from(gymsTable)
|
id,
|
||||||
.where(eq(gymsTable.id, id))
|
name,
|
||||||
.get();
|
location,
|
||||||
|
latitude,
|
||||||
|
longitude,
|
||||||
|
geofence_radius_meters as geofenceRadiusMeters,
|
||||||
|
geofence_enabled as geofenceEnabled,
|
||||||
|
status,
|
||||||
|
admin_user_id as adminUserId,
|
||||||
|
created_at as createdAt,
|
||||||
|
updated_at as updatedAt
|
||||||
|
FROM gyms
|
||||||
|
WHERE id = ${id}
|
||||||
|
LIMIT 1
|
||||||
|
`);
|
||||||
|
const createdRow = rowsCreated?.[0] ?? null;
|
||||||
|
const created = createdRow
|
||||||
|
? {
|
||||||
|
...createdRow,
|
||||||
|
geofenceEnabled:
|
||||||
|
typeof (createdRow as { geofenceEnabled?: unknown })
|
||||||
|
.geofenceEnabled === "boolean"
|
||||||
|
? (createdRow as { geofenceEnabled: boolean }).geofenceEnabled
|
||||||
|
: Boolean(
|
||||||
|
(createdRow as { geofenceEnabled?: unknown }).geofenceEnabled,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
: null;
|
||||||
return NextResponse.json(created, { status: 201 });
|
return NextResponse.json(created, { status: 201 });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error("Failed to create gym", error);
|
log.error("Failed to create gym", error);
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { NextRequest, NextResponse } from "next/server";
|
|||||||
import { getDatabase } from "@/lib/database";
|
import { getDatabase } from "@/lib/database";
|
||||||
import { ensureUserSynced } from "@/lib/sync-user";
|
import { ensureUserSynced } from "@/lib/sync-user";
|
||||||
import log from "@/lib/logger";
|
import log from "@/lib/logger";
|
||||||
|
import { getUserMembershipContext } from "@/lib/membership/access";
|
||||||
|
|
||||||
export async function POST(req: NextRequest) {
|
export async function POST(req: NextRequest) {
|
||||||
try {
|
try {
|
||||||
@ -11,6 +12,18 @@ export async function POST(req: NextRequest) {
|
|||||||
|
|
||||||
const db = await getDatabase();
|
const db = await getDatabase();
|
||||||
await ensureUserSynced(userId, db);
|
await ensureUserSynced(userId, db);
|
||||||
|
const { features, membershipType } = await getUserMembershipContext(userId);
|
||||||
|
|
||||||
|
if (!features.hydrationTracking) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error:
|
||||||
|
"Hydration tracking is available on Premium and VIP memberships",
|
||||||
|
membershipType,
|
||||||
|
},
|
||||||
|
{ status: 403 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const body = await req.json();
|
const body = await req.json();
|
||||||
const { date, entries, totalWater, waterGoal } = body;
|
const { date, entries, totalWater, waterGoal } = body;
|
||||||
@ -58,6 +71,18 @@ export async function GET(req: NextRequest) {
|
|||||||
|
|
||||||
const db = await getDatabase();
|
const db = await getDatabase();
|
||||||
await ensureUserSynced(userId, db);
|
await ensureUserSynced(userId, db);
|
||||||
|
const { features, membershipType } = await getUserMembershipContext(userId);
|
||||||
|
|
||||||
|
if (!features.hydrationTracking) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error:
|
||||||
|
"Hydration tracking is available on Premium and VIP memberships",
|
||||||
|
membershipType,
|
||||||
|
},
|
||||||
|
{ status: 403 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const url = new URL(req.url);
|
const url = new URL(req.url);
|
||||||
const date = url.searchParams.get("date");
|
const date = url.searchParams.get("date");
|
||||||
@ -100,6 +125,18 @@ export async function DELETE(req: NextRequest) {
|
|||||||
|
|
||||||
const db = await getDatabase();
|
const db = await getDatabase();
|
||||||
await ensureUserSynced(userId, db);
|
await ensureUserSynced(userId, db);
|
||||||
|
const { features, membershipType } = await getUserMembershipContext(userId);
|
||||||
|
|
||||||
|
if (!features.hydrationTracking) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error:
|
||||||
|
"Hydration tracking is available on Premium and VIP memberships",
|
||||||
|
membershipType,
|
||||||
|
},
|
||||||
|
{ status: 403 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const url = new URL(req.url);
|
const url = new URL(req.url);
|
||||||
const id = url.searchParams.get("id");
|
const id = url.searchParams.get("id");
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { NextRequest, NextResponse } from "next/server";
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
import { auth, clerkClient } from "@clerk/nextjs/server";
|
import { auth, clerkClient } from "@clerk/nextjs/server";
|
||||||
|
import { getAuthContext } from "@/lib/auth/context";
|
||||||
import log from "@/lib/logger";
|
import log from "@/lib/logger";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -18,6 +19,7 @@ export async function POST(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { id: invitationId } = await params;
|
const { id: invitationId } = await params;
|
||||||
|
const authContext = await getAuthContext();
|
||||||
|
|
||||||
// Fetch pending invitations to find the one being resent
|
// Fetch pending invitations to find the one being resent
|
||||||
const client = await clerkClient();
|
const client = await clerkClient();
|
||||||
@ -38,11 +40,23 @@ export async function POST(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const metadata = invitation.publicMetadata as any;
|
const metadata = invitation.publicMetadata as any;
|
||||||
|
const invitationGymId =
|
||||||
|
(metadata?.gymId as string | null | undefined) ?? null;
|
||||||
|
const createdBy = (metadata?.createdBy as string | undefined) ?? undefined;
|
||||||
|
|
||||||
|
const canManageByRole =
|
||||||
|
authContext.role === "superAdmin" ||
|
||||||
|
(authContext.role === "admin" &&
|
||||||
|
authContext.gymId !== null &&
|
||||||
|
invitationGymId === authContext.gymId);
|
||||||
|
|
||||||
// Check if current user created this invitation
|
// Check if current user created this invitation
|
||||||
if (metadata?.createdBy !== userId) {
|
if (createdBy !== userId && !canManageByRole) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ error: "Forbidden - You can only resend invitations you created" },
|
{
|
||||||
|
error:
|
||||||
|
"Forbidden - You can only resend invitations you created or manage within your scope",
|
||||||
|
},
|
||||||
{ status: 403 },
|
{ status: 403 },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { NextRequest, NextResponse } from "next/server";
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
import { auth, clerkClient } from "@clerk/nextjs/server";
|
import { auth, clerkClient } from "@clerk/nextjs/server";
|
||||||
|
import { getAuthContext } from "@/lib/auth/context";
|
||||||
import log from "@/lib/logger";
|
import log from "@/lib/logger";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -18,6 +19,7 @@ export async function DELETE(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { id: invitationId } = await params;
|
const { id: invitationId } = await params;
|
||||||
|
const authContext = await getAuthContext();
|
||||||
|
|
||||||
// Fetch pending invitations to find and verify the one being revoked
|
// Fetch pending invitations to find and verify the one being revoked
|
||||||
const client = await clerkClient();
|
const client = await clerkClient();
|
||||||
@ -38,11 +40,23 @@ export async function DELETE(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const metadata = invitation.publicMetadata as any;
|
const metadata = invitation.publicMetadata as any;
|
||||||
|
const invitationGymId =
|
||||||
|
(metadata?.gymId as string | null | undefined) ?? null;
|
||||||
|
const createdBy = (metadata?.createdBy as string | undefined) ?? undefined;
|
||||||
|
|
||||||
|
const canManageByRole =
|
||||||
|
authContext.role === "superAdmin" ||
|
||||||
|
(authContext.role === "admin" &&
|
||||||
|
authContext.gymId !== null &&
|
||||||
|
invitationGymId === authContext.gymId);
|
||||||
|
|
||||||
// Check if current user created this invitation
|
// Check if current user created this invitation
|
||||||
if (metadata?.createdBy !== userId) {
|
if (createdBy !== userId && !canManageByRole) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ error: "Forbidden - You can only cancel invitations you created" },
|
{
|
||||||
|
error:
|
||||||
|
"Forbidden - You can only cancel invitations you created or manage within your scope",
|
||||||
|
},
|
||||||
{ status: 403 },
|
{ status: 403 },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,92 @@
|
|||||||
|
/**
|
||||||
|
* @jest-environment node
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { NextRequest } from "next/server";
|
||||||
|
import { POST } from "../route";
|
||||||
|
|
||||||
|
jest.mock("@clerk/nextjs/server", () => ({
|
||||||
|
auth: jest.fn(),
|
||||||
|
clerkClient: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/lib/auth/context", () => ({
|
||||||
|
getAuthContext: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/lib/logger", () => ({
|
||||||
|
info: jest.fn(),
|
||||||
|
warn: jest.fn(),
|
||||||
|
error: jest.fn(),
|
||||||
|
debug: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("POST /api/invitations authz", () => {
|
||||||
|
const mockAuth = require("@clerk/nextjs/server").auth as jest.Mock;
|
||||||
|
const mockClerkClient = require("@clerk/nextjs/server")
|
||||||
|
.clerkClient as jest.Mock;
|
||||||
|
const mockGetAuthContext = require("@/lib/auth/context")
|
||||||
|
.getAuthContext as jest.Mock;
|
||||||
|
|
||||||
|
const createInvitation = jest.fn();
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
mockClerkClient.mockResolvedValue({
|
||||||
|
invitations: {
|
||||||
|
createInvitation,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("blocks admin from inviting into another gym", async () => {
|
||||||
|
mockAuth.mockResolvedValue({ userId: "admin_1" });
|
||||||
|
mockGetAuthContext.mockResolvedValue({
|
||||||
|
userId: "admin_1",
|
||||||
|
role: "admin",
|
||||||
|
gymId: "gym_a",
|
||||||
|
});
|
||||||
|
|
||||||
|
const request = new NextRequest("http://localhost/api/invitations", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
inviteeEmail: "test@example.com",
|
||||||
|
roleAssigned: "trainer",
|
||||||
|
gymId: "gym_b",
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await POST(request);
|
||||||
|
|
||||||
|
expect(response.status).toBe(403);
|
||||||
|
expect(createInvitation).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("allows superAdmin to invite with explicit gym", async () => {
|
||||||
|
mockAuth.mockResolvedValue({ userId: "super_1" });
|
||||||
|
mockGetAuthContext.mockResolvedValue({
|
||||||
|
userId: "super_1",
|
||||||
|
role: "superAdmin",
|
||||||
|
gymId: null,
|
||||||
|
});
|
||||||
|
createInvitation.mockResolvedValue({ id: "inv_1" });
|
||||||
|
|
||||||
|
const request = new NextRequest("http://localhost/api/invitations", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
inviteeEmail: "test@example.com",
|
||||||
|
roleAssigned: "admin",
|
||||||
|
gymId: "gym_b",
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await POST(request);
|
||||||
|
|
||||||
|
expect(response.status).toBe(201);
|
||||||
|
expect(createInvitation).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
emailAddress: "test@example.com",
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import { NextRequest, NextResponse } from "next/server";
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
import { auth, clerkClient } from "@clerk/nextjs/server";
|
import { auth, clerkClient } from "@clerk/nextjs/server";
|
||||||
import { getAuthContext } from "@/lib/auth/context";
|
import { getAuthContext } from "@/lib/auth/context";
|
||||||
import { validateGymAccess } from "@/lib/auth/permissions";
|
import { getInvitableRoles, validateGymAccess } from "@/lib/auth/permissions";
|
||||||
import log from "@/lib/logger";
|
import log from "@/lib/logger";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -132,91 +132,51 @@ export async function POST(req: Request) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch inviter user from Clerk
|
const authContext = await getAuthContext();
|
||||||
const client = await clerkClient();
|
const { role: inviterRole, gymId: inviterGymId } = authContext;
|
||||||
const inviter = await client.users.getUser(userId);
|
|
||||||
const inviterRole =
|
const allowedRoles = getInvitableRoles(inviterRole);
|
||||||
(inviter.publicMetadata?.role as
|
if (!allowedRoles.includes(roleAssigned)) {
|
||||||
| "superAdmin"
|
return NextResponse.json(
|
||||||
| "admin"
|
{ error: `Forbidden - Cannot invite role '${roleAssigned}'` },
|
||||||
| "trainer"
|
{ status: 403 },
|
||||||
| "client"
|
);
|
||||||
| "generalUser") ?? "client";
|
}
|
||||||
const inviterGymId =
|
|
||||||
(inviter.publicMetadata?.gymId as string | undefined) ?? undefined;
|
|
||||||
|
|
||||||
// Enforce role-based rules and resolve target gymId for the invitation
|
// Enforce role-based rules and resolve target gymId for the invitation
|
||||||
let gymIdForInvite: string | null = null;
|
let gymIdForInvite: string | null = null;
|
||||||
switch (inviterRole) {
|
if (inviterRole === "superAdmin") {
|
||||||
case "admin": {
|
|
||||||
if (roleAssigned !== "trainer" && roleAssigned !== "client") {
|
|
||||||
return NextResponse.json(
|
|
||||||
{ error: "Admin can only invite trainer or client" },
|
|
||||||
{ status: 403 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (!inviterGymId) {
|
|
||||||
return NextResponse.json(
|
|
||||||
{ error: "Inviter admin must be assigned to a gym" },
|
|
||||||
{ status: 400 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
gymIdForInvite = inviterGymId;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "trainer": {
|
|
||||||
if (roleAssigned !== "client") {
|
|
||||||
return NextResponse.json(
|
|
||||||
{ error: "Trainer can only invite client" },
|
|
||||||
{ status: 403 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (!inviterGymId) {
|
|
||||||
return NextResponse.json(
|
|
||||||
{ error: "Inviter trainer must be assigned to a gym" },
|
|
||||||
{ status: 400 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
gymIdForInvite = inviterGymId;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "superAdmin": {
|
|
||||||
if (
|
|
||||||
roleAssigned !== "admin" &&
|
|
||||||
roleAssigned !== "trainer" &&
|
|
||||||
roleAssigned !== "client"
|
|
||||||
) {
|
|
||||||
return NextResponse.json(
|
|
||||||
{ error: "Invalid roleAssigned for SuperAdmin" },
|
|
||||||
{ status: 400 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// Prefer explicitly provided gymId, otherwise fall back to inviter's gymId if present
|
|
||||||
gymIdForInvite = requestedGymId || inviterGymId || null;
|
gymIdForInvite = requestedGymId || inviterGymId || null;
|
||||||
if (!gymIdForInvite) {
|
if (!gymIdForInvite) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ error: "gymId is required for SuperAdmin when inviting" },
|
{ error: "gymId is required for superAdmin invitations" },
|
||||||
{ status: 400 },
|
{ status: 400 },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
} else {
|
||||||
}
|
if (!inviterGymId) {
|
||||||
default: {
|
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ error: "Inviter role not permitted to create invitations" },
|
{ error: "Inviter must be assigned to a gym" },
|
||||||
|
{ status: 400 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (requestedGymId && requestedGymId !== inviterGymId) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Cannot invite users into another gym" },
|
||||||
{ status: 403 },
|
{ status: 403 },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
gymIdForInvite = inviterGymId;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create Clerk invitation with metadata needed by webhook to assign role & gym
|
// Create Clerk invitation with metadata needed by webhook to assign role & gym
|
||||||
// reuse existing Clerk client instance
|
const client = await clerkClient();
|
||||||
const invitation = await client.invitations.createInvitation({
|
const invitation = await client.invitations.createInvitation({
|
||||||
emailAddress: inviteeEmail,
|
emailAddress: inviteeEmail,
|
||||||
publicMetadata: {
|
publicMetadata: {
|
||||||
role: roleAssigned,
|
role: roleAssigned,
|
||||||
gymId: gymIdForInvite,
|
gymId: gymIdForInvite,
|
||||||
createdBy: inviter.id,
|
createdBy: userId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
32
apps/admin/src/app/api/membership/features/route.ts
Normal file
32
apps/admin/src/app/api/membership/features/route.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import { auth } from "@clerk/nextjs/server";
|
||||||
|
import { MEMBERSHIP_FEATURES } from "@/lib/membership/features";
|
||||||
|
import { getUserMembershipContext } from "@/lib/membership/access";
|
||||||
|
|
||||||
|
export async function GET() {
|
||||||
|
try {
|
||||||
|
const { userId } = await auth();
|
||||||
|
if (!userId) {
|
||||||
|
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const { membershipType, features } = await getUserMembershipContext(userId);
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
success: true,
|
||||||
|
data: {
|
||||||
|
membershipType,
|
||||||
|
currentFeatures: features,
|
||||||
|
plans: MEMBERSHIP_FEATURES,
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Failed to load membership features" },
|
||||||
|
{ status: 500 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,87 @@
|
|||||||
|
/**
|
||||||
|
* @jest-environment node
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { NextRequest } from "next/server";
|
||||||
|
import { POST } from "../route";
|
||||||
|
|
||||||
|
jest.mock("@clerk/nextjs/server", () => ({
|
||||||
|
auth: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/lib/database", () => ({
|
||||||
|
getDatabase: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/lib/sync-user", () => ({
|
||||||
|
ensureUserSynced: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/lib/logger", () => ({
|
||||||
|
info: jest.fn(),
|
||||||
|
warn: jest.fn(),
|
||||||
|
error: jest.fn(),
|
||||||
|
debug: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("POST /api/notifications authz", () => {
|
||||||
|
const mockAuth = require("@clerk/nextjs/server").auth as jest.Mock;
|
||||||
|
const mockGetDatabase = require("@/lib/database").getDatabase as jest.Mock;
|
||||||
|
const mockEnsureUserSynced = require("@/lib/sync-user")
|
||||||
|
.ensureUserSynced as jest.Mock;
|
||||||
|
|
||||||
|
const mockDb = {
|
||||||
|
getUserById: jest.fn(),
|
||||||
|
createNotification: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
mockGetDatabase.mockResolvedValue(mockDb);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns 403 for non-staff user", async () => {
|
||||||
|
mockAuth.mockResolvedValue({ userId: "client_1" });
|
||||||
|
mockEnsureUserSynced.mockResolvedValue({
|
||||||
|
id: "client_1",
|
||||||
|
role: "client",
|
||||||
|
gymId: "gym_a",
|
||||||
|
});
|
||||||
|
|
||||||
|
const request = new NextRequest("http://localhost/api/notifications", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
targetUserId: "client_2",
|
||||||
|
title: "Hello",
|
||||||
|
message: "Test",
|
||||||
|
type: "system",
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await POST(request);
|
||||||
|
expect(response.status).toBe(403);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns 403 for cross-gym notify by admin", async () => {
|
||||||
|
mockAuth.mockResolvedValue({ userId: "admin_1" });
|
||||||
|
mockEnsureUserSynced.mockResolvedValue({
|
||||||
|
id: "admin_1",
|
||||||
|
role: "admin",
|
||||||
|
gymId: "gym_a",
|
||||||
|
});
|
||||||
|
mockDb.getUserById.mockResolvedValue({ id: "client_2", gymId: "gym_b" });
|
||||||
|
|
||||||
|
const request = new NextRequest("http://localhost/api/notifications", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
targetUserId: "client_2",
|
||||||
|
title: "Hello",
|
||||||
|
message: "Test",
|
||||||
|
type: "system",
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await POST(request);
|
||||||
|
expect(response.status).toBe(403);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -2,6 +2,7 @@ import { NextRequest, NextResponse } from "next/server";
|
|||||||
import { auth } from "@clerk/nextjs/server";
|
import { auth } from "@clerk/nextjs/server";
|
||||||
import { getDatabase } from "@/lib/database";
|
import { getDatabase } from "@/lib/database";
|
||||||
import log from "@/lib/logger";
|
import log from "@/lib/logger";
|
||||||
|
import { ensureUserSynced } from "@/lib/sync-user";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET /api/notifications
|
* GET /api/notifications
|
||||||
@ -84,6 +85,39 @@ export async function POST(req: NextRequest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const db = await getDatabase();
|
const db = await getDatabase();
|
||||||
|
const currentUser = await ensureUserSynced(userId, db);
|
||||||
|
|
||||||
|
if (!currentUser) {
|
||||||
|
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const canCreateNotifications =
|
||||||
|
currentUser.role === "superAdmin" ||
|
||||||
|
currentUser.role === "admin" ||
|
||||||
|
currentUser.role === "trainer";
|
||||||
|
|
||||||
|
if (!canCreateNotifications) {
|
||||||
|
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const targetUser = await db.getUserById(targetUserId);
|
||||||
|
if (!targetUser) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Target user not found" },
|
||||||
|
{ status: 404 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
currentUser.role !== "superAdmin" &&
|
||||||
|
(!currentUser.gymId || targetUser.gymId !== currentUser.gymId)
|
||||||
|
) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Forbidden - Cannot notify users from other gyms" },
|
||||||
|
{ status: 403 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const notification = await db.createNotification({
|
const notification = await db.createNotification({
|
||||||
id: crypto.randomUUID(),
|
id: crypto.randomUUID(),
|
||||||
userId: targetUserId,
|
userId: targetUserId,
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { NextRequest, NextResponse } from "next/server";
|
|||||||
import { getDatabase } from "@/lib/database";
|
import { getDatabase } from "@/lib/database";
|
||||||
import { ensureUserSynced } from "@/lib/sync-user";
|
import { ensureUserSynced } from "@/lib/sync-user";
|
||||||
import log from "@/lib/logger";
|
import log from "@/lib/logger";
|
||||||
|
import { getUserMembershipContext } from "@/lib/membership/access";
|
||||||
|
|
||||||
export async function POST(req: NextRequest) {
|
export async function POST(req: NextRequest) {
|
||||||
try {
|
try {
|
||||||
@ -11,6 +12,18 @@ export async function POST(req: NextRequest) {
|
|||||||
|
|
||||||
const db = await getDatabase();
|
const db = await getDatabase();
|
||||||
await ensureUserSynced(userId, db);
|
await ensureUserSynced(userId, db);
|
||||||
|
const { features, membershipType } = await getUserMembershipContext(userId);
|
||||||
|
|
||||||
|
if (!features.nutritionTracking) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error:
|
||||||
|
"Nutrition tracking is available on Premium and VIP memberships",
|
||||||
|
membershipType,
|
||||||
|
},
|
||||||
|
{ status: 403 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const body = await req.json();
|
const body = await req.json();
|
||||||
const {
|
const {
|
||||||
@ -59,6 +72,18 @@ export async function GET(req: NextRequest) {
|
|||||||
|
|
||||||
const db = await getDatabase();
|
const db = await getDatabase();
|
||||||
await ensureUserSynced(userId, db);
|
await ensureUserSynced(userId, db);
|
||||||
|
const { features, membershipType } = await getUserMembershipContext(userId);
|
||||||
|
|
||||||
|
if (!features.nutritionTracking) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error:
|
||||||
|
"Nutrition tracking is available on Premium and VIP memberships",
|
||||||
|
membershipType,
|
||||||
|
},
|
||||||
|
{ status: 403 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const url = new URL(req.url);
|
const url = new URL(req.url);
|
||||||
const date = url.searchParams.get("date");
|
const date = url.searchParams.get("date");
|
||||||
@ -88,6 +113,18 @@ export async function DELETE(req: NextRequest) {
|
|||||||
|
|
||||||
const db = await getDatabase();
|
const db = await getDatabase();
|
||||||
await ensureUserSynced(userId, db);
|
await ensureUserSynced(userId, db);
|
||||||
|
const { features, membershipType } = await getUserMembershipContext(userId);
|
||||||
|
|
||||||
|
if (!features.nutritionTracking) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error:
|
||||||
|
"Nutrition tracking is available on Premium and VIP memberships",
|
||||||
|
membershipType,
|
||||||
|
},
|
||||||
|
{ status: 403 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const url = new URL(req.url);
|
const url = new URL(req.url);
|
||||||
const id = url.searchParams.get("id");
|
const id = url.searchParams.get("id");
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { NextRequest, NextResponse } from "next/server";
|
|||||||
import { getDatabase } from "@/lib/database";
|
import { getDatabase } from "@/lib/database";
|
||||||
import { ensureUserSynced } from "@/lib/sync-user";
|
import { ensureUserSynced } from "@/lib/sync-user";
|
||||||
import log from "@/lib/logger";
|
import log from "@/lib/logger";
|
||||||
|
import { getUserMembershipContext } from "@/lib/membership/access";
|
||||||
|
|
||||||
export async function POST(req: NextRequest) {
|
export async function POST(req: NextRequest) {
|
||||||
try {
|
try {
|
||||||
@ -11,6 +12,18 @@ export async function POST(req: NextRequest) {
|
|||||||
|
|
||||||
const db = await getDatabase();
|
const db = await getDatabase();
|
||||||
await ensureUserSynced(userId, db);
|
await ensureUserSynced(userId, db);
|
||||||
|
const { features, membershipType } = await getUserMembershipContext(userId);
|
||||||
|
|
||||||
|
if (!features.nutritionTracking) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error:
|
||||||
|
"Nutrition tracking is available on Premium and VIP memberships",
|
||||||
|
membershipType,
|
||||||
|
},
|
||||||
|
{ status: 403 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const body = await req.json();
|
const body = await req.json();
|
||||||
const { date, meals, totalCalories, calorieGoal } = body;
|
const { date, meals, totalCalories, calorieGoal } = body;
|
||||||
@ -58,6 +71,18 @@ export async function GET(req: NextRequest) {
|
|||||||
|
|
||||||
const db = await getDatabase();
|
const db = await getDatabase();
|
||||||
await ensureUserSynced(userId, db);
|
await ensureUserSynced(userId, db);
|
||||||
|
const { features, membershipType } = await getUserMembershipContext(userId);
|
||||||
|
|
||||||
|
if (!features.nutritionTracking) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error:
|
||||||
|
"Nutrition tracking is available on Premium and VIP memberships",
|
||||||
|
membershipType,
|
||||||
|
},
|
||||||
|
{ status: 403 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const url = new URL(req.url);
|
const url = new URL(req.url);
|
||||||
const date = url.searchParams.get("date");
|
const date = url.searchParams.get("date");
|
||||||
@ -100,6 +125,18 @@ export async function DELETE(req: NextRequest) {
|
|||||||
|
|
||||||
const db = await getDatabase();
|
const db = await getDatabase();
|
||||||
await ensureUserSynced(userId, db);
|
await ensureUserSynced(userId, db);
|
||||||
|
const { features, membershipType } = await getUserMembershipContext(userId);
|
||||||
|
|
||||||
|
if (!features.nutritionTracking) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error:
|
||||||
|
"Nutrition tracking is available on Premium and VIP memberships",
|
||||||
|
membershipType,
|
||||||
|
},
|
||||||
|
{ status: 403 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const url = new URL(req.url);
|
const url = new URL(req.url);
|
||||||
const id = url.searchParams.get("id");
|
const id = url.searchParams.get("id");
|
||||||
|
|||||||
@ -0,0 +1,83 @@
|
|||||||
|
/**
|
||||||
|
* @jest-environment node
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { POST } from "../route";
|
||||||
|
|
||||||
|
jest.mock("@clerk/nextjs/server", () => ({
|
||||||
|
auth: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/lib/database", () => ({
|
||||||
|
getDatabase: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/lib/sync-user", () => ({
|
||||||
|
ensureUserSynced: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/lib/logger", () => ({
|
||||||
|
info: jest.fn(),
|
||||||
|
warn: jest.fn(),
|
||||||
|
error: jest.fn(),
|
||||||
|
debug: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("POST /api/recommendations/approve authz", () => {
|
||||||
|
const mockAuth = require("@clerk/nextjs/server").auth as jest.Mock;
|
||||||
|
const mockGetDatabase = require("@/lib/database").getDatabase as jest.Mock;
|
||||||
|
const mockEnsureUserSynced = require("@/lib/sync-user")
|
||||||
|
.ensureUserSynced as jest.Mock;
|
||||||
|
|
||||||
|
const mockDb = {
|
||||||
|
getAllRecommendations: jest.fn(),
|
||||||
|
getUserById: jest.fn(),
|
||||||
|
updateRecommendation: jest.fn(),
|
||||||
|
createNotification: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
mockGetDatabase.mockResolvedValue(mockDb);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns 403 for non-staff role", async () => {
|
||||||
|
mockAuth.mockResolvedValue({ userId: "client_1" });
|
||||||
|
mockEnsureUserSynced.mockResolvedValue({
|
||||||
|
id: "client_1",
|
||||||
|
role: "client",
|
||||||
|
gymId: "gym_a",
|
||||||
|
});
|
||||||
|
|
||||||
|
const req = new Request("http://localhost/api/recommendations/approve", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({ recommendationId: "rec_1", status: "approved" }),
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
});
|
||||||
|
|
||||||
|
const res = await POST(req);
|
||||||
|
expect(res.status).toBe(403);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns 403 for cross-gym approval by admin", async () => {
|
||||||
|
mockAuth.mockResolvedValue({ userId: "admin_1" });
|
||||||
|
mockEnsureUserSynced.mockResolvedValue({
|
||||||
|
id: "admin_1",
|
||||||
|
role: "admin",
|
||||||
|
gymId: "gym_a",
|
||||||
|
});
|
||||||
|
mockDb.getAllRecommendations.mockResolvedValue([
|
||||||
|
{ id: "rec_1", userId: "client_1" },
|
||||||
|
]);
|
||||||
|
mockDb.getUserById.mockResolvedValue({ id: "client_1", gymId: "gym_b" });
|
||||||
|
|
||||||
|
const req = new Request("http://localhost/api/recommendations/approve", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({ recommendationId: "rec_1", status: "approved" }),
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
});
|
||||||
|
|
||||||
|
const res = await POST(req);
|
||||||
|
expect(res.status).toBe(403);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -1,13 +1,115 @@
|
|||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
|
import { auth } from "@clerk/nextjs/server";
|
||||||
import { getDatabase } from "@/lib/database";
|
import { getDatabase } from "@/lib/database";
|
||||||
import log from "@/lib/logger";
|
import log from "@/lib/logger";
|
||||||
|
import { ensureUserSynced } from "@/lib/sync-user";
|
||||||
|
|
||||||
|
const AI_LINK_PREFIX = "[AI_LINKED]";
|
||||||
|
|
||||||
|
type GoalType =
|
||||||
|
| "weight_target"
|
||||||
|
| "strength_milestone"
|
||||||
|
| "endurance_target"
|
||||||
|
| "flexibility_goal"
|
||||||
|
| "habit_building"
|
||||||
|
| "custom";
|
||||||
|
|
||||||
|
interface ParsedPlanItem {
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
goalType: GoalType;
|
||||||
|
}
|
||||||
|
|
||||||
|
function inferGoalType(text: string): GoalType {
|
||||||
|
const normalized = text.toLowerCase();
|
||||||
|
|
||||||
|
if (
|
||||||
|
normalized.includes("strength") ||
|
||||||
|
normalized.includes("bench") ||
|
||||||
|
normalized.includes("squat") ||
|
||||||
|
normalized.includes("deadlift") ||
|
||||||
|
normalized.includes("weights")
|
||||||
|
) {
|
||||||
|
return "strength_milestone";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
normalized.includes("run") ||
|
||||||
|
normalized.includes("cardio") ||
|
||||||
|
normalized.includes("endurance") ||
|
||||||
|
normalized.includes("cycle")
|
||||||
|
) {
|
||||||
|
return "endurance_target";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
normalized.includes("stretch") ||
|
||||||
|
normalized.includes("mobility") ||
|
||||||
|
normalized.includes("yoga") ||
|
||||||
|
normalized.includes("flexibility")
|
||||||
|
) {
|
||||||
|
return "flexibility_goal";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
normalized.includes("daily") ||
|
||||||
|
normalized.includes("routine") ||
|
||||||
|
normalized.includes("habit")
|
||||||
|
) {
|
||||||
|
return "habit_building";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "custom";
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseActivityPlanToItems(activityPlan: string): ParsedPlanItem[] {
|
||||||
|
const lines = activityPlan
|
||||||
|
.replace(/\r\n/g, "\n")
|
||||||
|
.split(/\n+/)
|
||||||
|
.flatMap((line) => line.split(/(?<=[.!?])\s+(?=[A-Z0-9])/g))
|
||||||
|
.map((line) => line.trim())
|
||||||
|
.filter(Boolean)
|
||||||
|
.map((line) => line.replace(/^[-*•\d.)\s]+/, "").trim())
|
||||||
|
.filter((line) => line.length > 10)
|
||||||
|
.slice(0, 8);
|
||||||
|
|
||||||
|
const uniqueLines = Array.from(new Set(lines));
|
||||||
|
|
||||||
|
return uniqueLines.map((line) => ({
|
||||||
|
id: crypto.randomUUID(),
|
||||||
|
title: line.length > 72 ? `${line.slice(0, 69)}...` : line,
|
||||||
|
description: line,
|
||||||
|
goalType: inferGoalType(line),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDefaultPlanItems(): ParsedPlanItem[] {
|
||||||
|
const defaults = [
|
||||||
|
"Complete 3 strength sessions this week with progressive overload.",
|
||||||
|
"Add 2 cardio sessions of 25-30 minutes for endurance.",
|
||||||
|
"Do a 10-minute mobility routine daily after training.",
|
||||||
|
];
|
||||||
|
|
||||||
|
return defaults.map((line) => ({
|
||||||
|
id: crypto.randomUUID(),
|
||||||
|
title: line.length > 72 ? `${line.slice(0, 69)}...` : line,
|
||||||
|
description: line,
|
||||||
|
goalType: inferGoalType(line),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
export async function POST(req: Request) {
|
export async function POST(req: Request) {
|
||||||
try {
|
try {
|
||||||
|
const { userId: clerkUserId } = await auth();
|
||||||
|
if (!clerkUserId) {
|
||||||
|
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
const body = await req.json();
|
const body = await req.json();
|
||||||
log.debug("Approve recommendation request body", { body });
|
log.debug("Approve recommendation request body", { body });
|
||||||
|
|
||||||
const { recommendationId, status, approvedBy } = body;
|
const { recommendationId, status } = body;
|
||||||
|
|
||||||
if (!recommendationId || !status) {
|
if (!recommendationId || !status) {
|
||||||
log.error("Missing required fields", {
|
log.error("Missing required fields", {
|
||||||
@ -22,12 +124,52 @@ export async function POST(req: Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const db = await getDatabase();
|
const db = await getDatabase();
|
||||||
|
const currentUser = await ensureUserSynced(clerkUserId, db);
|
||||||
|
|
||||||
|
if (!currentUser) {
|
||||||
|
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const canApproveRecommendations =
|
||||||
|
currentUser.role === "superAdmin" ||
|
||||||
|
currentUser.role === "admin" ||
|
||||||
|
currentUser.role === "trainer";
|
||||||
|
|
||||||
|
if (!canApproveRecommendations) {
|
||||||
|
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const existingRecommendation = (await db.getAllRecommendations()).find(
|
||||||
|
(recommendation) => recommendation.id === recommendationId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!existingRecommendation) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Recommendation not found" },
|
||||||
|
{ status: 404 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentUser.role !== "superAdmin") {
|
||||||
|
const targetUser = await db.getUserById(existingRecommendation.userId);
|
||||||
|
|
||||||
|
if (
|
||||||
|
!currentUser.gymId ||
|
||||||
|
!targetUser ||
|
||||||
|
targetUser.gymId !== currentUser.gymId
|
||||||
|
) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Forbidden - Cannot access users from other gyms" },
|
||||||
|
{ status: 403 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update recommendation status
|
// Update recommendation status
|
||||||
const updates: any = {
|
const updates: any = {
|
||||||
status,
|
status,
|
||||||
approvedAt: status === "approved" ? new Date() : undefined,
|
approvedAt: status === "approved" ? new Date() : undefined,
|
||||||
approvedBy: status === "approved" ? approvedBy : undefined,
|
approvedBy: status === "approved" ? clerkUserId : undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Remove undefined keys
|
// Remove undefined keys
|
||||||
@ -47,8 +189,103 @@ export async function POST(req: Request) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If approved, create a notification for the user
|
let pausedGoalsCount = 0;
|
||||||
|
let createdGoalsCount = 0;
|
||||||
|
|
||||||
|
// If approved, regenerate linked AI goals and create a notification for the user
|
||||||
if (status === "approved") {
|
if (status === "approved") {
|
||||||
|
try {
|
||||||
|
const existingActiveGoals = await db.getFitnessGoalsByUserId(
|
||||||
|
updatedRecommendation.userId,
|
||||||
|
"active",
|
||||||
|
);
|
||||||
|
|
||||||
|
const linkedGoals = existingActiveGoals.filter((goal) =>
|
||||||
|
goal.notes?.startsWith(AI_LINK_PREFIX),
|
||||||
|
);
|
||||||
|
|
||||||
|
pausedGoalsCount = linkedGoals.length;
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
linkedGoals.map((goal) =>
|
||||||
|
db.updateFitnessGoal(goal.id, {
|
||||||
|
status: "paused",
|
||||||
|
notes: `${goal.notes || ""}\nPaused due to recommendation approval on ${new Date().toISOString()}`,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
let planItems = parseActivityPlanToItems(
|
||||||
|
updatedRecommendation.activityPlan || "",
|
||||||
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
planItems.length === 0 &&
|
||||||
|
updatedRecommendation.recommendationText
|
||||||
|
) {
|
||||||
|
planItems = parseActivityPlanToItems(
|
||||||
|
updatedRecommendation.recommendationText,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (planItems.length === 0) {
|
||||||
|
planItems = getDefaultPlanItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
const fitnessProfileId =
|
||||||
|
updatedRecommendation.fitnessProfileId ||
|
||||||
|
(await db.getFitnessProfileByUserId(updatedRecommendation.userId))
|
||||||
|
?.id;
|
||||||
|
|
||||||
|
if (!fitnessProfileId) {
|
||||||
|
log.warn("No fitness profile available for AI goal creation", {
|
||||||
|
recommendationId,
|
||||||
|
userId: updatedRecommendation.userId,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const createdGoals = await Promise.all(
|
||||||
|
planItems.map((item) =>
|
||||||
|
db.createFitnessGoal({
|
||||||
|
id: crypto.randomUUID(),
|
||||||
|
userId: updatedRecommendation.userId,
|
||||||
|
fitnessProfileId,
|
||||||
|
goalType: item.goalType,
|
||||||
|
title: item.title,
|
||||||
|
description: item.description,
|
||||||
|
targetValue: undefined,
|
||||||
|
currentValue: 0,
|
||||||
|
unit: undefined,
|
||||||
|
startDate: new Date(),
|
||||||
|
targetDate: undefined,
|
||||||
|
completedDate: undefined,
|
||||||
|
status: "active",
|
||||||
|
progress: 0,
|
||||||
|
priority: "medium",
|
||||||
|
notes: `${AI_LINK_PREFIX} recommendationId=${updatedRecommendation.id}; itemId=${item.id}`,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
createdGoalsCount = createdGoals.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("Regenerated linked AI goals from approved recommendation", {
|
||||||
|
recommendationId: updatedRecommendation.id,
|
||||||
|
userId: updatedRecommendation.userId,
|
||||||
|
pausedGoals: pausedGoalsCount,
|
||||||
|
createdGoals: createdGoalsCount,
|
||||||
|
});
|
||||||
|
} catch (goalConversionError) {
|
||||||
|
log.error(
|
||||||
|
"Failed to regenerate linked goals for approved recommendation",
|
||||||
|
goalConversionError,
|
||||||
|
{
|
||||||
|
recommendationId,
|
||||||
|
userId: updatedRecommendation.userId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await db.createNotification({
|
await db.createNotification({
|
||||||
id: crypto.randomUUID(),
|
id: crypto.randomUUID(),
|
||||||
@ -75,6 +312,8 @@ export async function POST(req: Request) {
|
|||||||
data: updatedRecommendation,
|
data: updatedRecommendation,
|
||||||
meta: {
|
meta: {
|
||||||
timestamp: new Date().toISOString(),
|
timestamp: new Date().toISOString(),
|
||||||
|
pausedGoals: pausedGoalsCount,
|
||||||
|
createdGoals: createdGoalsCount,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
455
apps/admin/src/app/api/recommendations/generate-self/route.ts
Normal file
455
apps/admin/src/app/api/recommendations/generate-self/route.ts
Normal file
@ -0,0 +1,455 @@
|
|||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import { auth } from "@clerk/nextjs/server";
|
||||||
|
import { getDatabase } from "@/lib/database";
|
||||||
|
import { buildAIContext } from "@/lib/ai/ai-context";
|
||||||
|
import { buildEnhancedPrompt, buildBasicPrompt } from "@/lib/ai/prompt-builder";
|
||||||
|
import log from "@/lib/logger";
|
||||||
|
import { ensureUserSynced } from "@/lib/sync-user";
|
||||||
|
import { getUserMembershipContext } from "@/lib/membership/access";
|
||||||
|
|
||||||
|
const AI_LINK_PREFIX = "[AI_LINKED]";
|
||||||
|
|
||||||
|
interface ParsedPlanItem {
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
goalType:
|
||||||
|
| "weight_target"
|
||||||
|
| "strength_milestone"
|
||||||
|
| "endurance_target"
|
||||||
|
| "flexibility_goal"
|
||||||
|
| "habit_building"
|
||||||
|
| "custom";
|
||||||
|
}
|
||||||
|
|
||||||
|
interface GeneratedPlanContent {
|
||||||
|
recommendationText?: string;
|
||||||
|
activityPlan?: string;
|
||||||
|
dietPlan?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildFallbackPlan(profile: {
|
||||||
|
activityLevel?: string;
|
||||||
|
fitnessGoals?: string[] | string;
|
||||||
|
medicalConditions?: string;
|
||||||
|
}): GeneratedPlanContent {
|
||||||
|
const goals = Array.isArray(profile.fitnessGoals)
|
||||||
|
? profile.fitnessGoals
|
||||||
|
: typeof profile.fitnessGoals === "string" && profile.fitnessGoals
|
||||||
|
? [profile.fitnessGoals]
|
||||||
|
: ["general fitness"];
|
||||||
|
|
||||||
|
const primaryGoal = goals[0] || "general fitness";
|
||||||
|
const activityLevel = profile.activityLevel || "moderate";
|
||||||
|
const hasMedicalNotes = Boolean(profile.medicalConditions?.trim());
|
||||||
|
|
||||||
|
return {
|
||||||
|
recommendationText:
|
||||||
|
`Personalized starter plan focused on ${primaryGoal} with ${activityLevel} activity pacing.` +
|
||||||
|
(hasMedicalNotes
|
||||||
|
? " Medical notes detected, so keep intensity conservative and progress gradually."
|
||||||
|
: ""),
|
||||||
|
activityPlan:
|
||||||
|
"- 3 strength sessions per week (full-body, 35-45 min)\n" +
|
||||||
|
"- 2 cardio sessions per week (20-30 min brisk walk/run/cycle)\n" +
|
||||||
|
"- 10 minutes daily mobility/stretching after workouts\n" +
|
||||||
|
"- 1 full recovery day each week",
|
||||||
|
dietPlan:
|
||||||
|
"- Build meals around lean protein, vegetables, whole grains, and hydration\n" +
|
||||||
|
"- Keep portions consistent and avoid skipping meals\n" +
|
||||||
|
"- Track intake daily and adjust calories based on weekly progress",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function inferGoalType(text: string): ParsedPlanItem["goalType"] {
|
||||||
|
const normalized = text.toLowerCase();
|
||||||
|
|
||||||
|
if (
|
||||||
|
normalized.includes("strength") ||
|
||||||
|
normalized.includes("bench") ||
|
||||||
|
normalized.includes("squat") ||
|
||||||
|
normalized.includes("deadlift") ||
|
||||||
|
normalized.includes("weights")
|
||||||
|
) {
|
||||||
|
return "strength_milestone";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
normalized.includes("run") ||
|
||||||
|
normalized.includes("cardio") ||
|
||||||
|
normalized.includes("endurance") ||
|
||||||
|
normalized.includes("cycle")
|
||||||
|
) {
|
||||||
|
return "endurance_target";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
normalized.includes("stretch") ||
|
||||||
|
normalized.includes("mobility") ||
|
||||||
|
normalized.includes("yoga") ||
|
||||||
|
normalized.includes("flexibility")
|
||||||
|
) {
|
||||||
|
return "flexibility_goal";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
normalized.includes("daily") ||
|
||||||
|
normalized.includes("routine") ||
|
||||||
|
normalized.includes("habit")
|
||||||
|
) {
|
||||||
|
return "habit_building";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "custom";
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseActivityPlanToItems(activityPlan: string): ParsedPlanItem[] {
|
||||||
|
const lines = activityPlan
|
||||||
|
.replace(/\r\n/g, "\n")
|
||||||
|
.split(/\n+/)
|
||||||
|
.flatMap((line) => line.split(/(?<=[.!?])\s+(?=[A-Z0-9])/g))
|
||||||
|
.map((line) => line.trim())
|
||||||
|
.filter(Boolean)
|
||||||
|
.map((line) => line.replace(/^[-*•\d.)\s]+/, "").trim())
|
||||||
|
.filter((line) => line.length > 10)
|
||||||
|
.slice(0, 8);
|
||||||
|
|
||||||
|
const uniqueLines = Array.from(new Set(lines));
|
||||||
|
|
||||||
|
return uniqueLines.map((line) => ({
|
||||||
|
id: crypto.randomUUID(),
|
||||||
|
title: line.length > 72 ? `${line.slice(0, 69)}...` : line,
|
||||||
|
description: line,
|
||||||
|
goalType: inferGoalType(line),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDefaultPlanItems(): ParsedPlanItem[] {
|
||||||
|
const defaults = [
|
||||||
|
"Complete 3 strength sessions this week with progressive overload.",
|
||||||
|
"Add 2 cardio sessions of 25-30 minutes for endurance.",
|
||||||
|
"Do a 10-minute mobility routine daily after training.",
|
||||||
|
];
|
||||||
|
|
||||||
|
return defaults.map((line) => ({
|
||||||
|
id: crypto.randomUUID(),
|
||||||
|
title: line.length > 72 ? `${line.slice(0, 69)}...` : line,
|
||||||
|
description: line,
|
||||||
|
goalType: inferGoalType(line),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseJsonPayload(content: string): GeneratedPlanContent {
|
||||||
|
let cleanResponse = content.trim();
|
||||||
|
|
||||||
|
if (cleanResponse.startsWith("```json")) {
|
||||||
|
cleanResponse = cleanResponse
|
||||||
|
.replace(/^```json\s*/, "")
|
||||||
|
.replace(/\s*```$/, "");
|
||||||
|
} else if (cleanResponse.startsWith("```")) {
|
||||||
|
cleanResponse = cleanResponse.replace(/^```\s*/, "").replace(/\s*```$/, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
const firstBrace = cleanResponse.indexOf("{");
|
||||||
|
const lastBrace = cleanResponse.lastIndexOf("}");
|
||||||
|
if (firstBrace !== -1 && lastBrace !== -1) {
|
||||||
|
cleanResponse = cleanResponse.substring(firstBrace, lastBrace + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSON.parse(cleanResponse) as GeneratedPlanContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function generateWithOpenAI(
|
||||||
|
openaiApiKey: string,
|
||||||
|
prompt: string,
|
||||||
|
): Promise<GeneratedPlanContent> {
|
||||||
|
const response = await fetch("https://api.openai.com/v1/chat/completions", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Authorization: `Bearer ${openaiApiKey}`,
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
model: "gpt-4o-mini",
|
||||||
|
messages: [
|
||||||
|
{
|
||||||
|
role: "system",
|
||||||
|
content:
|
||||||
|
'You are a professional fitness trainer and nutritionist. Always respond with valid JSON only, no markdown or code blocks. The response must have this exact structure: {"recommendationText": "string", "activityPlan": "string", "dietPlan": "string"}',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: "user",
|
||||||
|
content: prompt,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
temperature: 0.7,
|
||||||
|
max_tokens: 1500,
|
||||||
|
response_format: { type: "json_object" },
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const errorText = await response.text();
|
||||||
|
throw new Error(`OpenAI failed: ${response.status} ${errorText}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
return parseJsonPayload(data.choices[0].message.content as string);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function generateWithDeepSeek(
|
||||||
|
deepseekApiKey: string,
|
||||||
|
prompt: string,
|
||||||
|
): Promise<GeneratedPlanContent> {
|
||||||
|
const response = await fetch("https://api.deepseek.com/v1/chat/completions", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Authorization: `Bearer ${deepseekApiKey}`,
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
model: "deepseek-chat",
|
||||||
|
messages: [
|
||||||
|
{
|
||||||
|
role: "system",
|
||||||
|
content:
|
||||||
|
"You are a professional fitness trainer and nutritionist. Always respond with valid JSON only, no markdown or code blocks.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: "user",
|
||||||
|
content: prompt,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
temperature: 0.7,
|
||||||
|
max_tokens: 1200,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const errorText = await response.text();
|
||||||
|
throw new Error(`DeepSeek failed: ${response.status} ${errorText}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
return parseJsonPayload(data.choices[0].message.content as string);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function generateWithOllama(
|
||||||
|
prompt: string,
|
||||||
|
): Promise<GeneratedPlanContent> {
|
||||||
|
const response = await fetch("http://localhost:11434/api/generate", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
model: "gemma3:latest",
|
||||||
|
prompt,
|
||||||
|
stream: false,
|
||||||
|
format: "json",
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const errorText = await response.text();
|
||||||
|
throw new Error(`Ollama failed: ${response.status} ${errorText}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
return parseJsonPayload(data.response as string);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function POST() {
|
||||||
|
try {
|
||||||
|
const { userId } = await auth();
|
||||||
|
if (!userId) {
|
||||||
|
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const db = await getDatabase();
|
||||||
|
const currentUser = await ensureUserSynced(userId, db);
|
||||||
|
|
||||||
|
if (!currentUser) {
|
||||||
|
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const { membershipType, features } = await getUserMembershipContext(userId);
|
||||||
|
|
||||||
|
if (membershipType === "basic") {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error:
|
||||||
|
"AI plan generation is available on Premium and VIP memberships",
|
||||||
|
membershipType,
|
||||||
|
},
|
||||||
|
{ status: 403 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (features.recommendationsPerMonth > 0) {
|
||||||
|
const currentMonth = new Date();
|
||||||
|
const monthStart = new Date(
|
||||||
|
currentMonth.getFullYear(),
|
||||||
|
currentMonth.getMonth(),
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
const monthEnd = new Date(
|
||||||
|
currentMonth.getFullYear(),
|
||||||
|
currentMonth.getMonth() + 1,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
|
||||||
|
const existingRecommendations =
|
||||||
|
await db.getRecommendationsByUserId(userId);
|
||||||
|
const recommendationsThisMonth = existingRecommendations.filter(
|
||||||
|
(recommendation) =>
|
||||||
|
recommendation.generatedAt >= monthStart &&
|
||||||
|
recommendation.generatedAt < monthEnd,
|
||||||
|
).length;
|
||||||
|
|
||||||
|
if (recommendationsThisMonth >= features.recommendationsPerMonth) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error: `Your ${membershipType} plan includes ${features.recommendationsPerMonth} AI recommendation(s) per month`,
|
||||||
|
membershipType,
|
||||||
|
},
|
||||||
|
{ status: 403 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const profile = await db.getFitnessProfileByUserId(userId);
|
||||||
|
if (!profile) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Complete your fitness profile before generating a plan" },
|
||||||
|
{ status: 404 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let prompt: string;
|
||||||
|
try {
|
||||||
|
const context = await buildAIContext(userId);
|
||||||
|
prompt = buildEnhancedPrompt(context);
|
||||||
|
} catch (error) {
|
||||||
|
log.warn("Failed to build AI context for self-generate", {
|
||||||
|
userId,
|
||||||
|
error: error instanceof Error ? error.message : String(error),
|
||||||
|
});
|
||||||
|
prompt = buildBasicPrompt(profile);
|
||||||
|
}
|
||||||
|
|
||||||
|
const openaiApiKey = process.env.OPENAI_API_KEY;
|
||||||
|
const deepseekApiKey = process.env.DEEPSEEK_API_KEY;
|
||||||
|
|
||||||
|
let parsedResponse: GeneratedPlanContent;
|
||||||
|
let usedFallbackPlan = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (openaiApiKey) {
|
||||||
|
parsedResponse = await generateWithOpenAI(openaiApiKey, prompt);
|
||||||
|
} else if (deepseekApiKey) {
|
||||||
|
parsedResponse = await generateWithDeepSeek(deepseekApiKey, prompt);
|
||||||
|
} else {
|
||||||
|
parsedResponse = await generateWithOllama(prompt);
|
||||||
|
}
|
||||||
|
} catch (providerError) {
|
||||||
|
log.error("Self-generate provider failed", providerError, {
|
||||||
|
userId,
|
||||||
|
hasOpenAI: Boolean(openaiApiKey),
|
||||||
|
hasDeepSeek: Boolean(deepseekApiKey),
|
||||||
|
});
|
||||||
|
|
||||||
|
parsedResponse = buildFallbackPlan({
|
||||||
|
activityLevel: profile.activityLevel,
|
||||||
|
fitnessGoals: profile.fitnessGoals,
|
||||||
|
medicalConditions: profile.medicalConditions,
|
||||||
|
});
|
||||||
|
usedFallbackPlan = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const recommendation = await db.createRecommendation({
|
||||||
|
id: crypto.randomUUID(),
|
||||||
|
userId,
|
||||||
|
fitnessProfileId: profile.id,
|
||||||
|
recommendationText: parsedResponse.recommendationText || "",
|
||||||
|
activityPlan: parsedResponse.activityPlan || "",
|
||||||
|
dietPlan: parsedResponse.dietPlan || "",
|
||||||
|
status: "approved",
|
||||||
|
generatedAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const existingActiveGoals = await db.getFitnessGoalsByUserId(
|
||||||
|
userId,
|
||||||
|
"active",
|
||||||
|
);
|
||||||
|
const linkedGoals = existingActiveGoals.filter((goal) =>
|
||||||
|
goal.notes?.startsWith(AI_LINK_PREFIX),
|
||||||
|
);
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
linkedGoals.map((goal) =>
|
||||||
|
db.updateFitnessGoal(goal.id, {
|
||||||
|
status: "paused",
|
||||||
|
notes: `${goal.notes || ""}\nPaused due to new AI plan generation on ${new Date().toISOString()}`,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
let planItems = parseActivityPlanToItems(parsedResponse.activityPlan || "");
|
||||||
|
|
||||||
|
if (planItems.length === 0 && parsedResponse.recommendationText) {
|
||||||
|
planItems = parseActivityPlanToItems(parsedResponse.recommendationText);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (planItems.length === 0) {
|
||||||
|
planItems = getDefaultPlanItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug("AI plan parsed into goal items", {
|
||||||
|
recommendationId: recommendation.id,
|
||||||
|
userId,
|
||||||
|
parsedItems: planItems.length,
|
||||||
|
});
|
||||||
|
|
||||||
|
const createdGoals = await Promise.all(
|
||||||
|
planItems.map((item) =>
|
||||||
|
db.createFitnessGoal({
|
||||||
|
id: crypto.randomUUID(),
|
||||||
|
userId,
|
||||||
|
fitnessProfileId: profile.id,
|
||||||
|
goalType: item.goalType,
|
||||||
|
title: item.title,
|
||||||
|
description: item.description,
|
||||||
|
targetValue: undefined,
|
||||||
|
currentValue: 0,
|
||||||
|
unit: undefined,
|
||||||
|
startDate: new Date(),
|
||||||
|
targetDate: undefined,
|
||||||
|
completedDate: undefined,
|
||||||
|
status: "active",
|
||||||
|
progress: 0,
|
||||||
|
priority: "medium",
|
||||||
|
notes: `${AI_LINK_PREFIX} recommendationId=${recommendation.id}; itemId=${item.id}`,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
success: true,
|
||||||
|
data: recommendation,
|
||||||
|
meta: {
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
createdGoals: createdGoals.length,
|
||||||
|
pausedGoals: linkedGoals.length,
|
||||||
|
usedFallbackPlan,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
log.error("Failed to self-generate recommendation", error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Internal server error" },
|
||||||
|
{ status: 500 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,85 @@
|
|||||||
|
/**
|
||||||
|
* @jest-environment node
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { POST } from "../route";
|
||||||
|
|
||||||
|
jest.mock("@clerk/nextjs/server", () => ({
|
||||||
|
auth: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/lib/database", () => ({
|
||||||
|
getDatabase: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/lib/sync-user", () => ({
|
||||||
|
ensureUserSynced: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/lib/ai/ai-context", () => ({
|
||||||
|
buildAIContext: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/lib/ai/prompt-builder", () => ({
|
||||||
|
buildEnhancedPrompt: jest.fn(),
|
||||||
|
buildBasicPrompt: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/lib/logger", () => ({
|
||||||
|
info: jest.fn(),
|
||||||
|
warn: jest.fn(),
|
||||||
|
error: jest.fn(),
|
||||||
|
debug: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("POST /api/recommendations/generate authz", () => {
|
||||||
|
const mockAuth = require("@clerk/nextjs/server").auth as jest.Mock;
|
||||||
|
const mockGetDatabase = require("@/lib/database").getDatabase as jest.Mock;
|
||||||
|
const mockEnsureUserSynced = require("@/lib/sync-user")
|
||||||
|
.ensureUserSynced as jest.Mock;
|
||||||
|
|
||||||
|
const mockDb = {
|
||||||
|
getUserById: jest.fn(),
|
||||||
|
getFitnessProfileByUserId: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
mockGetDatabase.mockResolvedValue(mockDb);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns 401 when unauthenticated", async () => {
|
||||||
|
mockAuth.mockResolvedValue({ userId: null });
|
||||||
|
|
||||||
|
const req = new Request("http://localhost/api/recommendations/generate", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({ userId: "client_1" }),
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
});
|
||||||
|
|
||||||
|
const res = await POST(req);
|
||||||
|
expect(res.status).toBe(401);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns 403 when staff accesses user from another gym", async () => {
|
||||||
|
mockAuth.mockResolvedValue({ userId: "admin_1" });
|
||||||
|
mockEnsureUserSynced.mockResolvedValue({
|
||||||
|
id: "admin_1",
|
||||||
|
role: "admin",
|
||||||
|
gymId: "gym_a",
|
||||||
|
});
|
||||||
|
mockDb.getUserById.mockResolvedValue({
|
||||||
|
id: "client_1",
|
||||||
|
gymId: "gym_b",
|
||||||
|
});
|
||||||
|
|
||||||
|
const req = new Request("http://localhost/api/recommendations/generate", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({ userId: "client_1" }),
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
});
|
||||||
|
|
||||||
|
const res = await POST(req);
|
||||||
|
expect(res.status).toBe(403);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -1,11 +1,19 @@
|
|||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
|
import { auth } from "@clerk/nextjs/server";
|
||||||
import { getDatabase } from "@/lib/database";
|
import { getDatabase } from "@/lib/database";
|
||||||
import { buildAIContext } from "@/lib/ai/ai-context";
|
import { buildAIContext } from "@/lib/ai/ai-context";
|
||||||
import { buildEnhancedPrompt, buildBasicPrompt } from "@/lib/ai/prompt-builder";
|
import { buildEnhancedPrompt, buildBasicPrompt } from "@/lib/ai/prompt-builder";
|
||||||
import log from "@/lib/logger";
|
import log from "@/lib/logger";
|
||||||
|
import { ensureUserSynced } from "@/lib/sync-user";
|
||||||
|
import { getUserMembershipContext } from "@/lib/membership/access";
|
||||||
|
|
||||||
export async function POST(req: Request) {
|
export async function POST(req: Request) {
|
||||||
try {
|
try {
|
||||||
|
const { userId: clerkUserId } = await auth();
|
||||||
|
if (!clerkUserId) {
|
||||||
|
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
const { userId, useExternalModel, modelProvider } = await req.json();
|
const { userId, useExternalModel, modelProvider } = await req.json();
|
||||||
|
|
||||||
if (!userId) {
|
if (!userId) {
|
||||||
@ -22,6 +30,69 @@ export async function POST(req: Request) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const db = await getDatabase();
|
const db = await getDatabase();
|
||||||
|
const currentUser = await ensureUserSynced(clerkUserId, db);
|
||||||
|
|
||||||
|
if (!currentUser) {
|
||||||
|
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const canGenerateRecommendations =
|
||||||
|
currentUser.role === "superAdmin" ||
|
||||||
|
currentUser.role === "admin" ||
|
||||||
|
currentUser.role === "trainer";
|
||||||
|
|
||||||
|
if (!canGenerateRecommendations) {
|
||||||
|
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const targetUser = await db.getUserById(userId);
|
||||||
|
if (!targetUser) {
|
||||||
|
return NextResponse.json({ error: "User not found" }, { status: 404 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const { membershipType, features } = await getUserMembershipContext(userId);
|
||||||
|
|
||||||
|
if (features.recommendationsPerMonth === 1) {
|
||||||
|
const currentMonth = new Date();
|
||||||
|
const monthStart = new Date(
|
||||||
|
currentMonth.getFullYear(),
|
||||||
|
currentMonth.getMonth(),
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
const monthEnd = new Date(
|
||||||
|
currentMonth.getFullYear(),
|
||||||
|
currentMonth.getMonth() + 1,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
|
||||||
|
const existingRecommendations =
|
||||||
|
await db.getRecommendationsByUserId(userId);
|
||||||
|
const recommendationsThisMonth = existingRecommendations.filter(
|
||||||
|
(recommendation) =>
|
||||||
|
recommendation.generatedAt >= monthStart &&
|
||||||
|
recommendation.generatedAt < monthEnd,
|
||||||
|
).length;
|
||||||
|
|
||||||
|
if (recommendationsThisMonth >= 1) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
error:
|
||||||
|
"Basic membership includes 1 recommendation per month. Upgrade to Premium or VIP for unlimited recommendations.",
|
||||||
|
membershipType,
|
||||||
|
},
|
||||||
|
{ status: 403 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentUser.role !== "superAdmin") {
|
||||||
|
if (!currentUser.gymId || targetUser.gymId !== currentUser.gymId) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Forbidden - Cannot access users from other gyms" },
|
||||||
|
{ status: 403 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Fetch fitness profile
|
// Fetch fitness profile
|
||||||
const profile = await db.getFitnessProfileByUserId(userId);
|
const profile = await db.getFitnessProfileByUserId(userId);
|
||||||
|
|||||||
@ -106,7 +106,7 @@ export async function POST(request: NextRequest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const db = await getDatabase();
|
const db = await getDatabase();
|
||||||
const currentUser = await db.getUserById(currentUserId);
|
const currentUser = await ensureUserSynced(currentUserId, db);
|
||||||
const isStaff =
|
const isStaff =
|
||||||
currentUser?.role === "admin" ||
|
currentUser?.role === "admin" ||
|
||||||
currentUser?.role === "superAdmin" ||
|
currentUser?.role === "superAdmin" ||
|
||||||
@ -140,6 +140,18 @@ export async function POST(request: NextRequest) {
|
|||||||
content,
|
content,
|
||||||
} = validation.data;
|
} = validation.data;
|
||||||
|
|
||||||
|
const targetUser = await db.getUserById(userId);
|
||||||
|
if (!targetUser) {
|
||||||
|
return badRequestResponse("Target user not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
currentUser?.role !== "superAdmin" &&
|
||||||
|
(!currentUser?.gymId || targetUser.gymId !== currentUser.gymId)
|
||||||
|
) {
|
||||||
|
return forbiddenResponse("Cannot create recommendations for other gyms");
|
||||||
|
}
|
||||||
|
|
||||||
// Handle AI Plan (Legacy/Specific)
|
// Handle AI Plan (Legacy/Specific)
|
||||||
if (recommendationText && activityPlan && dietPlan && fitnessProfileId) {
|
if (recommendationText && activityPlan && dietPlan && fitnessProfileId) {
|
||||||
const recommendation = await db.createRecommendation({
|
const recommendation = await db.createRecommendation({
|
||||||
@ -198,6 +210,41 @@ export async function PUT(request: NextRequest) {
|
|||||||
validation.data;
|
validation.data;
|
||||||
|
|
||||||
const db = await getDatabase();
|
const db = await getDatabase();
|
||||||
|
const currentUser = await ensureUserSynced(currentUserId, db);
|
||||||
|
|
||||||
|
if (!currentUser) {
|
||||||
|
return forbiddenResponse("User not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
const isStaff =
|
||||||
|
currentUser.role === "admin" ||
|
||||||
|
currentUser.role === "superAdmin" ||
|
||||||
|
currentUser.role === "trainer";
|
||||||
|
|
||||||
|
if (!isStaff) {
|
||||||
|
return forbiddenResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
const existingRecommendation = (await db.getAllRecommendations()).find(
|
||||||
|
(recommendation) => recommendation.id === id,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!existingRecommendation) {
|
||||||
|
return badRequestResponse("Recommendation not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentUser.role !== "superAdmin") {
|
||||||
|
const targetUser = await db.getUserById(existingRecommendation.userId);
|
||||||
|
if (
|
||||||
|
!currentUser.gymId ||
|
||||||
|
!targetUser ||
|
||||||
|
targetUser.gymId !== currentUser.gymId
|
||||||
|
) {
|
||||||
|
return forbiddenResponse(
|
||||||
|
"Cannot modify recommendations for other gyms",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const updated = await db.updateRecommendation(id, {
|
const updated = await db.updateRecommendation(id, {
|
||||||
...(status && { status }),
|
...(status && { status }),
|
||||||
|
|||||||
@ -35,16 +35,8 @@ export async function DELETE(
|
|||||||
|
|
||||||
const { id } = await params;
|
const { id } = await params;
|
||||||
|
|
||||||
// Try to find the assignment by checking trainer's assignments first
|
|
||||||
const trainerAssignments = await db.getTrainerClientAssignments(
|
|
||||||
currentUser.id,
|
|
||||||
);
|
|
||||||
let assignment = trainerAssignments.find((a) => a.id === id);
|
|
||||||
|
|
||||||
if (!assignment) {
|
|
||||||
// Check all assignments to find the one with this ID
|
|
||||||
const allAssignments = await db.getAllTrainerClientAssignments();
|
const allAssignments = await db.getAllTrainerClientAssignments();
|
||||||
assignment = allAssignments.find((a) => a.id === id);
|
const assignment = allAssignments.find((a) => a.id === id);
|
||||||
|
|
||||||
if (!assignment) {
|
if (!assignment) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
@ -53,18 +45,27 @@ export async function DELETE(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deactivate the assignment
|
if (currentUser.role !== "superAdmin") {
|
||||||
await db.deactivateTrainerClientAssignment(id);
|
if (!currentUser.gymId) {
|
||||||
|
return NextResponse.json({ error: "No gym assigned" }, { status: 403 });
|
||||||
|
}
|
||||||
|
|
||||||
log.info("Trainer-client assignment deactivated", {
|
const [trainer, client] = await Promise.all([
|
||||||
assignmentId: id,
|
db.getUserById(assignment.trainerId),
|
||||||
deactivatedBy: currentUser.id,
|
db.getUserById(assignment.clientId),
|
||||||
});
|
]);
|
||||||
|
|
||||||
return NextResponse.json({
|
if (
|
||||||
success: true,
|
!trainer ||
|
||||||
message: "Assignment deactivated successfully",
|
!client ||
|
||||||
});
|
trainer.gymId !== currentUser.gymId ||
|
||||||
|
client.gymId !== currentUser.gymId
|
||||||
|
) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Cannot modify assignments from other gyms" },
|
||||||
|
{ status: 403 },
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deactivate the assignment
|
// Deactivate the assignment
|
||||||
|
|||||||
@ -0,0 +1,89 @@
|
|||||||
|
/**
|
||||||
|
* @jest-environment node
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { NextRequest } from "next/server";
|
||||||
|
import { GET, POST } from "../route";
|
||||||
|
|
||||||
|
jest.mock("@clerk/nextjs/server", () => ({
|
||||||
|
auth: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/lib/database", () => ({
|
||||||
|
getDatabase: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/lib/sync-user", () => ({
|
||||||
|
ensureUserSynced: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/lib/logger", () => ({
|
||||||
|
info: jest.fn(),
|
||||||
|
warn: jest.fn(),
|
||||||
|
error: jest.fn(),
|
||||||
|
debug: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("/api/trainer-client authz", () => {
|
||||||
|
const mockAuth = require("@clerk/nextjs/server").auth as jest.Mock;
|
||||||
|
const mockGetDatabase = require("@/lib/database").getDatabase as jest.Mock;
|
||||||
|
const mockEnsureUserSynced = require("@/lib/sync-user")
|
||||||
|
.ensureUserSynced as jest.Mock;
|
||||||
|
|
||||||
|
const mockDb = {
|
||||||
|
getUserById: jest.fn(),
|
||||||
|
getTrainerClientAssignments: jest.fn(),
|
||||||
|
getAllTrainerClientAssignments: jest.fn(),
|
||||||
|
createTrainerClientAssignment: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
mockGetDatabase.mockResolvedValue(mockDb);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("blocks non-admin users from listing assignments", async () => {
|
||||||
|
mockAuth.mockResolvedValue({ userId: "trainer_1" });
|
||||||
|
mockEnsureUserSynced.mockResolvedValue({
|
||||||
|
id: "trainer_1",
|
||||||
|
role: "trainer",
|
||||||
|
gymId: "gym_a",
|
||||||
|
});
|
||||||
|
|
||||||
|
const request = new NextRequest("http://localhost/api/trainer-client");
|
||||||
|
const response = await GET(request);
|
||||||
|
|
||||||
|
expect(response.status).toBe(403);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("blocks admins from creating assignments across gyms", async () => {
|
||||||
|
mockAuth.mockResolvedValue({ userId: "admin_1" });
|
||||||
|
mockEnsureUserSynced.mockResolvedValue({
|
||||||
|
id: "admin_1",
|
||||||
|
role: "admin",
|
||||||
|
gymId: "gym_a",
|
||||||
|
});
|
||||||
|
|
||||||
|
mockDb.getUserById
|
||||||
|
.mockResolvedValueOnce({
|
||||||
|
id: "trainer_2",
|
||||||
|
role: "trainer",
|
||||||
|
gymId: "gym_b",
|
||||||
|
})
|
||||||
|
.mockResolvedValueOnce({
|
||||||
|
id: "client_2",
|
||||||
|
role: "client",
|
||||||
|
gymId: "gym_b",
|
||||||
|
});
|
||||||
|
|
||||||
|
const request = new NextRequest("http://localhost/api/trainer-client", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({ trainerId: "trainer_2", clientId: "client_2" }),
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await POST(request);
|
||||||
|
|
||||||
|
expect(response.status).toBe(403);
|
||||||
|
expect(mockDb.createTrainerClientAssignment).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -38,17 +38,110 @@ export async function GET(request: NextRequest) {
|
|||||||
const trainerId = searchParams.get("trainerId");
|
const trainerId = searchParams.get("trainerId");
|
||||||
const clientId = searchParams.get("clientId");
|
const clientId = searchParams.get("clientId");
|
||||||
|
|
||||||
let assignments;
|
if (trainerId && clientId) {
|
||||||
|
const [trainer, client] = await Promise.all([
|
||||||
|
db.getUserById(trainerId),
|
||||||
|
db.getUserById(clientId),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!trainer || !client) {
|
||||||
|
return NextResponse.json({ error: "User not found" }, { status: 404 });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
currentUser.role !== "superAdmin" &&
|
||||||
|
(!currentUser.gymId ||
|
||||||
|
trainer.gymId !== currentUser.gymId ||
|
||||||
|
client.gymId !== currentUser.gymId)
|
||||||
|
) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Cannot access assignments from other gyms" },
|
||||||
|
{ status: 403 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trainerId && !clientId) {
|
||||||
|
const trainer = await db.getUserById(trainerId);
|
||||||
|
if (!trainer) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Trainer not found" },
|
||||||
|
{ status: 404 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
currentUser.role !== "superAdmin" &&
|
||||||
|
(!currentUser.gymId || trainer.gymId !== currentUser.gymId)
|
||||||
|
) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Cannot access assignments from other gyms" },
|
||||||
|
{ status: 403 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!trainerId && clientId) {
|
||||||
|
const client = await db.getUserById(clientId);
|
||||||
|
if (!client) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Client not found" },
|
||||||
|
{ status: 404 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
currentUser.role !== "superAdmin" &&
|
||||||
|
(!currentUser.gymId || client.gymId !== currentUser.gymId)
|
||||||
|
) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Cannot access assignments from other gyms" },
|
||||||
|
{ status: 403 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let assignments = trainerId
|
||||||
|
? await db.getTrainerClientAssignments(trainerId)
|
||||||
|
: await db.getAllTrainerClientAssignments();
|
||||||
|
|
||||||
if (trainerId) {
|
|
||||||
assignments = await db.getTrainerClientAssignments(trainerId);
|
|
||||||
// Filter by clientId if provided
|
|
||||||
if (clientId) {
|
if (clientId) {
|
||||||
assignments = assignments.filter((a) => a.clientId === clientId);
|
assignments = assignments.filter((a) => a.clientId === clientId);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// Get all assignments (for admins, filtered by gym)
|
if (currentUser.role !== "superAdmin") {
|
||||||
assignments = await db.getAllTrainerClientAssignments();
|
if (!currentUser.gymId) {
|
||||||
|
return NextResponse.json({ error: "No gym assigned" }, { status: 403 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const involvedUserIds = Array.from(
|
||||||
|
new Set(
|
||||||
|
assignments.flatMap((assignment) => [
|
||||||
|
assignment.trainerId,
|
||||||
|
assignment.clientId,
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
const users = await Promise.all(
|
||||||
|
involvedUserIds.map((userId) => db.getUserById(userId)),
|
||||||
|
);
|
||||||
|
|
||||||
|
const gymByUserId = new Map(
|
||||||
|
users
|
||||||
|
.filter((user): user is NonNullable<typeof user> => !!user)
|
||||||
|
.map((user) => [user.id, user.gymId]),
|
||||||
|
);
|
||||||
|
|
||||||
|
assignments = assignments.filter((assignment) => {
|
||||||
|
const trainerGymId = gymByUserId.get(assignment.trainerId);
|
||||||
|
const clientGymId = gymByUserId.get(assignment.clientId);
|
||||||
|
|
||||||
|
return (
|
||||||
|
trainerGymId === currentUser.gymId &&
|
||||||
|
clientGymId === currentUser.gymId
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return NextResponse.json({ assignments });
|
return NextResponse.json({ assignments });
|
||||||
@ -121,6 +214,18 @@ export async function POST(request: NextRequest) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
currentUser.role !== "superAdmin" &&
|
||||||
|
(!currentUser.gymId ||
|
||||||
|
trainer.gymId !== currentUser.gymId ||
|
||||||
|
client.gymId !== currentUser.gymId)
|
||||||
|
) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Cannot assign users from other gyms" },
|
||||||
|
{ status: 403 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Check if assignment already exists
|
// Check if assignment already exists
|
||||||
const existingAssignments = await db.getTrainerClientAssignments(trainerId);
|
const existingAssignments = await db.getTrainerClientAssignments(trainerId);
|
||||||
const existingAssignment = existingAssignments.find(
|
const existingAssignment = existingAssignments.find(
|
||||||
|
|||||||
109
apps/admin/src/app/api/users/__tests__/delete-authz.test.ts
Normal file
109
apps/admin/src/app/api/users/__tests__/delete-authz.test.ts
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/**
|
||||||
|
* @jest-environment node
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { NextRequest } from "next/server";
|
||||||
|
import { DELETE } from "../route";
|
||||||
|
|
||||||
|
jest.mock("@clerk/nextjs/server", () => ({
|
||||||
|
auth: jest.fn(),
|
||||||
|
clerkClient: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/lib/database/index", () => ({
|
||||||
|
getDatabase: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/lib/sync-user", () => ({
|
||||||
|
ensureUserSynced: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@fitai/database", () => ({
|
||||||
|
db: {
|
||||||
|
all: jest.fn(),
|
||||||
|
get: jest.fn(),
|
||||||
|
run: jest.fn(),
|
||||||
|
},
|
||||||
|
sql: jest.fn((strings: TemplateStringsArray) => strings.join("")),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/lib/logger", () => ({
|
||||||
|
info: jest.fn(),
|
||||||
|
warn: jest.fn(),
|
||||||
|
error: jest.fn(),
|
||||||
|
debug: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("DELETE /api/users authz", () => {
|
||||||
|
const mockAuth = require("@clerk/nextjs/server").auth as jest.Mock;
|
||||||
|
const mockGetDatabase = require("@/lib/database/index")
|
||||||
|
.getDatabase as jest.Mock;
|
||||||
|
const mockEnsureUserSynced = require("@/lib/sync-user")
|
||||||
|
.ensureUserSynced as jest.Mock;
|
||||||
|
|
||||||
|
const mockDb = {
|
||||||
|
getUserById: jest.fn(),
|
||||||
|
deleteUser: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
mockGetDatabase.mockResolvedValue(mockDb);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("blocks self deletion", async () => {
|
||||||
|
mockAuth.mockResolvedValue({ userId: "admin_1" });
|
||||||
|
mockEnsureUserSynced.mockResolvedValue({
|
||||||
|
id: "admin_1",
|
||||||
|
role: "admin",
|
||||||
|
gymId: "gym_a",
|
||||||
|
});
|
||||||
|
|
||||||
|
const request = new NextRequest("http://localhost/api/users?id=admin_1", {
|
||||||
|
method: "DELETE",
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await DELETE(request);
|
||||||
|
expect(response.status).toBe(403);
|
||||||
|
expect(mockDb.deleteUser).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("blocks cross-gym deletion for admin", async () => {
|
||||||
|
mockAuth.mockResolvedValue({ userId: "admin_1" });
|
||||||
|
mockEnsureUserSynced.mockResolvedValue({
|
||||||
|
id: "admin_1",
|
||||||
|
role: "admin",
|
||||||
|
gymId: "gym_a",
|
||||||
|
});
|
||||||
|
mockDb.getUserById.mockResolvedValue({ id: "user_2", gymId: "gym_b" });
|
||||||
|
|
||||||
|
const request = new NextRequest("http://localhost/api/users?id=user_2", {
|
||||||
|
method: "DELETE",
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await DELETE(request);
|
||||||
|
expect(response.status).toBe(403);
|
||||||
|
expect(mockDb.deleteUser).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("allows superAdmin cross-gym deletion", async () => {
|
||||||
|
mockAuth.mockResolvedValue({ userId: "super_1" });
|
||||||
|
mockEnsureUserSynced.mockResolvedValue({
|
||||||
|
id: "super_1",
|
||||||
|
role: "superAdmin",
|
||||||
|
gymId: null,
|
||||||
|
});
|
||||||
|
mockDb.getUserById.mockResolvedValue({ id: "user_2", gymId: "gym_b" });
|
||||||
|
|
||||||
|
const request = new NextRequest("http://localhost/api/users?id=user_2", {
|
||||||
|
method: "DELETE",
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await DELETE(request);
|
||||||
|
const payload = await response.json();
|
||||||
|
|
||||||
|
expect(response.status).toBe(200);
|
||||||
|
expect(payload.success).toBe(true);
|
||||||
|
expect(mockDb.deleteUser).toHaveBeenCalledWith("user_2");
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -1,8 +1,78 @@
|
|||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
import { auth } from "@clerk/nextjs/server";
|
import { auth } from "@clerk/nextjs/server";
|
||||||
import { db, users as usersTable, eq, sql } from "@fitai/database";
|
import { db, users as usersTable, eq, sql } from "@fitai/database";
|
||||||
|
import { ensureGymsGeofenceColumns } from "@/lib/geofence";
|
||||||
import log from "@/lib/logger";
|
import log from "@/lib/logger";
|
||||||
|
|
||||||
|
export async function GET() {
|
||||||
|
try {
|
||||||
|
const { userId } = await auth();
|
||||||
|
if (!userId) return new NextResponse("Unauthorized", { status: 401 });
|
||||||
|
|
||||||
|
const user = await db
|
||||||
|
.select()
|
||||||
|
.from(usersTable)
|
||||||
|
.where(eq(usersTable.id, userId))
|
||||||
|
.get();
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
return new NextResponse("User not found", { status: 404 });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!user.gymId) {
|
||||||
|
return NextResponse.json({ gymId: null, gym: null });
|
||||||
|
}
|
||||||
|
|
||||||
|
await ensureGymsGeofenceColumns();
|
||||||
|
|
||||||
|
const rows = await db.all(sql`
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
location,
|
||||||
|
latitude,
|
||||||
|
longitude,
|
||||||
|
geofence_radius_meters as geofenceRadiusMeters,
|
||||||
|
geofence_enabled as geofenceEnabled,
|
||||||
|
status
|
||||||
|
FROM gyms
|
||||||
|
WHERE id = ${user.gymId}
|
||||||
|
LIMIT 1
|
||||||
|
`);
|
||||||
|
|
||||||
|
const gym = rows?.[0] as
|
||||||
|
| {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
location: string | null;
|
||||||
|
latitude: number | null;
|
||||||
|
longitude: number | null;
|
||||||
|
geofenceRadiusMeters: number | null;
|
||||||
|
geofenceEnabled: number | boolean | null;
|
||||||
|
status: "active" | "inactive";
|
||||||
|
}
|
||||||
|
| undefined;
|
||||||
|
|
||||||
|
if (!gym || gym.status !== "active") {
|
||||||
|
return NextResponse.json({ gymId: user.gymId, gym: null });
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
gymId: user.gymId,
|
||||||
|
gym: {
|
||||||
|
...gym,
|
||||||
|
geofenceEnabled:
|
||||||
|
typeof gym.geofenceEnabled === "boolean"
|
||||||
|
? gym.geofenceEnabled
|
||||||
|
: Boolean(gym.geofenceEnabled),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
log.error("Failed to fetch current user gym", error);
|
||||||
|
return new NextResponse("Internal Server Error", { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PATCH /api/users/gym
|
* PATCH /api/users/gym
|
||||||
* Body: { gymId: string | null }
|
* Body: { gymId: string | null }
|
||||||
|
|||||||
@ -580,26 +580,76 @@ export async function PUT(request: NextRequest) {
|
|||||||
|
|
||||||
export async function DELETE(request: NextRequest) {
|
export async function DELETE(request: NextRequest) {
|
||||||
try {
|
try {
|
||||||
|
const { userId: clerkUserId } = await auth();
|
||||||
|
if (!clerkUserId) {
|
||||||
|
return unauthorizedResponse();
|
||||||
|
}
|
||||||
|
|
||||||
const db = await getDatabase();
|
const db = await getDatabase();
|
||||||
|
const currentUser = await ensureUserSynced(clerkUserId, db);
|
||||||
|
|
||||||
|
if (!currentUser) {
|
||||||
|
return forbiddenResponse("Current user not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
const canDeleteUsers =
|
||||||
|
currentUser.role === "admin" || currentUser.role === "superAdmin";
|
||||||
|
|
||||||
|
if (!canDeleteUsers) {
|
||||||
|
return forbiddenResponse("Only admins can delete users");
|
||||||
|
}
|
||||||
|
|
||||||
const { searchParams } = new URL(request.url);
|
const { searchParams } = new URL(request.url);
|
||||||
const id = searchParams.get("id");
|
const id = searchParams.get("id");
|
||||||
const body = await request.json().catch(() => ({}));
|
const body = await request.json().catch(() => ({}));
|
||||||
const { ids } = body;
|
const { ids } = body;
|
||||||
|
|
||||||
|
const targetIds: string[] = Array.isArray(ids)
|
||||||
|
? ids.filter(
|
||||||
|
(userId: unknown): userId is string => typeof userId === "string",
|
||||||
|
)
|
||||||
|
: id
|
||||||
|
? [id]
|
||||||
|
: [];
|
||||||
|
|
||||||
|
if (targetIds.length === 0) {
|
||||||
|
return badRequestResponse("User ID or IDs array required");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetIds.includes(clerkUserId)) {
|
||||||
|
return forbiddenResponse("Cannot delete your own account");
|
||||||
|
}
|
||||||
|
|
||||||
|
const targetUsers = await Promise.all(
|
||||||
|
targetIds.map((targetId) => db.getUserById(targetId)),
|
||||||
|
);
|
||||||
|
|
||||||
|
const missingTargets = targetUsers.filter((user) => !user).length;
|
||||||
|
if (missingTargets > 0) {
|
||||||
|
return notFoundResponse("One or more users were not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentUser.role !== "superAdmin") {
|
||||||
|
if (!currentUser.gymId) {
|
||||||
|
return forbiddenResponse("No gym assigned to current user");
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasCrossGymTarget = targetUsers.some(
|
||||||
|
(targetUser) => targetUser && targetUser.gymId !== currentUser.gymId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (hasCrossGymTarget) {
|
||||||
|
return forbiddenResponse("Cannot delete users from other gyms");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ids && Array.isArray(ids)) {
|
if (ids && Array.isArray(ids)) {
|
||||||
// Bulk delete
|
// Bulk delete
|
||||||
await Promise.all(ids.map((userId: string) => db.deleteUser(userId)));
|
await Promise.all(ids.map((userId: string) => db.deleteUser(userId)));
|
||||||
return successResponse({ deleted: ids.length });
|
return successResponse({ deleted: ids.length });
|
||||||
} else if (id) {
|
|
||||||
// Single delete
|
|
||||||
const user = await db.getUserById(id);
|
|
||||||
if (!user) {
|
|
||||||
return notFoundResponse("User not found");
|
|
||||||
}
|
|
||||||
await db.deleteUser(id);
|
|
||||||
return successResponse({ deleted: 1 });
|
|
||||||
} else {
|
} else {
|
||||||
return badRequestResponse("User ID or IDs array required");
|
await db.deleteUser(id as string);
|
||||||
|
return successResponse({ deleted: 1 });
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error("Failed to delete user(s)", error);
|
log.error("Failed to delete user(s)", error);
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import {
|
|||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { useUser } from "@clerk/nextjs";
|
import { useUser } from "@clerk/nextjs";
|
||||||
import log from "@/lib/logger";
|
import log from "@/lib/logger";
|
||||||
|
import { MEMBERSHIP_FEATURES } from "@/lib/membership/features";
|
||||||
|
|
||||||
interface Backup {
|
interface Backup {
|
||||||
name: string;
|
name: string;
|
||||||
@ -28,6 +29,10 @@ interface Gym {
|
|||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
location?: string | null;
|
location?: string | null;
|
||||||
|
latitude?: number | null;
|
||||||
|
longitude?: number | null;
|
||||||
|
geofenceRadiusMeters?: number | null;
|
||||||
|
geofenceEnabled?: boolean;
|
||||||
status: "active" | "inactive";
|
status: "active" | "inactive";
|
||||||
adminUserId: string;
|
adminUserId: string;
|
||||||
createdAt?: number;
|
createdAt?: number;
|
||||||
@ -71,6 +76,11 @@ export default function SettingsPage() {
|
|||||||
const [gymStats, setGymStats] = useState<GymStats | null>(null);
|
const [gymStats, setGymStats] = useState<GymStats | null>(null);
|
||||||
const [statsLoading, setStatsLoading] = useState(false);
|
const [statsLoading, setStatsLoading] = useState(false);
|
||||||
const [deletingGym, setDeletingGym] = useState(false);
|
const [deletingGym, setDeletingGym] = useState(false);
|
||||||
|
const [savingGeofence, setSavingGeofence] = useState(false);
|
||||||
|
const [geofenceLatitude, setGeofenceLatitude] = useState("");
|
||||||
|
const [geofenceLongitude, setGeofenceLongitude] = useState("");
|
||||||
|
const [geofenceRadiusMeters, setGeofenceRadiusMeters] = useState("30");
|
||||||
|
const [geofenceEnabled, setGeofenceEnabled] = useState(true);
|
||||||
|
|
||||||
// Create Gym modal state
|
// Create Gym modal state
|
||||||
const [showCreateGym, setShowCreateGym] = useState(false);
|
const [showCreateGym, setShowCreateGym] = useState(false);
|
||||||
@ -185,6 +195,87 @@ export default function SettingsPage() {
|
|||||||
const handleSelectGym = async (gym: Gym | null) => {
|
const handleSelectGym = async (gym: Gym | null) => {
|
||||||
setSelectedGym(gym);
|
setSelectedGym(gym);
|
||||||
setGymStats(null);
|
setGymStats(null);
|
||||||
|
|
||||||
|
if (gym) {
|
||||||
|
setGeofenceLatitude(
|
||||||
|
gym.latitude !== null && gym.latitude !== undefined
|
||||||
|
? String(gym.latitude)
|
||||||
|
: "",
|
||||||
|
);
|
||||||
|
setGeofenceLongitude(
|
||||||
|
gym.longitude !== null && gym.longitude !== undefined
|
||||||
|
? String(gym.longitude)
|
||||||
|
: "",
|
||||||
|
);
|
||||||
|
setGeofenceRadiusMeters(String(gym.geofenceRadiusMeters ?? 30));
|
||||||
|
setGeofenceEnabled(gym.geofenceEnabled ?? true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSaveGeofence = async () => {
|
||||||
|
if (!selectedGym) return;
|
||||||
|
|
||||||
|
const latitude =
|
||||||
|
geofenceLatitude.trim() === "" ? null : Number(geofenceLatitude);
|
||||||
|
const longitude =
|
||||||
|
geofenceLongitude.trim() === "" ? null : Number(geofenceLongitude);
|
||||||
|
const radius = Number(geofenceRadiusMeters);
|
||||||
|
|
||||||
|
if (
|
||||||
|
latitude !== null &&
|
||||||
|
(!Number.isFinite(latitude) || latitude < -90 || latitude > 90)
|
||||||
|
) {
|
||||||
|
setGymMessage({
|
||||||
|
type: "error",
|
||||||
|
text: "Latitude must be between -90 and 90",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
longitude !== null &&
|
||||||
|
(!Number.isFinite(longitude) || longitude < -180 || longitude > 180)
|
||||||
|
) {
|
||||||
|
setGymMessage({
|
||||||
|
type: "error",
|
||||||
|
text: "Longitude must be between -180 and 180",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Number.isFinite(radius) || radius <= 0) {
|
||||||
|
setGymMessage({
|
||||||
|
type: "error",
|
||||||
|
text: "Radius must be a positive number",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setSavingGeofence(true);
|
||||||
|
setGymMessage(null);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.patch(`/api/gyms/${selectedGym.id}`, {
|
||||||
|
latitude,
|
||||||
|
longitude,
|
||||||
|
geofenceRadiusMeters: radius,
|
||||||
|
geofenceEnabled,
|
||||||
|
});
|
||||||
|
setGymMessage({ type: "success", text: "Geofence settings updated" });
|
||||||
|
const updatedGym = response.data as Gym;
|
||||||
|
setSelectedGym(updatedGym);
|
||||||
|
setGyms((prev) =>
|
||||||
|
prev.map((gym) => (gym.id === updatedGym.id ? updatedGym : gym)),
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
log.error("Failed to update geofence settings", error);
|
||||||
|
setGymMessage({
|
||||||
|
type: "error",
|
||||||
|
text: "Failed to update geofence settings",
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
setSavingGeofence(false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDeleteGym = async (gymId: string) => {
|
const handleDeleteGym = async (gymId: string) => {
|
||||||
@ -474,6 +565,91 @@ export default function SettingsPage() {
|
|||||||
{selectedGym.status}
|
{selectedGym.status}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="text-xs text-slate-500">Geofence</p>
|
||||||
|
<p className="font-medium">
|
||||||
|
{selectedGym.geofenceEnabled === false
|
||||||
|
? "Disabled"
|
||||||
|
: `${selectedGym.geofenceRadiusMeters ?? 30}m`}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Geofence Settings */}
|
||||||
|
<div className="p-4 border rounded-lg space-y-3">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<h5 className="text-sm font-medium text-slate-700">
|
||||||
|
Attendance Geofence
|
||||||
|
</h5>
|
||||||
|
<label className="inline-flex items-center gap-2 text-sm text-slate-700">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={geofenceEnabled}
|
||||||
|
onChange={(e) => setGeofenceEnabled(e.target.checked)}
|
||||||
|
/>
|
||||||
|
Enabled
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-3">
|
||||||
|
<div>
|
||||||
|
<label className="block text-xs text-slate-500 mb-1">
|
||||||
|
Latitude
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
step="any"
|
||||||
|
value={geofenceLatitude}
|
||||||
|
onChange={(e) => setGeofenceLatitude(e.target.value)}
|
||||||
|
className="w-full border border-gray-300 rounded px-3 py-2"
|
||||||
|
placeholder="e.g. 37.7749"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className="block text-xs text-slate-500 mb-1">
|
||||||
|
Longitude
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
step="any"
|
||||||
|
value={geofenceLongitude}
|
||||||
|
onChange={(e) => setGeofenceLongitude(e.target.value)}
|
||||||
|
className="w-full border border-gray-300 rounded px-3 py-2"
|
||||||
|
placeholder="e.g. -122.4194"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className="block text-xs text-slate-500 mb-1">
|
||||||
|
Radius (meters)
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
min="1"
|
||||||
|
value={geofenceRadiusMeters}
|
||||||
|
onChange={(e) =>
|
||||||
|
setGeofenceRadiusMeters(e.target.value)
|
||||||
|
}
|
||||||
|
className="w-full border border-gray-300 rounded px-3 py-2"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<p className="text-xs text-slate-500">
|
||||||
|
Default radius is 30m and geofence is enabled by default.
|
||||||
|
</p>
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
onClick={handleSaveGeofence}
|
||||||
|
disabled={savingGeofence}
|
||||||
|
>
|
||||||
|
{savingGeofence ? (
|
||||||
|
<Loader2 className="w-4 h-4 animate-spin" />
|
||||||
|
) : (
|
||||||
|
"Save Geofence"
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Stats */}
|
{/* Stats */}
|
||||||
@ -558,6 +734,109 @@ export default function SettingsPage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Membership Feature Access */}
|
||||||
|
<div className="mt-6">
|
||||||
|
<h5 className="text-sm font-medium text-slate-700 mb-2">
|
||||||
|
Membership Feature Access
|
||||||
|
</h5>
|
||||||
|
<div className="overflow-x-auto border rounded-lg">
|
||||||
|
<table className="w-full text-left text-sm">
|
||||||
|
<thead className="bg-slate-50 border-b">
|
||||||
|
<tr>
|
||||||
|
<th className="px-4 py-3 font-semibold text-slate-900">
|
||||||
|
Feature
|
||||||
|
</th>
|
||||||
|
<th className="px-4 py-3 font-semibold text-slate-900">
|
||||||
|
Basic
|
||||||
|
</th>
|
||||||
|
<th className="px-4 py-3 font-semibold text-slate-900">
|
||||||
|
Premium
|
||||||
|
</th>
|
||||||
|
<th className="px-4 py-3 font-semibold text-slate-900">
|
||||||
|
VIP
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody className="divide-y">
|
||||||
|
<tr>
|
||||||
|
<td className="px-4 py-3 text-slate-700">
|
||||||
|
Recommendations per month
|
||||||
|
</td>
|
||||||
|
<td className="px-4 py-3 text-slate-700">
|
||||||
|
{MEMBERSHIP_FEATURES.basic.recommendationsPerMonth}
|
||||||
|
</td>
|
||||||
|
<td className="px-4 py-3 text-slate-700">
|
||||||
|
Unlimited
|
||||||
|
</td>
|
||||||
|
<td className="px-4 py-3 text-slate-700">
|
||||||
|
Unlimited
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td className="px-4 py-3 text-slate-700">
|
||||||
|
Nutrition tracking
|
||||||
|
</td>
|
||||||
|
<td className="px-4 py-3 text-slate-700">
|
||||||
|
{MEMBERSHIP_FEATURES.basic.nutritionTracking
|
||||||
|
? "Yes"
|
||||||
|
: "No"}
|
||||||
|
</td>
|
||||||
|
<td className="px-4 py-3 text-slate-700">
|
||||||
|
{MEMBERSHIP_FEATURES.premium.nutritionTracking
|
||||||
|
? "Yes"
|
||||||
|
: "No"}
|
||||||
|
</td>
|
||||||
|
<td className="px-4 py-3 text-slate-700">
|
||||||
|
{MEMBERSHIP_FEATURES.vip.nutritionTracking
|
||||||
|
? "Yes"
|
||||||
|
: "No"}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td className="px-4 py-3 text-slate-700">
|
||||||
|
Hydration tracking
|
||||||
|
</td>
|
||||||
|
<td className="px-4 py-3 text-slate-700">
|
||||||
|
{MEMBERSHIP_FEATURES.basic.hydrationTracking
|
||||||
|
? "Yes"
|
||||||
|
: "No"}
|
||||||
|
</td>
|
||||||
|
<td className="px-4 py-3 text-slate-700">
|
||||||
|
{MEMBERSHIP_FEATURES.premium.hydrationTracking
|
||||||
|
? "Yes"
|
||||||
|
: "No"}
|
||||||
|
</td>
|
||||||
|
<td className="px-4 py-3 text-slate-700">
|
||||||
|
{MEMBERSHIP_FEATURES.vip.hydrationTracking
|
||||||
|
? "Yes"
|
||||||
|
: "No"}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td className="px-4 py-3 text-slate-700">
|
||||||
|
Advanced statistics
|
||||||
|
</td>
|
||||||
|
<td className="px-4 py-3 text-slate-700">
|
||||||
|
{MEMBERSHIP_FEATURES.basic.advancedStatistics
|
||||||
|
? "Yes"
|
||||||
|
: "No"}
|
||||||
|
</td>
|
||||||
|
<td className="px-4 py-3 text-slate-700">
|
||||||
|
{MEMBERSHIP_FEATURES.premium.advancedStatistics
|
||||||
|
? "Yes"
|
||||||
|
: "No"}
|
||||||
|
</td>
|
||||||
|
<td className="px-4 py-3 text-slate-700">
|
||||||
|
{MEMBERSHIP_FEATURES.vip.advancedStatistics
|
||||||
|
? "Yes"
|
||||||
|
: "No"}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex items-center justify-center h-64 bg-slate-50 rounded-lg">
|
<div className="flex items-center justify-center h-64 bg-slate-50 rounded-lg">
|
||||||
|
|||||||
@ -1,11 +1,7 @@
|
|||||||
import { clerkClient } from "@clerk/nextjs/server";
|
import { clerkClient } from "@clerk/nextjs/server";
|
||||||
|
import { type UserRole } from "@fitai/shared";
|
||||||
import log from "./logger";
|
import log from "./logger";
|
||||||
|
|
||||||
/**
|
|
||||||
* User roles available in the application
|
|
||||||
*/
|
|
||||||
export type UserRole = "admin" | "trainer" | "client";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a user's role in Clerk public metadata
|
* Set a user's role in Clerk public metadata
|
||||||
* This will trigger a webhook that syncs the role to the database
|
* This will trigger a webhook that syncs the role to the database
|
||||||
@ -71,7 +67,8 @@ export async function hasRole(
|
|||||||
* const isAdmin = await isAdmin('user_abc123');
|
* const isAdmin = await isAdmin('user_abc123');
|
||||||
*/
|
*/
|
||||||
export async function isAdmin(userId: string): Promise<boolean> {
|
export async function isAdmin(userId: string): Promise<boolean> {
|
||||||
return hasRole(userId, "admin");
|
const role = await getUserRole(userId);
|
||||||
|
return role === "admin" || role === "superAdmin";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -161,6 +158,7 @@ export async function getUserCountByRole(): Promise<Record<UserRole, number>> {
|
|||||||
const { data: users } = await client.users.getUserList();
|
const { data: users } = await client.users.getUserList();
|
||||||
|
|
||||||
const counts: Record<UserRole, number> = {
|
const counts: Record<UserRole, number> = {
|
||||||
|
superAdmin: 0,
|
||||||
admin: 0,
|
admin: 0,
|
||||||
trainer: 0,
|
trainer: 0,
|
||||||
client: 0,
|
client: 0,
|
||||||
|
|||||||
@ -154,6 +154,7 @@ export interface IDatabase {
|
|||||||
getRecommendationsByUserId(userId: string): Promise<Recommendation[]>;
|
getRecommendationsByUserId(userId: string): Promise<Recommendation[]>;
|
||||||
getRecommendationsByUserIds(userIds: string[]): Promise<Recommendation[]>;
|
getRecommendationsByUserIds(userIds: string[]): Promise<Recommendation[]>;
|
||||||
getAllRecommendations(): Promise<Recommendation[]>;
|
getAllRecommendations(): Promise<Recommendation[]>;
|
||||||
|
getRecommendationById(id: string): Promise<Recommendation | null>;
|
||||||
updateRecommendation(
|
updateRecommendation(
|
||||||
id: string,
|
id: string,
|
||||||
updates: Partial<Recommendation>,
|
updates: Partial<Recommendation>,
|
||||||
|
|||||||
277
apps/admin/src/lib/geofence.ts
Normal file
277
apps/admin/src/lib/geofence.ts
Normal file
@ -0,0 +1,277 @@
|
|||||||
|
import { db, eq, sql, users } from "@fitai/database";
|
||||||
|
|
||||||
|
export const DEFAULT_GEOFENCE_RADIUS_METERS = 30;
|
||||||
|
export const MAX_LOCATION_ACCURACY_METERS = 50;
|
||||||
|
export const MAX_FALLBACK_ACCURACY_MARGIN_METERS = 120;
|
||||||
|
|
||||||
|
export interface UserLocation {
|
||||||
|
latitude: number;
|
||||||
|
longitude: number;
|
||||||
|
accuracy: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function ensureGymsGeofenceColumns(): Promise<void> {
|
||||||
|
const rows = await db.all(sql`PRAGMA table_info('gyms')`);
|
||||||
|
const columns = new Set(
|
||||||
|
(rows as Array<{ name?: string }>).map((row) => row.name).filter(Boolean),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!columns.has("latitude")) {
|
||||||
|
await db.run(sql`ALTER TABLE gyms ADD COLUMN latitude REAL`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!columns.has("longitude")) {
|
||||||
|
await db.run(sql`ALTER TABLE gyms ADD COLUMN longitude REAL`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!columns.has("geofence_radius_meters")) {
|
||||||
|
await db.run(
|
||||||
|
sql`ALTER TABLE gyms ADD COLUMN geofence_radius_meters REAL NOT NULL DEFAULT 30`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!columns.has("geofence_enabled")) {
|
||||||
|
await db.run(
|
||||||
|
sql`ALTER TABLE gyms ADD COLUMN geofence_enabled INTEGER NOT NULL DEFAULT 1`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface GymGeofenceConfig {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
latitude: number | null;
|
||||||
|
longitude: number | null;
|
||||||
|
geofenceRadiusMeters: number | null;
|
||||||
|
geofenceEnabled: boolean | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getUserGymGeofence(
|
||||||
|
userId: string,
|
||||||
|
): Promise<GymGeofenceConfig | null> {
|
||||||
|
await ensureGymsGeofenceColumns();
|
||||||
|
|
||||||
|
const user = await db.select().from(users).where(eq(users.id, userId)).get();
|
||||||
|
if (!user?.gymId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rows = await db.all(sql`
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
latitude,
|
||||||
|
longitude,
|
||||||
|
geofence_radius_meters as geofenceRadiusMeters,
|
||||||
|
geofence_enabled as geofenceEnabled
|
||||||
|
FROM gyms
|
||||||
|
WHERE id = ${user.gymId}
|
||||||
|
LIMIT 1
|
||||||
|
`);
|
||||||
|
const gym = rows?.[0] as
|
||||||
|
| {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
latitude: number | null;
|
||||||
|
longitude: number | null;
|
||||||
|
geofenceRadiusMeters: number | null;
|
||||||
|
geofenceEnabled: number | boolean | null;
|
||||||
|
}
|
||||||
|
| undefined;
|
||||||
|
if (!gym) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: gym.id,
|
||||||
|
name: gym.name,
|
||||||
|
latitude: gym.latitude,
|
||||||
|
longitude: gym.longitude,
|
||||||
|
geofenceRadiusMeters: gym.geofenceRadiusMeters,
|
||||||
|
geofenceEnabled:
|
||||||
|
typeof gym.geofenceEnabled === "boolean"
|
||||||
|
? gym.geofenceEnabled
|
||||||
|
: gym.geofenceEnabled === null
|
||||||
|
? null
|
||||||
|
: Boolean(gym.geofenceEnabled),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseUserLocation(payload: unknown): UserLocation | null {
|
||||||
|
if (!payload || typeof payload !== "object") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const raw = payload as Record<string, unknown>;
|
||||||
|
const latitude = Number(raw.latitude);
|
||||||
|
const longitude = Number(raw.longitude);
|
||||||
|
const accuracy = Number(raw.accuracy);
|
||||||
|
|
||||||
|
if (
|
||||||
|
!Number.isFinite(latitude) ||
|
||||||
|
!Number.isFinite(longitude) ||
|
||||||
|
!Number.isFinite(accuracy)
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { latitude, longitude, accuracy };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function validateGeofence(
|
||||||
|
gym: GymGeofenceConfig,
|
||||||
|
location: UserLocation | null,
|
||||||
|
): { ok: true } | { ok: false; status: number; error: string } {
|
||||||
|
const geofenceEnabled = gym.geofenceEnabled ?? true;
|
||||||
|
if (!geofenceEnabled) {
|
||||||
|
return { ok: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!location) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
status: 400,
|
||||||
|
error: "Location is required for gym check-in/check-out",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (location.accuracy > MAX_LOCATION_ACCURACY_METERS) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
status: 400,
|
||||||
|
error: `Location accuracy too low (${Math.round(location.accuracy)}m). Move to an open area and try again.`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gym.latitude === null || gym.longitude === null) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
status: 400,
|
||||||
|
error: "Gym geofence is enabled but gym coordinates are not configured",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const radius = gym.geofenceRadiusMeters ?? DEFAULT_GEOFENCE_RADIUS_METERS;
|
||||||
|
const distanceMeters = haversineDistanceMeters(
|
||||||
|
gym.latitude,
|
||||||
|
gym.longitude,
|
||||||
|
location.latitude,
|
||||||
|
location.longitude,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (distanceMeters > radius) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
status: 403,
|
||||||
|
error: `You are outside the gym geofence (${Math.round(distanceMeters)}m away, allowed ${Math.round(radius)}m).`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return { ok: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function validateGeofenceWithFallback(
|
||||||
|
gym: GymGeofenceConfig,
|
||||||
|
location: UserLocation | null,
|
||||||
|
fallbackRequested: boolean,
|
||||||
|
): { ok: true } | { ok: false; status: number; error: string } {
|
||||||
|
const geofenceEnabled = gym.geofenceEnabled ?? true;
|
||||||
|
if (!geofenceEnabled) {
|
||||||
|
return { ok: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!location) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
status: 400,
|
||||||
|
error: "Location is required for gym check-in/check-out",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gym.latitude === null || gym.longitude === null) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
status: 400,
|
||||||
|
error: "Gym geofence is enabled but gym coordinates are not configured",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const radius = gym.geofenceRadiusMeters ?? DEFAULT_GEOFENCE_RADIUS_METERS;
|
||||||
|
const distanceMeters = haversineDistanceMeters(
|
||||||
|
gym.latitude,
|
||||||
|
gym.longitude,
|
||||||
|
location.latitude,
|
||||||
|
location.longitude,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (location.accuracy <= MAX_LOCATION_ACCURACY_METERS) {
|
||||||
|
if (distanceMeters > radius) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
status: 403,
|
||||||
|
error: `You are outside the gym geofence (${Math.round(distanceMeters)}m away, allowed ${Math.round(radius)}m).`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return { ok: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fallbackRequested) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
status: 400,
|
||||||
|
error: `Location accuracy too low (${Math.round(location.accuracy)}m). Move to an open area and try again.`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const fallbackMargin = Math.min(
|
||||||
|
location.accuracy,
|
||||||
|
MAX_FALLBACK_ACCURACY_MARGIN_METERS,
|
||||||
|
);
|
||||||
|
const fallbackAllowedDistance = radius + fallbackMargin;
|
||||||
|
|
||||||
|
if (distanceMeters > fallbackAllowedDistance) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
status: 403,
|
||||||
|
error: `You are outside the gym geofence (${Math.round(distanceMeters)}m away, fallback allowed ${Math.round(fallbackAllowedDistance)}m).`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return { ok: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function validateCheckInGeofence(
|
||||||
|
gym: GymGeofenceConfig,
|
||||||
|
location: UserLocation | null,
|
||||||
|
fallbackRequested: boolean,
|
||||||
|
): { ok: true } | { ok: false; status: number; error: string } {
|
||||||
|
return validateGeofenceWithFallback(gym, location, fallbackRequested);
|
||||||
|
}
|
||||||
|
|
||||||
|
function haversineDistanceMeters(
|
||||||
|
latitude1: number,
|
||||||
|
longitude1: number,
|
||||||
|
latitude2: number,
|
||||||
|
longitude2: number,
|
||||||
|
): number {
|
||||||
|
const earthRadiusMeters = 6371000;
|
||||||
|
const dLat = toRadians(latitude2 - latitude1);
|
||||||
|
const dLng = toRadians(longitude2 - longitude1);
|
||||||
|
const lat1Rad = toRadians(latitude1);
|
||||||
|
const lat2Rad = toRadians(latitude2);
|
||||||
|
|
||||||
|
const a =
|
||||||
|
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
|
||||||
|
Math.sin(dLng / 2) *
|
||||||
|
Math.sin(dLng / 2) *
|
||||||
|
Math.cos(lat1Rad) *
|
||||||
|
Math.cos(lat2Rad);
|
||||||
|
|
||||||
|
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
||||||
|
return earthRadiusMeters * c;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toRadians(degrees: number): number {
|
||||||
|
return (degrees * Math.PI) / 180;
|
||||||
|
}
|
||||||
26
apps/admin/src/lib/membership/access.ts
Normal file
26
apps/admin/src/lib/membership/access.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { getDatabase } from "@/lib/database";
|
||||||
|
import { getMembershipFeatures } from "./features";
|
||||||
|
|
||||||
|
export async function getUserMembershipContext(userId: string): Promise<{
|
||||||
|
membershipType: "basic" | "premium" | "vip";
|
||||||
|
features: ReturnType<typeof getMembershipFeatures>;
|
||||||
|
}> {
|
||||||
|
const db = await getDatabase();
|
||||||
|
const user = await db.getUserById(userId);
|
||||||
|
|
||||||
|
if (!user || user.role !== "client") {
|
||||||
|
const membershipType = "vip" as const;
|
||||||
|
return {
|
||||||
|
membershipType,
|
||||||
|
features: getMembershipFeatures(membershipType),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const client = await db.getClientByUserId(userId);
|
||||||
|
const membershipType = client?.membershipType ?? "basic";
|
||||||
|
|
||||||
|
return {
|
||||||
|
membershipType,
|
||||||
|
features: getMembershipFeatures(membershipType),
|
||||||
|
};
|
||||||
|
}
|
||||||
35
apps/admin/src/lib/membership/features.ts
Normal file
35
apps/admin/src/lib/membership/features.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import type { MembershipType } from "@/lib/validation/schemas";
|
||||||
|
|
||||||
|
export interface MembershipFeatures {
|
||||||
|
recommendationsPerMonth: number;
|
||||||
|
hydrationTracking: boolean;
|
||||||
|
nutritionTracking: boolean;
|
||||||
|
advancedStatistics: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const MEMBERSHIP_FEATURES: Record<MembershipType, MembershipFeatures> = {
|
||||||
|
basic: {
|
||||||
|
recommendationsPerMonth: 1,
|
||||||
|
hydrationTracking: false,
|
||||||
|
nutritionTracking: false,
|
||||||
|
advancedStatistics: false,
|
||||||
|
},
|
||||||
|
premium: {
|
||||||
|
recommendationsPerMonth: -1,
|
||||||
|
hydrationTracking: true,
|
||||||
|
nutritionTracking: true,
|
||||||
|
advancedStatistics: true,
|
||||||
|
},
|
||||||
|
vip: {
|
||||||
|
recommendationsPerMonth: -1,
|
||||||
|
hydrationTracking: true,
|
||||||
|
nutritionTracking: true,
|
||||||
|
advancedStatistics: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export function getMembershipFeatures(
|
||||||
|
membershipType: MembershipType,
|
||||||
|
): MembershipFeatures {
|
||||||
|
return MEMBERSHIP_FEATURES[membershipType];
|
||||||
|
}
|
||||||
@ -25,14 +25,6 @@ const isPublicRoute = createRouteMatcher([
|
|||||||
const isApiRoute = createRouteMatcher(["/api/(.*)"]);
|
const isApiRoute = createRouteMatcher(["/api/(.*)"]);
|
||||||
|
|
||||||
export default clerkMiddleware(async (auth, req) => {
|
export default clerkMiddleware(async (auth, req) => {
|
||||||
// Log for debugging
|
|
||||||
const authHeader = req.headers.get("authorization");
|
|
||||||
if (authHeader) {
|
|
||||||
log.debug("Authorization header present", {
|
|
||||||
preview: authHeader.substring(0, 20) + "...",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't protect public routes
|
// Don't protect public routes
|
||||||
if (isPublicRoute(req)) {
|
if (isPublicRoute(req)) {
|
||||||
log.debug("Public route, skipping auth");
|
log.debug("Public route, skipping auth");
|
||||||
@ -42,7 +34,6 @@ export default clerkMiddleware(async (auth, req) => {
|
|||||||
// For API routes, let the route handler check auth
|
// For API routes, let the route handler check auth
|
||||||
// This allows API routes to handle both web sessions and mobile Bearer tokens
|
// This allows API routes to handle both web sessions and mobile Bearer tokens
|
||||||
if (isApiRoute(req)) {
|
if (isApiRoute(req)) {
|
||||||
log.debug("API route, auth will be checked in handler");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,31 +0,0 @@
|
|||||||
# Values used to calculate the hash in this folder name.
|
|
||||||
# Should not depend on the absolute path of the project itself.
|
|
||||||
# - AGP: 8.11.0.
|
|
||||||
# - $NDK is the path to NDK 27.1.12297006.
|
|
||||||
# - $PROJECT is the path to the parent folder of the root Gradle build file.
|
|
||||||
# - $ABI is the ABI to be built with. The specific value doesn't contribute to the value of the hash.
|
|
||||||
# - $HASH is the hash value computed from this text.
|
|
||||||
# - $CMAKE is the path to CMake 3.22.1.
|
|
||||||
# - $NINJA is the path to Ninja.
|
|
||||||
-H/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/default-app-setup
|
|
||||||
-DCMAKE_SYSTEM_NAME=Android
|
|
||||||
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
|
|
||||||
-DCMAKE_SYSTEM_VERSION=26
|
|
||||||
-DANDROID_PLATFORM=android-26
|
|
||||||
-DANDROID_ABI=$ABI
|
|
||||||
-DCMAKE_ANDROID_ARCH_ABI=$ABI
|
|
||||||
-DANDROID_NDK=$NDK
|
|
||||||
-DCMAKE_ANDROID_NDK=$NDK
|
|
||||||
-DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake
|
|
||||||
-DCMAKE_MAKE_PROGRAM=$NINJA
|
|
||||||
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=$PROJECT/app/build/intermediates/cxx/Debug/$HASH/obj/$ABI
|
|
||||||
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=$PROJECT/app/build/intermediates/cxx/Debug/$HASH/obj/$ABI
|
|
||||||
-DCMAKE_BUILD_TYPE=Debug
|
|
||||||
-DCMAKE_FIND_ROOT_PATH=$PROJECT/app/.cxx/Debug/$HASH/prefab/$ABI/prefab
|
|
||||||
-B$PROJECT/app/.cxx/Debug/$HASH/$ABI
|
|
||||||
-GNinja
|
|
||||||
-DPROJECT_BUILD_DIR=$PROJECT/app/build
|
|
||||||
-DPROJECT_ROOT_DIR=$PROJECT
|
|
||||||
-DREACT_ANDROID_DIR=/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid
|
|
||||||
-DANDROID_STL=c++_shared
|
|
||||||
-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
if(NOT TARGET ReactAndroid::hermestooling)
|
|
||||||
add_library(ReactAndroid::hermestooling SHARED IMPORTED)
|
|
||||||
set_target_properties(ReactAndroid::hermestooling PROPERTIES
|
|
||||||
IMPORTED_LOCATION "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/hermestooling/libs/android.x86/libhermestooling.so"
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/hermestooling/include"
|
|
||||||
INTERFACE_LINK_LIBRARIES ""
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT TARGET ReactAndroid::jsi)
|
|
||||||
add_library(ReactAndroid::jsi SHARED IMPORTED)
|
|
||||||
set_target_properties(ReactAndroid::jsi PROPERTIES
|
|
||||||
IMPORTED_LOCATION "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/jsi/libs/android.x86/libjsi.so"
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/jsi/include"
|
|
||||||
INTERFACE_LINK_LIBRARIES ""
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT TARGET ReactAndroid::reactnative)
|
|
||||||
add_library(ReactAndroid::reactnative SHARED IMPORTED)
|
|
||||||
set_target_properties(ReactAndroid::reactnative PROPERTIES
|
|
||||||
IMPORTED_LOCATION "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/reactnative/libs/android.x86/libreactnative.so"
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/reactnative/include"
|
|
||||||
INTERFACE_LINK_LIBRARIES ""
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
set(PACKAGE_VERSION 0.81.5)
|
|
||||||
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
|
|
||||||
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
|
||||||
else()
|
|
||||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
|
||||||
if("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
|
|
||||||
set(PACKAGE_VERSION_EXACT TRUE)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
if(NOT TARGET fbjni::fbjni)
|
|
||||||
add_library(fbjni::fbjni SHARED IMPORTED)
|
|
||||||
set_target_properties(fbjni::fbjni PROPERTIES
|
|
||||||
IMPORTED_LOCATION "/home/echo/.gradle/caches/8.14.3/transforms/488fe6e480efb97ec75859f6e274282f/transformed/fbjni-0.7.0/prefab/modules/fbjni/libs/android.x86/libfbjni.so"
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "/home/echo/.gradle/caches/8.14.3/transforms/488fe6e480efb97ec75859f6e274282f/transformed/fbjni-0.7.0/prefab/modules/fbjni/include"
|
|
||||||
INTERFACE_LINK_LIBRARIES ""
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
set(PACKAGE_VERSION 3.22.1)
|
|
||||||
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
|
|
||||||
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
|
||||||
else()
|
|
||||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
|
||||||
if("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
|
|
||||||
set(PACKAGE_VERSION_EXACT TRUE)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
if(NOT TARGET hermes-engine::libhermes)
|
|
||||||
add_library(hermes-engine::libhermes SHARED IMPORTED)
|
|
||||||
set_target_properties(hermes-engine::libhermes PROPERTIES
|
|
||||||
IMPORTED_LOCATION "/home/echo/.gradle/caches/8.14.3/transforms/f3d279cf13499f4c93e2b512ac9499e6/transformed/hermes-android-0.81.5-debug/prefab/modules/libhermes/libs/android.x86/libhermes.so"
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "/home/echo/.gradle/caches/8.14.3/transforms/f3d279cf13499f4c93e2b512ac9499e6/transformed/hermes-android-0.81.5-debug/prefab/modules/libhermes/include"
|
|
||||||
INTERFACE_LINK_LIBRARIES ""
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
set(PACKAGE_VERSION 0.81.5)
|
|
||||||
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
|
|
||||||
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
|
||||||
else()
|
|
||||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
|
||||||
if("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
|
|
||||||
set(PACKAGE_VERSION_EXACT TRUE)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
if(NOT TARGET ReactAndroid::hermestooling)
|
|
||||||
add_library(ReactAndroid::hermestooling SHARED IMPORTED)
|
|
||||||
set_target_properties(ReactAndroid::hermestooling PROPERTIES
|
|
||||||
IMPORTED_LOCATION "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/hermestooling/libs/android.x86_64/libhermestooling.so"
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/hermestooling/include"
|
|
||||||
INTERFACE_LINK_LIBRARIES ""
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT TARGET ReactAndroid::jsi)
|
|
||||||
add_library(ReactAndroid::jsi SHARED IMPORTED)
|
|
||||||
set_target_properties(ReactAndroid::jsi PROPERTIES
|
|
||||||
IMPORTED_LOCATION "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/jsi/libs/android.x86_64/libjsi.so"
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/jsi/include"
|
|
||||||
INTERFACE_LINK_LIBRARIES ""
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT TARGET ReactAndroid::reactnative)
|
|
||||||
add_library(ReactAndroid::reactnative SHARED IMPORTED)
|
|
||||||
set_target_properties(ReactAndroid::reactnative PROPERTIES
|
|
||||||
IMPORTED_LOCATION "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/reactnative/libs/android.x86_64/libreactnative.so"
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/reactnative/include"
|
|
||||||
INTERFACE_LINK_LIBRARIES ""
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
set(PACKAGE_VERSION 0.81.5)
|
|
||||||
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
|
|
||||||
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
|
||||||
else()
|
|
||||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
|
||||||
if("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
|
|
||||||
set(PACKAGE_VERSION_EXACT TRUE)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
if(NOT TARGET fbjni::fbjni)
|
|
||||||
add_library(fbjni::fbjni SHARED IMPORTED)
|
|
||||||
set_target_properties(fbjni::fbjni PROPERTIES
|
|
||||||
IMPORTED_LOCATION "/home/echo/.gradle/caches/8.14.3/transforms/488fe6e480efb97ec75859f6e274282f/transformed/fbjni-0.7.0/prefab/modules/fbjni/libs/android.x86_64/libfbjni.so"
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "/home/echo/.gradle/caches/8.14.3/transforms/488fe6e480efb97ec75859f6e274282f/transformed/fbjni-0.7.0/prefab/modules/fbjni/include"
|
|
||||||
INTERFACE_LINK_LIBRARIES ""
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
set(PACKAGE_VERSION 3.22.1)
|
|
||||||
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
|
|
||||||
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
|
||||||
else()
|
|
||||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
|
||||||
if("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
|
|
||||||
set(PACKAGE_VERSION_EXACT TRUE)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
if(NOT TARGET hermes-engine::libhermes)
|
|
||||||
add_library(hermes-engine::libhermes SHARED IMPORTED)
|
|
||||||
set_target_properties(hermes-engine::libhermes PROPERTIES
|
|
||||||
IMPORTED_LOCATION "/home/echo/.gradle/caches/8.14.3/transforms/f3d279cf13499f4c93e2b512ac9499e6/transformed/hermes-android-0.81.5-debug/prefab/modules/libhermes/libs/android.x86_64/libhermes.so"
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "/home/echo/.gradle/caches/8.14.3/transforms/f3d279cf13499f4c93e2b512ac9499e6/transformed/hermes-android-0.81.5-debug/prefab/modules/libhermes/include"
|
|
||||||
INTERFACE_LINK_LIBRARIES ""
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
set(PACKAGE_VERSION 0.81.5)
|
|
||||||
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
|
|
||||||
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
|
||||||
else()
|
|
||||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
|
||||||
if("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
|
|
||||||
set(PACKAGE_VERSION_EXACT TRUE)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,851 +0,0 @@
|
|||||||
{
|
|
||||||
"inputs" :
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"path" : "CMakeLists.txt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeDetermineSystem.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/android.toolchain.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/android-legacy.toolchain.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/abis.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/platforms.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android-Determine.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/hooks/pre/Android-Determine.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeSystem.cmake.in"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isGenerated" : true,
|
|
||||||
"path" : "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/3.22.1-g37088a8/CMakeSystem.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/android.toolchain.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeSystemSpecificInitialize.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android-Initialize.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/hooks/pre/Android-Initialize.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeDetermineCCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeDetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android-Determine-C.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android/Determine-Compiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/hooks/pre/Determine-Compiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeDetermineCompilerId.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCompilerIdDetection.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/ADSP-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/ARMCC-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/ARMClang-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/AppleClang-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang-DetermineCompilerInternal.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Borland-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Bruce-C-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang-DetermineCompilerInternal.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Compaq-C-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Cray-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Embarcadero-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Fujitsu-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/FujitsuClang-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/GHS-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/GNU-C-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/HP-C-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/IAR-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Intel-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/IntelLLVM-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/MSVC-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/NVHPC-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/NVIDIA-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/OpenWatcom-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/PGI-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/PathScale-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/SCO-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/SDCC-C-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/SunPro-C-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/TI-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/TinyCC-C-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/VisualAge-C-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/IBMCPP-C-DetermineVersionInternal.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Watcom-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/XL-C-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/IBMCPP-C-DetermineVersionInternal.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/XLClang-C-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/zOS-C-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/IBMCPP-C-DetermineVersionInternal.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeFindBinUtils.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang-FindBinUtils.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCCompiler.cmake.in"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isGenerated" : true,
|
|
||||||
"path" : "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/3.22.1-g37088a8/CMakeCCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeDetermineCXXCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeDetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android-Determine-CXX.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android/Determine-Compiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeDetermineCompilerId.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCompilerIdDetection.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/ADSP-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/ARMCC-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/ARMClang-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/AppleClang-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang-DetermineCompilerInternal.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Borland-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang-DetermineCompilerInternal.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Comeau-CXX-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Compaq-CXX-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Cray-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Embarcadero-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Fujitsu-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/FujitsuClang-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/GHS-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/GNU-CXX-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/HP-CXX-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/IAR-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Intel-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/IntelLLVM-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/MSVC-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/NVHPC-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/NVIDIA-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/OpenWatcom-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/PGI-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/PathScale-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/SCO-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/SunPro-CXX-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/TI-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/VisualAge-CXX-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/IBMCPP-CXX-DetermineVersionInternal.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Watcom-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/XL-CXX-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/IBMCPP-CXX-DetermineVersionInternal.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/XLClang-CXX-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/zOS-CXX-DetermineCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/IBMCPP-CXX-DetermineVersionInternal.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeFindBinUtils.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang-FindBinUtils.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCXXCompiler.cmake.in"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isGenerated" : true,
|
|
||||||
"path" : "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/3.22.1-g37088a8/CMakeCXXCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeSystemSpecificInformation.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeGenericSystem.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeInitializeConfigs.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/hooks/pre/Android.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Linux.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/UnixPaths.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCInformation.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeLanguageInformation.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang-C.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/CMakeCommonCompilerMacros.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/GNU.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/CMakeCommonCompilerMacros.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android-Clang-C.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android-Clang.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/hooks/pre/Android-Clang.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/flags.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCommonLanguageInclude.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeTestCCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeTestCompilerCommon.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeDetermineCompilerABI.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeParseImplicitIncludeInfo.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeParseImplicitLinkInfo.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeParseLibraryArchitecture.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeTestCompilerCommon.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCCompilerABI.c"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeDetermineCompileFeatures.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Internal/FeatureTesting.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCCompiler.cmake.in"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isGenerated" : true,
|
|
||||||
"path" : "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/3.22.1-g37088a8/CMakeCCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCXXInformation.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeLanguageInformation.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang-CXX.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android-Clang-CXX.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android-Clang.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCommonLanguageInclude.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeTestCXXCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeTestCompilerCommon.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeDetermineCompilerABI.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeParseImplicitIncludeInfo.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeParseImplicitLinkInfo.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeParseLibraryArchitecture.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeTestCompilerCommon.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCXXCompilerABI.cpp"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeDetermineCompileFeatures.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Internal/FeatureTesting.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCXXCompiler.cmake.in"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isGenerated" : true,
|
|
||||||
"path" : "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/3.22.1-g37088a8/CMakeCXXCompiler.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/folly-flags.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactCommon/cmake-utils/react-native-flags.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CheckIPOSupported.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CheckIPOSupported/CMakeLists-CXX.txt.in"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CheckIPOSupported/foo.cpp"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isCMake" : true,
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CheckIPOSupported/main.cpp"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/prefab/x86/prefab/lib/i686-linux-android/cmake/ReactAndroid/ReactAndroidConfigVersion.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/prefab/x86/prefab/lib/i686-linux-android/cmake/ReactAndroid/ReactAndroidConfig.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/prefab/x86/prefab/lib/i686-linux-android/cmake/fbjni/fbjniConfigVersion.cmake"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"isExternal" : true,
|
|
||||||
"path" : "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/prefab/x86/prefab/lib/i686-linux-android/cmake/fbjni/fbjniConfig.cmake"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"kind" : "cmakeFiles",
|
|
||||||
"paths" :
|
|
||||||
{
|
|
||||||
"build" : "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86",
|
|
||||||
"source" : "/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/default-app-setup"
|
|
||||||
},
|
|
||||||
"version" :
|
|
||||||
{
|
|
||||||
"major" : 1,
|
|
||||||
"minor" : 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
{
|
|
||||||
"configurations" :
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"directories" :
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"build" : ".",
|
|
||||||
"jsonFile" : "directory-.-Debug-f5ebdc15457944623624.json",
|
|
||||||
"minimumCMakeVersion" :
|
|
||||||
{
|
|
||||||
"string" : "3.13"
|
|
||||||
},
|
|
||||||
"projectIndex" : 0,
|
|
||||||
"source" : ".",
|
|
||||||
"targetIndexes" :
|
|
||||||
[
|
|
||||||
0
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name" : "Debug",
|
|
||||||
"projects" :
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"directoryIndexes" :
|
|
||||||
[
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"name" : "appmodules",
|
|
||||||
"targetIndexes" :
|
|
||||||
[
|
|
||||||
0
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"targets" :
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"directoryIndex" : 0,
|
|
||||||
"id" : "appmodules::@6890427a1f51a3e7e1df",
|
|
||||||
"jsonFile" : "target-appmodules-Debug-9ef032710fe355da9383.json",
|
|
||||||
"name" : "appmodules",
|
|
||||||
"projectIndex" : 0
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"kind" : "codemodel",
|
|
||||||
"paths" :
|
|
||||||
{
|
|
||||||
"build" : "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86",
|
|
||||||
"source" : "/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/default-app-setup"
|
|
||||||
},
|
|
||||||
"version" :
|
|
||||||
{
|
|
||||||
"major" : 2,
|
|
||||||
"minor" : 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"backtraceGraph" :
|
|
||||||
{
|
|
||||||
"commands" : [],
|
|
||||||
"files" : [],
|
|
||||||
"nodes" : []
|
|
||||||
},
|
|
||||||
"installers" : [],
|
|
||||||
"paths" :
|
|
||||||
{
|
|
||||||
"build" : ".",
|
|
||||||
"source" : "."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,92 +0,0 @@
|
|||||||
{
|
|
||||||
"cmake" :
|
|
||||||
{
|
|
||||||
"generator" :
|
|
||||||
{
|
|
||||||
"multiConfig" : false,
|
|
||||||
"name" : "Ninja"
|
|
||||||
},
|
|
||||||
"paths" :
|
|
||||||
{
|
|
||||||
"cmake" : "/home/echo/Android/Sdk/cmake/3.22.1/bin/cmake",
|
|
||||||
"cpack" : "/home/echo/Android/Sdk/cmake/3.22.1/bin/cpack",
|
|
||||||
"ctest" : "/home/echo/Android/Sdk/cmake/3.22.1/bin/ctest",
|
|
||||||
"root" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22"
|
|
||||||
},
|
|
||||||
"version" :
|
|
||||||
{
|
|
||||||
"isDirty" : false,
|
|
||||||
"major" : 3,
|
|
||||||
"minor" : 22,
|
|
||||||
"patch" : 1,
|
|
||||||
"string" : "3.22.1-g37088a8",
|
|
||||||
"suffix" : "g37088a8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"objects" :
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"jsonFile" : "codemodel-v2-d483cb7bfe026ad3a64f.json",
|
|
||||||
"kind" : "codemodel",
|
|
||||||
"version" :
|
|
||||||
{
|
|
||||||
"major" : 2,
|
|
||||||
"minor" : 3
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"jsonFile" : "cache-v2-099ee692bdea7ed85643.json",
|
|
||||||
"kind" : "cache",
|
|
||||||
"version" :
|
|
||||||
{
|
|
||||||
"major" : 2,
|
|
||||||
"minor" : 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"jsonFile" : "cmakeFiles-v1-b99aeefcc68e41c89ebf.json",
|
|
||||||
"kind" : "cmakeFiles",
|
|
||||||
"version" :
|
|
||||||
{
|
|
||||||
"major" : 1,
|
|
||||||
"minor" : 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"reply" :
|
|
||||||
{
|
|
||||||
"client-agp" :
|
|
||||||
{
|
|
||||||
"cache-v2" :
|
|
||||||
{
|
|
||||||
"jsonFile" : "cache-v2-099ee692bdea7ed85643.json",
|
|
||||||
"kind" : "cache",
|
|
||||||
"version" :
|
|
||||||
{
|
|
||||||
"major" : 2,
|
|
||||||
"minor" : 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"cmakeFiles-v1" :
|
|
||||||
{
|
|
||||||
"jsonFile" : "cmakeFiles-v1-b99aeefcc68e41c89ebf.json",
|
|
||||||
"kind" : "cmakeFiles",
|
|
||||||
"version" :
|
|
||||||
{
|
|
||||||
"major" : 1,
|
|
||||||
"minor" : 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"codemodel-v2" :
|
|
||||||
{
|
|
||||||
"jsonFile" : "codemodel-v2-d483cb7bfe026ad3a64f.json",
|
|
||||||
"kind" : "codemodel",
|
|
||||||
"version" :
|
|
||||||
{
|
|
||||||
"major" : 2,
|
|
||||||
"minor" : 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,226 +0,0 @@
|
|||||||
{
|
|
||||||
"artifacts" :
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"path" : "/home/echo/dev/prototype/apps/mobile/android/app/build/intermediates/cxx/Debug/2z472e3c/obj/x86/libappmodules.so"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"backtrace" : 3,
|
|
||||||
"backtraceGraph" :
|
|
||||||
{
|
|
||||||
"commands" :
|
|
||||||
[
|
|
||||||
"add_library",
|
|
||||||
"include",
|
|
||||||
"target_link_libraries",
|
|
||||||
"target_compile_options",
|
|
||||||
"target_compile_reactnative_options",
|
|
||||||
"target_compile_definitions",
|
|
||||||
"target_include_directories"
|
|
||||||
],
|
|
||||||
"files" :
|
|
||||||
[
|
|
||||||
"/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake",
|
|
||||||
"CMakeLists.txt",
|
|
||||||
"/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactCommon/cmake-utils/react-native-flags.cmake"
|
|
||||||
],
|
|
||||||
"nodes" :
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"file" : 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"command" : 1,
|
|
||||||
"file" : 1,
|
|
||||||
"line" : 31,
|
|
||||||
"parent" : 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"file" : 0,
|
|
||||||
"parent" : 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"command" : 0,
|
|
||||||
"file" : 0,
|
|
||||||
"line" : 64,
|
|
||||||
"parent" : 2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"command" : 2,
|
|
||||||
"file" : 0,
|
|
||||||
"line" : 81,
|
|
||||||
"parent" : 2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"command" : 4,
|
|
||||||
"file" : 0,
|
|
||||||
"line" : 71,
|
|
||||||
"parent" : 2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"command" : 3,
|
|
||||||
"file" : 2,
|
|
||||||
"line" : 30,
|
|
||||||
"parent" : 5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"command" : 5,
|
|
||||||
"file" : 2,
|
|
||||||
"line" : 33,
|
|
||||||
"parent" : 5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"command" : 6,
|
|
||||||
"file" : 0,
|
|
||||||
"line" : 66,
|
|
||||||
"parent" : 2
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"compileGroups" :
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"compileCommandFragments" :
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"fragment" : "-g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D__BIONIC_NO_PAGE_SIZE_MACRO -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fno-limit-debug-info -fPIC"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"backtrace" : 6,
|
|
||||||
"fragment" : "-Wall"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"backtrace" : 6,
|
|
||||||
"fragment" : "-Werror"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"backtrace" : 6,
|
|
||||||
"fragment" : "-fexceptions"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"backtrace" : 6,
|
|
||||||
"fragment" : "-frtti"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"backtrace" : 6,
|
|
||||||
"fragment" : "-std=c++20"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"backtrace" : 6,
|
|
||||||
"fragment" : "-DFOLLY_NO_CONFIG=1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"backtrace" : 6,
|
|
||||||
"fragment" : "-DLOG_TAG=\\\"ReactNative\\\""
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"defines" :
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"backtrace" : 7,
|
|
||||||
"define" : "RN_SERIALIZABLE_STATE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"define" : "appmodules_EXPORTS"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"includes" :
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"backtrace" : 8,
|
|
||||||
"path" : "/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/default-app-setup"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"backtrace" : 8,
|
|
||||||
"path" : "/home/echo/dev/prototype/apps/mobile/android/app/build/generated/autolinking/src/main/jni"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"backtrace" : 4,
|
|
||||||
"isSystem" : true,
|
|
||||||
"path" : "/home/echo/.gradle/caches/8.14.3/transforms/488fe6e480efb97ec75859f6e274282f/transformed/fbjni-0.7.0/prefab/modules/fbjni/include"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"backtrace" : 4,
|
|
||||||
"isSystem" : true,
|
|
||||||
"path" : "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/jsi/include"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"backtrace" : 4,
|
|
||||||
"isSystem" : true,
|
|
||||||
"path" : "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/reactnative/include"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"language" : "CXX",
|
|
||||||
"sourceIndexes" :
|
|
||||||
[
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"sysroot" :
|
|
||||||
{
|
|
||||||
"path" : "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"id" : "appmodules::@6890427a1f51a3e7e1df",
|
|
||||||
"link" :
|
|
||||||
{
|
|
||||||
"commandFragments" :
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"fragment" : "-Wl,--build-id=sha1 -Wl,--no-rosegment -Wl,--no-undefined-version -Wl,--fatal-warnings -Wl,--no-undefined -Qunused-arguments",
|
|
||||||
"role" : "flags"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"backtrace" : 4,
|
|
||||||
"fragment" : "/home/echo/.gradle/caches/8.14.3/transforms/488fe6e480efb97ec75859f6e274282f/transformed/fbjni-0.7.0/prefab/modules/fbjni/libs/android.x86/libfbjni.so",
|
|
||||||
"role" : "libraries"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"backtrace" : 4,
|
|
||||||
"fragment" : "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/jsi/libs/android.x86/libjsi.so",
|
|
||||||
"role" : "libraries"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"backtrace" : 4,
|
|
||||||
"fragment" : "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/reactnative/libs/android.x86/libreactnative.so",
|
|
||||||
"role" : "libraries"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fragment" : "-latomic -lm",
|
|
||||||
"role" : "libraries"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"language" : "CXX",
|
|
||||||
"sysroot" :
|
|
||||||
{
|
|
||||||
"path" : "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"name" : "appmodules",
|
|
||||||
"nameOnDisk" : "libappmodules.so",
|
|
||||||
"paths" :
|
|
||||||
{
|
|
||||||
"build" : ".",
|
|
||||||
"source" : "."
|
|
||||||
},
|
|
||||||
"sourceGroups" :
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"name" : "Source Files",
|
|
||||||
"sourceIndexes" :
|
|
||||||
[
|
|
||||||
0
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"sources" :
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"backtrace" : 3,
|
|
||||||
"compileGroupIndex" : 0,
|
|
||||||
"path" : "OnLoad.cpp",
|
|
||||||
"sourceGroupIndex" : 0
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"type" : "SHARED_LIBRARY"
|
|
||||||
}
|
|
||||||
@ -1,420 +0,0 @@
|
|||||||
# This is the CMakeCache file.
|
|
||||||
# For build in directory: /home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86
|
|
||||||
# It was generated by CMake: /home/echo/Android/Sdk/cmake/3.22.1/bin/cmake
|
|
||||||
# You can edit this file to change values found and used by cmake.
|
|
||||||
# If you do not want to change any of the values, simply exit the editor.
|
|
||||||
# If you do want to change a value, simply edit, save, and exit the editor.
|
|
||||||
# The syntax for the file is as follows:
|
|
||||||
# KEY:TYPE=VALUE
|
|
||||||
# KEY is the name of a variable in the cache.
|
|
||||||
# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!.
|
|
||||||
# VALUE is the current value for the KEY.
|
|
||||||
|
|
||||||
########################
|
|
||||||
# EXTERNAL cache entries
|
|
||||||
########################
|
|
||||||
|
|
||||||
//No help, variable specified on the command line.
|
|
||||||
ANDROID_ABI:UNINITIALIZED=x86
|
|
||||||
|
|
||||||
//No help, variable specified on the command line.
|
|
||||||
ANDROID_NDK:UNINITIALIZED=/home/echo/Android/Sdk/ndk/27.1.12297006
|
|
||||||
|
|
||||||
//No help, variable specified on the command line.
|
|
||||||
ANDROID_PLATFORM:UNINITIALIZED=android-26
|
|
||||||
|
|
||||||
//No help, variable specified on the command line.
|
|
||||||
ANDROID_STL:UNINITIALIZED=c++_shared
|
|
||||||
|
|
||||||
//No help, variable specified on the command line.
|
|
||||||
ANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES:UNINITIALIZED=ON
|
|
||||||
|
|
||||||
//Path to a program.
|
|
||||||
CCACHE_FOUND:FILEPATH=CCACHE_FOUND-NOTFOUND
|
|
||||||
|
|
||||||
//Path to a program.
|
|
||||||
CMAKE_ADDR2LINE:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-addr2line
|
|
||||||
|
|
||||||
//No help, variable specified on the command line.
|
|
||||||
CMAKE_ANDROID_ARCH_ABI:UNINITIALIZED=x86
|
|
||||||
|
|
||||||
//No help, variable specified on the command line.
|
|
||||||
CMAKE_ANDROID_NDK:UNINITIALIZED=/home/echo/Android/Sdk/ndk/27.1.12297006
|
|
||||||
|
|
||||||
//Archiver
|
|
||||||
CMAKE_AR:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar
|
|
||||||
|
|
||||||
//Flags used by the compiler during all build types.
|
|
||||||
CMAKE_ASM_FLAGS:STRING=
|
|
||||||
|
|
||||||
//Flags used by the compiler during debug builds.
|
|
||||||
CMAKE_ASM_FLAGS_DEBUG:STRING=
|
|
||||||
|
|
||||||
//Flags used by the compiler during release builds.
|
|
||||||
CMAKE_ASM_FLAGS_RELEASE:STRING=
|
|
||||||
|
|
||||||
//Choose the type of build, options are: None Debug Release RelWithDebInfo
|
|
||||||
// MinSizeRel ...
|
|
||||||
CMAKE_BUILD_TYPE:STRING=Debug
|
|
||||||
|
|
||||||
//LLVM archiver
|
|
||||||
CMAKE_CXX_COMPILER_AR:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar
|
|
||||||
|
|
||||||
//Generate index for LLVM archive
|
|
||||||
CMAKE_CXX_COMPILER_RANLIB:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib
|
|
||||||
|
|
||||||
//Flags used by the compiler during all build types.
|
|
||||||
CMAKE_CXX_FLAGS:STRING=
|
|
||||||
|
|
||||||
//Flags used by the compiler during debug builds.
|
|
||||||
CMAKE_CXX_FLAGS_DEBUG:STRING=
|
|
||||||
|
|
||||||
//Flags used by the CXX compiler during MINSIZEREL builds.
|
|
||||||
CMAKE_CXX_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
|
|
||||||
|
|
||||||
//Flags used by the compiler during release builds.
|
|
||||||
CMAKE_CXX_FLAGS_RELEASE:STRING=
|
|
||||||
|
|
||||||
//Flags used by the CXX compiler during RELWITHDEBINFO builds.
|
|
||||||
CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
|
|
||||||
|
|
||||||
//Libraries linked by default with all C++ applications.
|
|
||||||
CMAKE_CXX_STANDARD_LIBRARIES:STRING=-latomic -lm
|
|
||||||
|
|
||||||
//LLVM archiver
|
|
||||||
CMAKE_C_COMPILER_AR:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar
|
|
||||||
|
|
||||||
//Generate index for LLVM archive
|
|
||||||
CMAKE_C_COMPILER_RANLIB:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib
|
|
||||||
|
|
||||||
//Flags used by the compiler during all build types.
|
|
||||||
CMAKE_C_FLAGS:STRING=
|
|
||||||
|
|
||||||
//Flags used by the compiler during debug builds.
|
|
||||||
CMAKE_C_FLAGS_DEBUG:STRING=
|
|
||||||
|
|
||||||
//Flags used by the C compiler during MINSIZEREL builds.
|
|
||||||
CMAKE_C_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
|
|
||||||
|
|
||||||
//Flags used by the compiler during release builds.
|
|
||||||
CMAKE_C_FLAGS_RELEASE:STRING=
|
|
||||||
|
|
||||||
//Flags used by the C compiler during RELWITHDEBINFO builds.
|
|
||||||
CMAKE_C_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
|
|
||||||
|
|
||||||
//Libraries linked by default with all C applications.
|
|
||||||
CMAKE_C_STANDARD_LIBRARIES:STRING=-latomic -lm
|
|
||||||
|
|
||||||
//Path to a program.
|
|
||||||
CMAKE_DLLTOOL:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-dlltool
|
|
||||||
|
|
||||||
//Flags used by the linker.
|
|
||||||
CMAKE_EXE_LINKER_FLAGS:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during DEBUG builds.
|
|
||||||
CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during MINSIZEREL builds.
|
|
||||||
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during RELEASE builds.
|
|
||||||
CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during RELWITHDEBINFO builds.
|
|
||||||
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
|
|
||||||
|
|
||||||
//No help, variable specified on the command line.
|
|
||||||
CMAKE_EXPORT_COMPILE_COMMANDS:UNINITIALIZED=ON
|
|
||||||
|
|
||||||
//No help, variable specified on the command line.
|
|
||||||
CMAKE_FIND_ROOT_PATH:UNINITIALIZED=/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/prefab/x86/prefab
|
|
||||||
|
|
||||||
//Install path prefix, prepended onto install directories.
|
|
||||||
CMAKE_INSTALL_PREFIX:PATH=/usr/local
|
|
||||||
|
|
||||||
//No help, variable specified on the command line.
|
|
||||||
CMAKE_LIBRARY_OUTPUT_DIRECTORY:UNINITIALIZED=/home/echo/dev/prototype/apps/mobile/android/app/build/intermediates/cxx/Debug/2z472e3c/obj/x86
|
|
||||||
|
|
||||||
//Path to a program.
|
|
||||||
CMAKE_LINKER:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/ld.lld
|
|
||||||
|
|
||||||
//No help, variable specified on the command line.
|
|
||||||
CMAKE_MAKE_PROGRAM:UNINITIALIZED=/home/echo/Android/Sdk/cmake/3.22.1/bin/ninja
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of modules.
|
|
||||||
CMAKE_MODULE_LINKER_FLAGS:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of modules during
|
|
||||||
// DEBUG builds.
|
|
||||||
CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of modules during
|
|
||||||
// MINSIZEREL builds.
|
|
||||||
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of modules during
|
|
||||||
// RELEASE builds.
|
|
||||||
CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of modules during
|
|
||||||
// RELWITHDEBINFO builds.
|
|
||||||
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
|
|
||||||
|
|
||||||
//Path to a program.
|
|
||||||
CMAKE_NM:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-nm
|
|
||||||
|
|
||||||
//Path to a program.
|
|
||||||
CMAKE_OBJCOPY:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-objcopy
|
|
||||||
|
|
||||||
//Path to a program.
|
|
||||||
CMAKE_OBJDUMP:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-objdump
|
|
||||||
|
|
||||||
//Value Computed by CMake
|
|
||||||
CMAKE_PROJECT_DESCRIPTION:STATIC=
|
|
||||||
|
|
||||||
//Value Computed by CMake
|
|
||||||
CMAKE_PROJECT_HOMEPAGE_URL:STATIC=
|
|
||||||
|
|
||||||
//Value Computed by CMake
|
|
||||||
CMAKE_PROJECT_NAME:STATIC=appmodules
|
|
||||||
|
|
||||||
//Ranlib
|
|
||||||
CMAKE_RANLIB:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib
|
|
||||||
|
|
||||||
//Path to a program.
|
|
||||||
CMAKE_READELF:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-readelf
|
|
||||||
|
|
||||||
//No help, variable specified on the command line.
|
|
||||||
CMAKE_RUNTIME_OUTPUT_DIRECTORY:UNINITIALIZED=/home/echo/dev/prototype/apps/mobile/android/app/build/intermediates/cxx/Debug/2z472e3c/obj/x86
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of dll's.
|
|
||||||
CMAKE_SHARED_LINKER_FLAGS:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of shared libraries
|
|
||||||
// during DEBUG builds.
|
|
||||||
CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of shared libraries
|
|
||||||
// during MINSIZEREL builds.
|
|
||||||
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of shared libraries
|
|
||||||
// during RELEASE builds.
|
|
||||||
CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of shared libraries
|
|
||||||
// during RELWITHDEBINFO builds.
|
|
||||||
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING=
|
|
||||||
|
|
||||||
//If set, runtime paths are not added when installing shared libraries,
|
|
||||||
// but are added when building.
|
|
||||||
CMAKE_SKIP_INSTALL_RPATH:BOOL=NO
|
|
||||||
|
|
||||||
//If set, runtime paths are not added when using shared libraries.
|
|
||||||
CMAKE_SKIP_RPATH:BOOL=NO
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of static libraries
|
|
||||||
// during all build types.
|
|
||||||
CMAKE_STATIC_LINKER_FLAGS:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of static libraries
|
|
||||||
// during DEBUG builds.
|
|
||||||
CMAKE_STATIC_LINKER_FLAGS_DEBUG:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of static libraries
|
|
||||||
// during MINSIZEREL builds.
|
|
||||||
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of static libraries
|
|
||||||
// during RELEASE builds.
|
|
||||||
CMAKE_STATIC_LINKER_FLAGS_RELEASE:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of static libraries
|
|
||||||
// during RELWITHDEBINFO builds.
|
|
||||||
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING=
|
|
||||||
|
|
||||||
//Strip
|
|
||||||
CMAKE_STRIP:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip
|
|
||||||
|
|
||||||
//No help, variable specified on the command line.
|
|
||||||
CMAKE_SYSTEM_NAME:UNINITIALIZED=Android
|
|
||||||
|
|
||||||
//No help, variable specified on the command line.
|
|
||||||
CMAKE_SYSTEM_VERSION:UNINITIALIZED=26
|
|
||||||
|
|
||||||
//The CMake toolchain file
|
|
||||||
CMAKE_TOOLCHAIN_FILE:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/android.toolchain.cmake
|
|
||||||
|
|
||||||
//If this value is on, makefiles will be generated without the
|
|
||||||
// .SILENT directive, and all commands will be echoed to the console
|
|
||||||
// during the make. This is useful for debugging only. With Visual
|
|
||||||
// Studio IDE projects all commands are done without /nologo.
|
|
||||||
CMAKE_VERBOSE_MAKEFILE:BOOL=FALSE
|
|
||||||
|
|
||||||
//No help, variable specified on the command line.
|
|
||||||
PROJECT_BUILD_DIR:UNINITIALIZED=/home/echo/dev/prototype/apps/mobile/android/app/build
|
|
||||||
|
|
||||||
//No help, variable specified on the command line.
|
|
||||||
PROJECT_ROOT_DIR:UNINITIALIZED=/home/echo/dev/prototype/apps/mobile/android
|
|
||||||
|
|
||||||
//No help, variable specified on the command line.
|
|
||||||
REACT_ANDROID_DIR:UNINITIALIZED=/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid
|
|
||||||
|
|
||||||
//The directory containing a CMake configuration file for ReactAndroid.
|
|
||||||
ReactAndroid_DIR:PATH=/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/prefab/x86/prefab/lib/i686-linux-android/cmake/ReactAndroid
|
|
||||||
|
|
||||||
//Value Computed by CMake
|
|
||||||
appmodules_BINARY_DIR:STATIC=/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86
|
|
||||||
|
|
||||||
//Value Computed by CMake
|
|
||||||
appmodules_IS_TOP_LEVEL:STATIC=ON
|
|
||||||
|
|
||||||
//Value Computed by CMake
|
|
||||||
appmodules_SOURCE_DIR:STATIC=/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/default-app-setup
|
|
||||||
|
|
||||||
//The directory containing a CMake configuration file for fbjni.
|
|
||||||
fbjni_DIR:PATH=/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/prefab/x86/prefab/lib/i686-linux-android/cmake/fbjni
|
|
||||||
|
|
||||||
|
|
||||||
########################
|
|
||||||
# INTERNAL cache entries
|
|
||||||
########################
|
|
||||||
|
|
||||||
//ADVANCED property for variable: CMAKE_ADDR2LINE
|
|
||||||
CMAKE_ADDR2LINE-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_AR
|
|
||||||
CMAKE_AR-ADVANCED:INTERNAL=1
|
|
||||||
//This is the directory where this CMakeCache.txt was created
|
|
||||||
CMAKE_CACHEFILE_DIR:INTERNAL=/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86
|
|
||||||
//Major version of cmake used to create the current loaded cache
|
|
||||||
CMAKE_CACHE_MAJOR_VERSION:INTERNAL=3
|
|
||||||
//Minor version of cmake used to create the current loaded cache
|
|
||||||
CMAKE_CACHE_MINOR_VERSION:INTERNAL=22
|
|
||||||
//Patch version of cmake used to create the current loaded cache
|
|
||||||
CMAKE_CACHE_PATCH_VERSION:INTERNAL=1
|
|
||||||
//Path to CMake executable.
|
|
||||||
CMAKE_COMMAND:INTERNAL=/home/echo/Android/Sdk/cmake/3.22.1/bin/cmake
|
|
||||||
//Path to cpack program executable.
|
|
||||||
CMAKE_CPACK_COMMAND:INTERNAL=/home/echo/Android/Sdk/cmake/3.22.1/bin/cpack
|
|
||||||
//Path to ctest program executable.
|
|
||||||
CMAKE_CTEST_COMMAND:INTERNAL=/home/echo/Android/Sdk/cmake/3.22.1/bin/ctest
|
|
||||||
//ADVANCED property for variable: CMAKE_CXX_COMPILER_AR
|
|
||||||
CMAKE_CXX_COMPILER_AR-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_CXX_COMPILER_RANLIB
|
|
||||||
CMAKE_CXX_COMPILER_RANLIB-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_CXX_FLAGS
|
|
||||||
CMAKE_CXX_FLAGS-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_CXX_FLAGS_DEBUG
|
|
||||||
CMAKE_CXX_FLAGS_DEBUG-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_CXX_FLAGS_MINSIZEREL
|
|
||||||
CMAKE_CXX_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELEASE
|
|
||||||
CMAKE_CXX_FLAGS_RELEASE-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
|
||||||
CMAKE_CXX_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_CXX_STANDARD_LIBRARIES
|
|
||||||
CMAKE_CXX_STANDARD_LIBRARIES-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_C_COMPILER_AR
|
|
||||||
CMAKE_C_COMPILER_AR-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_C_COMPILER_RANLIB
|
|
||||||
CMAKE_C_COMPILER_RANLIB-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_C_FLAGS
|
|
||||||
CMAKE_C_FLAGS-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_C_FLAGS_DEBUG
|
|
||||||
CMAKE_C_FLAGS_DEBUG-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_C_FLAGS_MINSIZEREL
|
|
||||||
CMAKE_C_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_C_FLAGS_RELEASE
|
|
||||||
CMAKE_C_FLAGS_RELEASE-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_C_FLAGS_RELWITHDEBINFO
|
|
||||||
CMAKE_C_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_C_STANDARD_LIBRARIES
|
|
||||||
CMAKE_C_STANDARD_LIBRARIES-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_DLLTOOL
|
|
||||||
CMAKE_DLLTOOL-ADVANCED:INTERNAL=1
|
|
||||||
//Executable file format
|
|
||||||
CMAKE_EXECUTABLE_FORMAT:INTERNAL=ELF
|
|
||||||
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS
|
|
||||||
CMAKE_EXE_LINKER_FLAGS-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_DEBUG
|
|
||||||
CMAKE_EXE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_MINSIZEREL
|
|
||||||
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELEASE
|
|
||||||
CMAKE_EXE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO
|
|
||||||
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
|
|
||||||
//Name of external makefile project generator.
|
|
||||||
CMAKE_EXTRA_GENERATOR:INTERNAL=
|
|
||||||
//Name of generator.
|
|
||||||
CMAKE_GENERATOR:INTERNAL=Ninja
|
|
||||||
//Generator instance identifier.
|
|
||||||
CMAKE_GENERATOR_INSTANCE:INTERNAL=
|
|
||||||
//Name of generator platform.
|
|
||||||
CMAKE_GENERATOR_PLATFORM:INTERNAL=
|
|
||||||
//Name of generator toolset.
|
|
||||||
CMAKE_GENERATOR_TOOLSET:INTERNAL=
|
|
||||||
//Source directory with the top level CMakeLists.txt file for this
|
|
||||||
// project
|
|
||||||
CMAKE_HOME_DIRECTORY:INTERNAL=/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/default-app-setup
|
|
||||||
//Install .so files without execute permission.
|
|
||||||
CMAKE_INSTALL_SO_NO_EXE:INTERNAL=0
|
|
||||||
//ADVANCED property for variable: CMAKE_LINKER
|
|
||||||
CMAKE_LINKER-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS
|
|
||||||
CMAKE_MODULE_LINKER_FLAGS-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_DEBUG
|
|
||||||
CMAKE_MODULE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL
|
|
||||||
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELEASE
|
|
||||||
CMAKE_MODULE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO
|
|
||||||
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_NM
|
|
||||||
CMAKE_NM-ADVANCED:INTERNAL=1
|
|
||||||
//number of local generators
|
|
||||||
CMAKE_NUMBER_OF_MAKEFILES:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_OBJCOPY
|
|
||||||
CMAKE_OBJCOPY-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_OBJDUMP
|
|
||||||
CMAKE_OBJDUMP-ADVANCED:INTERNAL=1
|
|
||||||
//Platform information initialized
|
|
||||||
CMAKE_PLATFORM_INFO_INITIALIZED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_RANLIB
|
|
||||||
CMAKE_RANLIB-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_READELF
|
|
||||||
CMAKE_READELF-ADVANCED:INTERNAL=1
|
|
||||||
//Path to CMake installation.
|
|
||||||
CMAKE_ROOT:INTERNAL=/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22
|
|
||||||
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS
|
|
||||||
CMAKE_SHARED_LINKER_FLAGS-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_DEBUG
|
|
||||||
CMAKE_SHARED_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL
|
|
||||||
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELEASE
|
|
||||||
CMAKE_SHARED_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO
|
|
||||||
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_SKIP_INSTALL_RPATH
|
|
||||||
CMAKE_SKIP_INSTALL_RPATH-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_SKIP_RPATH
|
|
||||||
CMAKE_SKIP_RPATH-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS
|
|
||||||
CMAKE_STATIC_LINKER_FLAGS-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_DEBUG
|
|
||||||
CMAKE_STATIC_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL
|
|
||||||
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELEASE
|
|
||||||
CMAKE_STATIC_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO
|
|
||||||
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_STRIP
|
|
||||||
CMAKE_STRIP-ADVANCED:INTERNAL=1
|
|
||||||
//uname command
|
|
||||||
CMAKE_UNAME:INTERNAL=/usr/bin/uname
|
|
||||||
//ADVANCED property for variable: CMAKE_VERBOSE_MAKEFILE
|
|
||||||
CMAKE_VERBOSE_MAKEFILE-ADVANCED:INTERNAL=1
|
|
||||||
|
|
||||||
@ -1,72 +0,0 @@
|
|||||||
set(CMAKE_C_COMPILER "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/clang")
|
|
||||||
set(CMAKE_C_COMPILER_ARG1 "")
|
|
||||||
set(CMAKE_C_COMPILER_ID "Clang")
|
|
||||||
set(CMAKE_C_COMPILER_VERSION "18.0.2")
|
|
||||||
set(CMAKE_C_COMPILER_VERSION_INTERNAL "")
|
|
||||||
set(CMAKE_C_COMPILER_WRAPPER "")
|
|
||||||
set(CMAKE_C_STANDARD_COMPUTED_DEFAULT "17")
|
|
||||||
set(CMAKE_C_EXTENSIONS_COMPUTED_DEFAULT "ON")
|
|
||||||
set(CMAKE_C_COMPILE_FEATURES "c_std_90;c_function_prototypes;c_std_99;c_restrict;c_variadic_macros;c_std_11;c_static_assert;c_std_17;c_std_23")
|
|
||||||
set(CMAKE_C90_COMPILE_FEATURES "c_std_90;c_function_prototypes")
|
|
||||||
set(CMAKE_C99_COMPILE_FEATURES "c_std_99;c_restrict;c_variadic_macros")
|
|
||||||
set(CMAKE_C11_COMPILE_FEATURES "c_std_11;c_static_assert")
|
|
||||||
set(CMAKE_C17_COMPILE_FEATURES "c_std_17")
|
|
||||||
set(CMAKE_C23_COMPILE_FEATURES "c_std_23")
|
|
||||||
|
|
||||||
set(CMAKE_C_PLATFORM_ID "Linux")
|
|
||||||
set(CMAKE_C_SIMULATE_ID "")
|
|
||||||
set(CMAKE_C_COMPILER_FRONTEND_VARIANT "GNU")
|
|
||||||
set(CMAKE_C_SIMULATE_VERSION "")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
set(CMAKE_AR "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar")
|
|
||||||
set(CMAKE_C_COMPILER_AR "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar")
|
|
||||||
set(CMAKE_RANLIB "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib")
|
|
||||||
set(CMAKE_C_COMPILER_RANLIB "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib")
|
|
||||||
set(CMAKE_LINKER "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/ld.lld")
|
|
||||||
set(CMAKE_MT "")
|
|
||||||
set(CMAKE_COMPILER_IS_GNUCC )
|
|
||||||
set(CMAKE_C_COMPILER_LOADED 1)
|
|
||||||
set(CMAKE_C_COMPILER_WORKS TRUE)
|
|
||||||
set(CMAKE_C_ABI_COMPILED TRUE)
|
|
||||||
|
|
||||||
set(CMAKE_C_COMPILER_ENV_VAR "CC")
|
|
||||||
|
|
||||||
set(CMAKE_C_COMPILER_ID_RUN 1)
|
|
||||||
set(CMAKE_C_SOURCE_FILE_EXTENSIONS c;m)
|
|
||||||
set(CMAKE_C_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
|
|
||||||
set(CMAKE_C_LINKER_PREFERENCE 10)
|
|
||||||
|
|
||||||
# Save compiler ABI information.
|
|
||||||
set(CMAKE_C_SIZEOF_DATA_PTR "4")
|
|
||||||
set(CMAKE_C_COMPILER_ABI "ELF")
|
|
||||||
set(CMAKE_C_BYTE_ORDER "LITTLE_ENDIAN")
|
|
||||||
set(CMAKE_C_LIBRARY_ARCHITECTURE "")
|
|
||||||
|
|
||||||
if(CMAKE_C_SIZEOF_DATA_PTR)
|
|
||||||
set(CMAKE_SIZEOF_VOID_P "${CMAKE_C_SIZEOF_DATA_PTR}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CMAKE_C_COMPILER_ABI)
|
|
||||||
set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_C_COMPILER_ABI}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CMAKE_C_LIBRARY_ARCHITECTURE)
|
|
||||||
set(CMAKE_LIBRARY_ARCHITECTURE "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CMAKE_C_CL_SHOWINCLUDES_PREFIX "")
|
|
||||||
if(CMAKE_C_CL_SHOWINCLUDES_PREFIX)
|
|
||||||
set(CMAKE_CL_SHOWINCLUDES_PREFIX "${CMAKE_C_CL_SHOWINCLUDES_PREFIX}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
set(CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/lib/clang/18/include;/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/i686-linux-android;/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include")
|
|
||||||
set(CMAKE_C_IMPLICIT_LINK_LIBRARIES "-l:libunwind.a;dl;c;-l:libunwind.a;dl")
|
|
||||||
set(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/lib/clang/18/lib/linux/i386;/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/i686-linux-android/26;/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/i686-linux-android;/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib")
|
|
||||||
set(CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "")
|
|
||||||
@ -1,83 +0,0 @@
|
|||||||
set(CMAKE_CXX_COMPILER "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++")
|
|
||||||
set(CMAKE_CXX_COMPILER_ARG1 "")
|
|
||||||
set(CMAKE_CXX_COMPILER_ID "Clang")
|
|
||||||
set(CMAKE_CXX_COMPILER_VERSION "18.0.2")
|
|
||||||
set(CMAKE_CXX_COMPILER_VERSION_INTERNAL "")
|
|
||||||
set(CMAKE_CXX_COMPILER_WRAPPER "")
|
|
||||||
set(CMAKE_CXX_STANDARD_COMPUTED_DEFAULT "17")
|
|
||||||
set(CMAKE_CXX_EXTENSIONS_COMPUTED_DEFAULT "ON")
|
|
||||||
set(CMAKE_CXX_COMPILE_FEATURES "cxx_std_98;cxx_template_template_parameters;cxx_std_11;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates;cxx_std_14;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates;cxx_std_17;cxx_std_20;cxx_std_23")
|
|
||||||
set(CMAKE_CXX98_COMPILE_FEATURES "cxx_std_98;cxx_template_template_parameters")
|
|
||||||
set(CMAKE_CXX11_COMPILE_FEATURES "cxx_std_11;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates")
|
|
||||||
set(CMAKE_CXX14_COMPILE_FEATURES "cxx_std_14;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates")
|
|
||||||
set(CMAKE_CXX17_COMPILE_FEATURES "cxx_std_17")
|
|
||||||
set(CMAKE_CXX20_COMPILE_FEATURES "cxx_std_20")
|
|
||||||
set(CMAKE_CXX23_COMPILE_FEATURES "cxx_std_23")
|
|
||||||
|
|
||||||
set(CMAKE_CXX_PLATFORM_ID "Linux")
|
|
||||||
set(CMAKE_CXX_SIMULATE_ID "")
|
|
||||||
set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT "GNU")
|
|
||||||
set(CMAKE_CXX_SIMULATE_VERSION "")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
set(CMAKE_AR "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar")
|
|
||||||
set(CMAKE_CXX_COMPILER_AR "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar")
|
|
||||||
set(CMAKE_RANLIB "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib")
|
|
||||||
set(CMAKE_CXX_COMPILER_RANLIB "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib")
|
|
||||||
set(CMAKE_LINKER "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/ld.lld")
|
|
||||||
set(CMAKE_MT "")
|
|
||||||
set(CMAKE_COMPILER_IS_GNUCXX )
|
|
||||||
set(CMAKE_CXX_COMPILER_LOADED 1)
|
|
||||||
set(CMAKE_CXX_COMPILER_WORKS TRUE)
|
|
||||||
set(CMAKE_CXX_ABI_COMPILED TRUE)
|
|
||||||
|
|
||||||
set(CMAKE_CXX_COMPILER_ENV_VAR "CXX")
|
|
||||||
|
|
||||||
set(CMAKE_CXX_COMPILER_ID_RUN 1)
|
|
||||||
set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;m;mm;mpp;CPP;ixx;cppm)
|
|
||||||
set(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC)
|
|
||||||
|
|
||||||
foreach (lang C OBJC OBJCXX)
|
|
||||||
if (CMAKE_${lang}_COMPILER_ID_RUN)
|
|
||||||
foreach(extension IN LISTS CMAKE_${lang}_SOURCE_FILE_EXTENSIONS)
|
|
||||||
list(REMOVE_ITEM CMAKE_CXX_SOURCE_FILE_EXTENSIONS ${extension})
|
|
||||||
endforeach()
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
set(CMAKE_CXX_LINKER_PREFERENCE 30)
|
|
||||||
set(CMAKE_CXX_LINKER_PREFERENCE_PROPAGATES 1)
|
|
||||||
|
|
||||||
# Save compiler ABI information.
|
|
||||||
set(CMAKE_CXX_SIZEOF_DATA_PTR "4")
|
|
||||||
set(CMAKE_CXX_COMPILER_ABI "ELF")
|
|
||||||
set(CMAKE_CXX_BYTE_ORDER "LITTLE_ENDIAN")
|
|
||||||
set(CMAKE_CXX_LIBRARY_ARCHITECTURE "")
|
|
||||||
|
|
||||||
if(CMAKE_CXX_SIZEOF_DATA_PTR)
|
|
||||||
set(CMAKE_SIZEOF_VOID_P "${CMAKE_CXX_SIZEOF_DATA_PTR}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CMAKE_CXX_COMPILER_ABI)
|
|
||||||
set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_CXX_COMPILER_ABI}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CMAKE_CXX_LIBRARY_ARCHITECTURE)
|
|
||||||
set(CMAKE_LIBRARY_ARCHITECTURE "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX "")
|
|
||||||
if(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX)
|
|
||||||
set(CMAKE_CL_SHOWINCLUDES_PREFIX "${CMAKE_CXX_CL_SHOWINCLUDES_PREFIX}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
set(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/c++/v1;/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/lib/clang/18/include;/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/i686-linux-android;/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include")
|
|
||||||
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "c++;m;-l:libunwind.a;dl;c;-l:libunwind.a;dl")
|
|
||||||
set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/lib/clang/18/lib/linux/i386;/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/i686-linux-android/26;/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/i686-linux-android;/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib")
|
|
||||||
set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "")
|
|
||||||
Binary file not shown.
Binary file not shown.
@ -1,15 +0,0 @@
|
|||||||
set(CMAKE_HOST_SYSTEM "Linux-6.17.8-arch1-1")
|
|
||||||
set(CMAKE_HOST_SYSTEM_NAME "Linux")
|
|
||||||
set(CMAKE_HOST_SYSTEM_VERSION "6.17.8-arch1-1")
|
|
||||||
set(CMAKE_HOST_SYSTEM_PROCESSOR "x86_64")
|
|
||||||
|
|
||||||
include("/home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/android.toolchain.cmake")
|
|
||||||
|
|
||||||
set(CMAKE_SYSTEM "Android-1")
|
|
||||||
set(CMAKE_SYSTEM_NAME "Android")
|
|
||||||
set(CMAKE_SYSTEM_VERSION "1")
|
|
||||||
set(CMAKE_SYSTEM_PROCESSOR "i686")
|
|
||||||
|
|
||||||
set(CMAKE_CROSSCOMPILING "TRUE")
|
|
||||||
|
|
||||||
set(CMAKE_SYSTEM_LOADED 1)
|
|
||||||
@ -1,803 +0,0 @@
|
|||||||
#ifdef __cplusplus
|
|
||||||
# error "A C++ compiler has been selected for C."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__18CXX)
|
|
||||||
# define ID_VOID_MAIN
|
|
||||||
#endif
|
|
||||||
#if defined(__CLASSIC_C__)
|
|
||||||
/* cv-qualifiers did not exist in K&R C */
|
|
||||||
# define const
|
|
||||||
# define volatile
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(__has_include)
|
|
||||||
/* If the compiler does not have __has_include, pretend the answer is
|
|
||||||
always no. */
|
|
||||||
# define __has_include(x) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Version number components: V=Version, R=Revision, P=Patch
|
|
||||||
Version date components: YYYY=Year, MM=Month, DD=Day */
|
|
||||||
|
|
||||||
#if defined(__INTEL_COMPILER) || defined(__ICC)
|
|
||||||
# define COMPILER_ID "Intel"
|
|
||||||
# if defined(_MSC_VER)
|
|
||||||
# define SIMULATE_ID "MSVC"
|
|
||||||
# endif
|
|
||||||
# if defined(__GNUC__)
|
|
||||||
# define SIMULATE_ID "GNU"
|
|
||||||
# endif
|
|
||||||
/* __INTEL_COMPILER = VRP prior to 2021, and then VVVV for 2021 and later,
|
|
||||||
except that a few beta releases use the old format with V=2021. */
|
|
||||||
# if __INTEL_COMPILER < 2021 || __INTEL_COMPILER == 202110 || __INTEL_COMPILER == 202111
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10)
|
|
||||||
# if defined(__INTEL_COMPILER_UPDATE)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER_UPDATE)
|
|
||||||
# else
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10)
|
|
||||||
# endif
|
|
||||||
# else
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER_UPDATE)
|
|
||||||
/* The third version component from --version is an update index,
|
|
||||||
but no macro is provided for it. */
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(0)
|
|
||||||
# endif
|
|
||||||
# if defined(__INTEL_COMPILER_BUILD_DATE)
|
|
||||||
/* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */
|
|
||||||
# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE)
|
|
||||||
# endif
|
|
||||||
# if defined(_MSC_VER)
|
|
||||||
/* _MSC_VER = VVRR */
|
|
||||||
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
|
|
||||||
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
|
|
||||||
# endif
|
|
||||||
# if defined(__GNUC__)
|
|
||||||
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
|
|
||||||
# elif defined(__GNUG__)
|
|
||||||
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
|
|
||||||
# endif
|
|
||||||
# if defined(__GNUC_MINOR__)
|
|
||||||
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
|
|
||||||
# endif
|
|
||||||
# if defined(__GNUC_PATCHLEVEL__)
|
|
||||||
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif (defined(__clang__) && defined(__INTEL_CLANG_COMPILER)) || defined(__INTEL_LLVM_COMPILER)
|
|
||||||
# define COMPILER_ID "IntelLLVM"
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
# define SIMULATE_ID "MSVC"
|
|
||||||
#endif
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
# define SIMULATE_ID "GNU"
|
|
||||||
#endif
|
|
||||||
/* __INTEL_LLVM_COMPILER = VVVVRP prior to 2021.2.0, VVVVRRPP for 2021.2.0 and
|
|
||||||
* later. Look for 6 digit vs. 8 digit version number to decide encoding.
|
|
||||||
* VVVV is no smaller than the current year when a version is released.
|
|
||||||
*/
|
|
||||||
#if __INTEL_LLVM_COMPILER < 1000000L
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/100)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/10 % 10)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 10)
|
|
||||||
#else
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/10000)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/100 % 100)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 100)
|
|
||||||
#endif
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
/* _MSC_VER = VVRR */
|
|
||||||
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
|
|
||||||
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
|
|
||||||
#endif
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
|
|
||||||
#elif defined(__GNUG__)
|
|
||||||
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
|
|
||||||
#endif
|
|
||||||
#if defined(__GNUC_MINOR__)
|
|
||||||
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
|
|
||||||
#endif
|
|
||||||
#if defined(__GNUC_PATCHLEVEL__)
|
|
||||||
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#elif defined(__PATHCC__)
|
|
||||||
# define COMPILER_ID "PathScale"
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__PATHCC__)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__)
|
|
||||||
# if defined(__PATHCC_PATCHLEVEL__)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__)
|
|
||||||
# define COMPILER_ID "Embarcadero"
|
|
||||||
# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF)
|
|
||||||
# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__CODEGEARC_VERSION__ & 0xFFFF)
|
|
||||||
|
|
||||||
#elif defined(__BORLANDC__)
|
|
||||||
# define COMPILER_ID "Borland"
|
|
||||||
/* __BORLANDC__ = 0xVRR */
|
|
||||||
# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8)
|
|
||||||
# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF)
|
|
||||||
|
|
||||||
#elif defined(__WATCOMC__) && __WATCOMC__ < 1200
|
|
||||||
# define COMPILER_ID "Watcom"
|
|
||||||
/* __WATCOMC__ = VVRR */
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
|
|
||||||
# if (__WATCOMC__ % 10) > 0
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__WATCOMC__)
|
|
||||||
# define COMPILER_ID "OpenWatcom"
|
|
||||||
/* __WATCOMC__ = VVRP + 1100 */
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC((__WATCOMC__ - 1100) / 100)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
|
|
||||||
# if (__WATCOMC__ % 10) > 0
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__SUNPRO_C)
|
|
||||||
# define COMPILER_ID "SunPro"
|
|
||||||
# if __SUNPRO_C >= 0x5100
|
|
||||||
/* __SUNPRO_C = 0xVRRP */
|
|
||||||
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>12)
|
|
||||||
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xFF)
|
|
||||||
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF)
|
|
||||||
# else
|
|
||||||
/* __SUNPRO_CC = 0xVRP */
|
|
||||||
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>8)
|
|
||||||
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xF)
|
|
||||||
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__HP_cc)
|
|
||||||
# define COMPILER_ID "HP"
|
|
||||||
/* __HP_cc = VVRRPP */
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__HP_cc/10000)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__HP_cc/100 % 100)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__HP_cc % 100)
|
|
||||||
|
|
||||||
#elif defined(__DECC)
|
|
||||||
# define COMPILER_ID "Compaq"
|
|
||||||
/* __DECC_VER = VVRRTPPPP */
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__DECC_VER/10000000)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__DECC_VER/100000 % 100)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__DECC_VER % 10000)
|
|
||||||
|
|
||||||
#elif defined(__IBMC__) && defined(__COMPILER_VER__)
|
|
||||||
# define COMPILER_ID "zOS"
|
|
||||||
/* __IBMC__ = VRP */
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10)
|
|
||||||
|
|
||||||
#elif defined(__ibmxl__) && defined(__clang__)
|
|
||||||
# define COMPILER_ID "XLClang"
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__ibmxl_version__)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__ibmxl_release__)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__ibmxl_modification__)
|
|
||||||
# define COMPILER_VERSION_TWEAK DEC(__ibmxl_ptf_fix_level__)
|
|
||||||
|
|
||||||
|
|
||||||
#elif defined(__IBMC__) && !defined(__COMPILER_VER__) && __IBMC__ >= 800
|
|
||||||
# define COMPILER_ID "XL"
|
|
||||||
/* __IBMC__ = VRP */
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10)
|
|
||||||
|
|
||||||
#elif defined(__IBMC__) && !defined(__COMPILER_VER__) && __IBMC__ < 800
|
|
||||||
# define COMPILER_ID "VisualAge"
|
|
||||||
/* __IBMC__ = VRP */
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10)
|
|
||||||
|
|
||||||
#elif defined(__NVCOMPILER)
|
|
||||||
# define COMPILER_ID "NVHPC"
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__NVCOMPILER_MAJOR__)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__NVCOMPILER_MINOR__)
|
|
||||||
# if defined(__NVCOMPILER_PATCHLEVEL__)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__NVCOMPILER_PATCHLEVEL__)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__PGI)
|
|
||||||
# define COMPILER_ID "PGI"
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__PGIC__)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__)
|
|
||||||
# if defined(__PGIC_PATCHLEVEL__)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(_CRAYC)
|
|
||||||
# define COMPILER_ID "Cray"
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(_RELEASE_MAJOR)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR)
|
|
||||||
|
|
||||||
#elif defined(__TI_COMPILER_VERSION__)
|
|
||||||
# define COMPILER_ID "TI"
|
|
||||||
/* __TI_COMPILER_VERSION__ = VVVRRRPPP */
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000)
|
|
||||||
|
|
||||||
#elif defined(__CLANG_FUJITSU)
|
|
||||||
# define COMPILER_ID "FujitsuClang"
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
|
|
||||||
# define COMPILER_VERSION_INTERNAL_STR __clang_version__
|
|
||||||
|
|
||||||
|
|
||||||
#elif defined(__FUJITSU)
|
|
||||||
# define COMPILER_ID "Fujitsu"
|
|
||||||
# if defined(__FCC_version__)
|
|
||||||
# define COMPILER_VERSION __FCC_version__
|
|
||||||
# elif defined(__FCC_major__)
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
|
|
||||||
# endif
|
|
||||||
# if defined(__fcc_version)
|
|
||||||
# define COMPILER_VERSION_INTERNAL DEC(__fcc_version)
|
|
||||||
# elif defined(__FCC_VERSION)
|
|
||||||
# define COMPILER_VERSION_INTERNAL DEC(__FCC_VERSION)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
|
|
||||||
#elif defined(__ghs__)
|
|
||||||
# define COMPILER_ID "GHS"
|
|
||||||
/* __GHS_VERSION_NUMBER = VVVVRP */
|
|
||||||
# ifdef __GHS_VERSION_NUMBER
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__GHS_VERSION_NUMBER / 100)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__GHS_VERSION_NUMBER / 10 % 10)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__GHS_VERSION_NUMBER % 10)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__TINYC__)
|
|
||||||
# define COMPILER_ID "TinyCC"
|
|
||||||
|
|
||||||
#elif defined(__BCC__)
|
|
||||||
# define COMPILER_ID "Bruce"
|
|
||||||
|
|
||||||
#elif defined(__SCO_VERSION__)
|
|
||||||
# define COMPILER_ID "SCO"
|
|
||||||
|
|
||||||
#elif defined(__ARMCC_VERSION) && !defined(__clang__)
|
|
||||||
# define COMPILER_ID "ARMCC"
|
|
||||||
#if __ARMCC_VERSION >= 1000000
|
|
||||||
/* __ARMCC_VERSION = VRRPPPP */
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/1000000)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 100)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
|
|
||||||
#else
|
|
||||||
/* __ARMCC_VERSION = VRPPPP */
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/100000)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 10)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#elif defined(__clang__) && defined(__apple_build_version__)
|
|
||||||
# define COMPILER_ID "AppleClang"
|
|
||||||
# if defined(_MSC_VER)
|
|
||||||
# define SIMULATE_ID "MSVC"
|
|
||||||
# endif
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
|
|
||||||
# if defined(_MSC_VER)
|
|
||||||
/* _MSC_VER = VVRR */
|
|
||||||
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
|
|
||||||
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
|
|
||||||
# endif
|
|
||||||
# define COMPILER_VERSION_TWEAK DEC(__apple_build_version__)
|
|
||||||
|
|
||||||
#elif defined(__clang__) && defined(__ARMCOMPILER_VERSION)
|
|
||||||
# define COMPILER_ID "ARMClang"
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__ARMCOMPILER_VERSION/1000000)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__ARMCOMPILER_VERSION/10000 % 100)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__ARMCOMPILER_VERSION % 10000)
|
|
||||||
# define COMPILER_VERSION_INTERNAL DEC(__ARMCOMPILER_VERSION)
|
|
||||||
|
|
||||||
#elif defined(__clang__)
|
|
||||||
# define COMPILER_ID "Clang"
|
|
||||||
# if defined(_MSC_VER)
|
|
||||||
# define SIMULATE_ID "MSVC"
|
|
||||||
# endif
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
|
|
||||||
# if defined(_MSC_VER)
|
|
||||||
/* _MSC_VER = VVRR */
|
|
||||||
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
|
|
||||||
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
# define COMPILER_ID "GNU"
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__GNUC__)
|
|
||||||
# if defined(__GNUC_MINOR__)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__)
|
|
||||||
# endif
|
|
||||||
# if defined(__GNUC_PATCHLEVEL__)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
# define COMPILER_ID "MSVC"
|
|
||||||
/* _MSC_VER = VVRR */
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100)
|
|
||||||
# if defined(_MSC_FULL_VER)
|
|
||||||
# if _MSC_VER >= 1400
|
|
||||||
/* _MSC_FULL_VER = VVRRPPPPP */
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000)
|
|
||||||
# else
|
|
||||||
/* _MSC_FULL_VER = VVRRPPPP */
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000)
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# if defined(_MSC_BUILD)
|
|
||||||
# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__VISUALDSPVERSION__) || defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__)
|
|
||||||
# define COMPILER_ID "ADSP"
|
|
||||||
#if defined(__VISUALDSPVERSION__)
|
|
||||||
/* __VISUALDSPVERSION__ = 0xVVRRPP00 */
|
|
||||||
# define COMPILER_VERSION_MAJOR HEX(__VISUALDSPVERSION__>>24)
|
|
||||||
# define COMPILER_VERSION_MINOR HEX(__VISUALDSPVERSION__>>16 & 0xFF)
|
|
||||||
# define COMPILER_VERSION_PATCH HEX(__VISUALDSPVERSION__>>8 & 0xFF)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
|
|
||||||
# define COMPILER_ID "IAR"
|
|
||||||
# if defined(__VER__) && defined(__ICCARM__)
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 1000000)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(((__VER__) / 1000) % 1000)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC((__VER__) % 1000)
|
|
||||||
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
|
|
||||||
# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__) || defined(__ICCRISCV__) || defined(__ICCV850__) || defined(__ICC8051__) || defined(__ICCSTM8__))
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 100)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC((__VER__) - (((__VER__) / 100)*100))
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__SUBVERSION__)
|
|
||||||
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__SDCC_VERSION_MAJOR) || defined(SDCC)
|
|
||||||
# define COMPILER_ID "SDCC"
|
|
||||||
# if defined(__SDCC_VERSION_MAJOR)
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__SDCC_VERSION_MAJOR)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__SDCC_VERSION_MINOR)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__SDCC_VERSION_PATCH)
|
|
||||||
# else
|
|
||||||
/* SDCC = VRP */
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(SDCC/100)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(SDCC/10 % 10)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(SDCC % 10)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
|
|
||||||
/* These compilers are either not known or too old to define an
|
|
||||||
identification macro. Try to identify the platform and guess that
|
|
||||||
it is the native compiler. */
|
|
||||||
#elif defined(__hpux) || defined(__hpua)
|
|
||||||
# define COMPILER_ID "HP"
|
|
||||||
|
|
||||||
#else /* unknown compiler */
|
|
||||||
# define COMPILER_ID ""
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Construct the string literal in pieces to prevent the source from
|
|
||||||
getting matched. Store it in a pointer rather than an array
|
|
||||||
because some compilers will just produce instructions to fill the
|
|
||||||
array rather than assigning a pointer to a static array. */
|
|
||||||
char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
|
|
||||||
#ifdef SIMULATE_ID
|
|
||||||
char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __QNXNTO__
|
|
||||||
char const* qnxnto = "INFO" ":" "qnxnto[]";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
|
|
||||||
char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define STRINGIFY_HELPER(X) #X
|
|
||||||
#define STRINGIFY(X) STRINGIFY_HELPER(X)
|
|
||||||
|
|
||||||
/* Identify known platforms by name. */
|
|
||||||
#if defined(__linux) || defined(__linux__) || defined(linux)
|
|
||||||
# define PLATFORM_ID "Linux"
|
|
||||||
|
|
||||||
#elif defined(__MSYS__)
|
|
||||||
# define PLATFORM_ID "MSYS"
|
|
||||||
|
|
||||||
#elif defined(__CYGWIN__)
|
|
||||||
# define PLATFORM_ID "Cygwin"
|
|
||||||
|
|
||||||
#elif defined(__MINGW32__)
|
|
||||||
# define PLATFORM_ID "MinGW"
|
|
||||||
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
# define PLATFORM_ID "Darwin"
|
|
||||||
|
|
||||||
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
|
|
||||||
# define PLATFORM_ID "Windows"
|
|
||||||
|
|
||||||
#elif defined(__FreeBSD__) || defined(__FreeBSD)
|
|
||||||
# define PLATFORM_ID "FreeBSD"
|
|
||||||
|
|
||||||
#elif defined(__NetBSD__) || defined(__NetBSD)
|
|
||||||
# define PLATFORM_ID "NetBSD"
|
|
||||||
|
|
||||||
#elif defined(__OpenBSD__) || defined(__OPENBSD)
|
|
||||||
# define PLATFORM_ID "OpenBSD"
|
|
||||||
|
|
||||||
#elif defined(__sun) || defined(sun)
|
|
||||||
# define PLATFORM_ID "SunOS"
|
|
||||||
|
|
||||||
#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__)
|
|
||||||
# define PLATFORM_ID "AIX"
|
|
||||||
|
|
||||||
#elif defined(__hpux) || defined(__hpux__)
|
|
||||||
# define PLATFORM_ID "HP-UX"
|
|
||||||
|
|
||||||
#elif defined(__HAIKU__)
|
|
||||||
# define PLATFORM_ID "Haiku"
|
|
||||||
|
|
||||||
#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
|
|
||||||
# define PLATFORM_ID "BeOS"
|
|
||||||
|
|
||||||
#elif defined(__QNX__) || defined(__QNXNTO__)
|
|
||||||
# define PLATFORM_ID "QNX"
|
|
||||||
|
|
||||||
#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__)
|
|
||||||
# define PLATFORM_ID "Tru64"
|
|
||||||
|
|
||||||
#elif defined(__riscos) || defined(__riscos__)
|
|
||||||
# define PLATFORM_ID "RISCos"
|
|
||||||
|
|
||||||
#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__)
|
|
||||||
# define PLATFORM_ID "SINIX"
|
|
||||||
|
|
||||||
#elif defined(__UNIX_SV__)
|
|
||||||
# define PLATFORM_ID "UNIX_SV"
|
|
||||||
|
|
||||||
#elif defined(__bsdos__)
|
|
||||||
# define PLATFORM_ID "BSDOS"
|
|
||||||
|
|
||||||
#elif defined(_MPRAS) || defined(MPRAS)
|
|
||||||
# define PLATFORM_ID "MP-RAS"
|
|
||||||
|
|
||||||
#elif defined(__osf) || defined(__osf__)
|
|
||||||
# define PLATFORM_ID "OSF1"
|
|
||||||
|
|
||||||
#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv)
|
|
||||||
# define PLATFORM_ID "SCO_SV"
|
|
||||||
|
|
||||||
#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX)
|
|
||||||
# define PLATFORM_ID "ULTRIX"
|
|
||||||
|
|
||||||
#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX)
|
|
||||||
# define PLATFORM_ID "Xenix"
|
|
||||||
|
|
||||||
#elif defined(__WATCOMC__)
|
|
||||||
# if defined(__LINUX__)
|
|
||||||
# define PLATFORM_ID "Linux"
|
|
||||||
|
|
||||||
# elif defined(__DOS__)
|
|
||||||
# define PLATFORM_ID "DOS"
|
|
||||||
|
|
||||||
# elif defined(__OS2__)
|
|
||||||
# define PLATFORM_ID "OS2"
|
|
||||||
|
|
||||||
# elif defined(__WINDOWS__)
|
|
||||||
# define PLATFORM_ID "Windows3x"
|
|
||||||
|
|
||||||
# elif defined(__VXWORKS__)
|
|
||||||
# define PLATFORM_ID "VxWorks"
|
|
||||||
|
|
||||||
# else /* unknown platform */
|
|
||||||
# define PLATFORM_ID
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__INTEGRITY)
|
|
||||||
# if defined(INT_178B)
|
|
||||||
# define PLATFORM_ID "Integrity178"
|
|
||||||
|
|
||||||
# else /* regular Integrity */
|
|
||||||
# define PLATFORM_ID "Integrity"
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#else /* unknown platform */
|
|
||||||
# define PLATFORM_ID
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* For windows compilers MSVC and Intel we can determine
|
|
||||||
the architecture of the compiler being used. This is because
|
|
||||||
the compilers do not have flags that can change the architecture,
|
|
||||||
but rather depend on which compiler is being used
|
|
||||||
*/
|
|
||||||
#if defined(_WIN32) && defined(_MSC_VER)
|
|
||||||
# if defined(_M_IA64)
|
|
||||||
# define ARCHITECTURE_ID "IA64"
|
|
||||||
|
|
||||||
# elif defined(_M_ARM64EC)
|
|
||||||
# define ARCHITECTURE_ID "ARM64EC"
|
|
||||||
|
|
||||||
# elif defined(_M_X64) || defined(_M_AMD64)
|
|
||||||
# define ARCHITECTURE_ID "x64"
|
|
||||||
|
|
||||||
# elif defined(_M_IX86)
|
|
||||||
# define ARCHITECTURE_ID "X86"
|
|
||||||
|
|
||||||
# elif defined(_M_ARM64)
|
|
||||||
# define ARCHITECTURE_ID "ARM64"
|
|
||||||
|
|
||||||
# elif defined(_M_ARM)
|
|
||||||
# if _M_ARM == 4
|
|
||||||
# define ARCHITECTURE_ID "ARMV4I"
|
|
||||||
# elif _M_ARM == 5
|
|
||||||
# define ARCHITECTURE_ID "ARMV5I"
|
|
||||||
# else
|
|
||||||
# define ARCHITECTURE_ID "ARMV" STRINGIFY(_M_ARM)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# elif defined(_M_MIPS)
|
|
||||||
# define ARCHITECTURE_ID "MIPS"
|
|
||||||
|
|
||||||
# elif defined(_M_SH)
|
|
||||||
# define ARCHITECTURE_ID "SHx"
|
|
||||||
|
|
||||||
# else /* unknown architecture */
|
|
||||||
# define ARCHITECTURE_ID ""
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__WATCOMC__)
|
|
||||||
# if defined(_M_I86)
|
|
||||||
# define ARCHITECTURE_ID "I86"
|
|
||||||
|
|
||||||
# elif defined(_M_IX86)
|
|
||||||
# define ARCHITECTURE_ID "X86"
|
|
||||||
|
|
||||||
# else /* unknown architecture */
|
|
||||||
# define ARCHITECTURE_ID ""
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
|
|
||||||
# if defined(__ICCARM__)
|
|
||||||
# define ARCHITECTURE_ID "ARM"
|
|
||||||
|
|
||||||
# elif defined(__ICCRX__)
|
|
||||||
# define ARCHITECTURE_ID "RX"
|
|
||||||
|
|
||||||
# elif defined(__ICCRH850__)
|
|
||||||
# define ARCHITECTURE_ID "RH850"
|
|
||||||
|
|
||||||
# elif defined(__ICCRL78__)
|
|
||||||
# define ARCHITECTURE_ID "RL78"
|
|
||||||
|
|
||||||
# elif defined(__ICCRISCV__)
|
|
||||||
# define ARCHITECTURE_ID "RISCV"
|
|
||||||
|
|
||||||
# elif defined(__ICCAVR__)
|
|
||||||
# define ARCHITECTURE_ID "AVR"
|
|
||||||
|
|
||||||
# elif defined(__ICC430__)
|
|
||||||
# define ARCHITECTURE_ID "MSP430"
|
|
||||||
|
|
||||||
# elif defined(__ICCV850__)
|
|
||||||
# define ARCHITECTURE_ID "V850"
|
|
||||||
|
|
||||||
# elif defined(__ICC8051__)
|
|
||||||
# define ARCHITECTURE_ID "8051"
|
|
||||||
|
|
||||||
# elif defined(__ICCSTM8__)
|
|
||||||
# define ARCHITECTURE_ID "STM8"
|
|
||||||
|
|
||||||
# else /* unknown architecture */
|
|
||||||
# define ARCHITECTURE_ID ""
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__ghs__)
|
|
||||||
# if defined(__PPC64__)
|
|
||||||
# define ARCHITECTURE_ID "PPC64"
|
|
||||||
|
|
||||||
# elif defined(__ppc__)
|
|
||||||
# define ARCHITECTURE_ID "PPC"
|
|
||||||
|
|
||||||
# elif defined(__ARM__)
|
|
||||||
# define ARCHITECTURE_ID "ARM"
|
|
||||||
|
|
||||||
# elif defined(__x86_64__)
|
|
||||||
# define ARCHITECTURE_ID "x64"
|
|
||||||
|
|
||||||
# elif defined(__i386__)
|
|
||||||
# define ARCHITECTURE_ID "X86"
|
|
||||||
|
|
||||||
# else /* unknown architecture */
|
|
||||||
# define ARCHITECTURE_ID ""
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__TI_COMPILER_VERSION__)
|
|
||||||
# if defined(__TI_ARM__)
|
|
||||||
# define ARCHITECTURE_ID "ARM"
|
|
||||||
|
|
||||||
# elif defined(__MSP430__)
|
|
||||||
# define ARCHITECTURE_ID "MSP430"
|
|
||||||
|
|
||||||
# elif defined(__TMS320C28XX__)
|
|
||||||
# define ARCHITECTURE_ID "TMS320C28x"
|
|
||||||
|
|
||||||
# elif defined(__TMS320C6X__) || defined(_TMS320C6X)
|
|
||||||
# define ARCHITECTURE_ID "TMS320C6x"
|
|
||||||
|
|
||||||
# else /* unknown architecture */
|
|
||||||
# define ARCHITECTURE_ID ""
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
# define ARCHITECTURE_ID
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Convert integer to decimal digit literals. */
|
|
||||||
#define DEC(n) \
|
|
||||||
('0' + (((n) / 10000000)%10)), \
|
|
||||||
('0' + (((n) / 1000000)%10)), \
|
|
||||||
('0' + (((n) / 100000)%10)), \
|
|
||||||
('0' + (((n) / 10000)%10)), \
|
|
||||||
('0' + (((n) / 1000)%10)), \
|
|
||||||
('0' + (((n) / 100)%10)), \
|
|
||||||
('0' + (((n) / 10)%10)), \
|
|
||||||
('0' + ((n) % 10))
|
|
||||||
|
|
||||||
/* Convert integer to hex digit literals. */
|
|
||||||
#define HEX(n) \
|
|
||||||
('0' + ((n)>>28 & 0xF)), \
|
|
||||||
('0' + ((n)>>24 & 0xF)), \
|
|
||||||
('0' + ((n)>>20 & 0xF)), \
|
|
||||||
('0' + ((n)>>16 & 0xF)), \
|
|
||||||
('0' + ((n)>>12 & 0xF)), \
|
|
||||||
('0' + ((n)>>8 & 0xF)), \
|
|
||||||
('0' + ((n)>>4 & 0xF)), \
|
|
||||||
('0' + ((n) & 0xF))
|
|
||||||
|
|
||||||
/* Construct a string literal encoding the version number. */
|
|
||||||
#ifdef COMPILER_VERSION
|
|
||||||
char const* info_version = "INFO" ":" "compiler_version[" COMPILER_VERSION "]";
|
|
||||||
|
|
||||||
/* Construct a string literal encoding the version number components. */
|
|
||||||
#elif defined(COMPILER_VERSION_MAJOR)
|
|
||||||
char const info_version[] = {
|
|
||||||
'I', 'N', 'F', 'O', ':',
|
|
||||||
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[',
|
|
||||||
COMPILER_VERSION_MAJOR,
|
|
||||||
# ifdef COMPILER_VERSION_MINOR
|
|
||||||
'.', COMPILER_VERSION_MINOR,
|
|
||||||
# ifdef COMPILER_VERSION_PATCH
|
|
||||||
'.', COMPILER_VERSION_PATCH,
|
|
||||||
# ifdef COMPILER_VERSION_TWEAK
|
|
||||||
'.', COMPILER_VERSION_TWEAK,
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
']','\0'};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Construct a string literal encoding the internal version number. */
|
|
||||||
#ifdef COMPILER_VERSION_INTERNAL
|
|
||||||
char const info_version_internal[] = {
|
|
||||||
'I', 'N', 'F', 'O', ':',
|
|
||||||
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','_',
|
|
||||||
'i','n','t','e','r','n','a','l','[',
|
|
||||||
COMPILER_VERSION_INTERNAL,']','\0'};
|
|
||||||
#elif defined(COMPILER_VERSION_INTERNAL_STR)
|
|
||||||
char const* info_version_internal = "INFO" ":" "compiler_version_internal[" COMPILER_VERSION_INTERNAL_STR "]";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Construct a string literal encoding the version number components. */
|
|
||||||
#ifdef SIMULATE_VERSION_MAJOR
|
|
||||||
char const info_simulate_version[] = {
|
|
||||||
'I', 'N', 'F', 'O', ':',
|
|
||||||
's','i','m','u','l','a','t','e','_','v','e','r','s','i','o','n','[',
|
|
||||||
SIMULATE_VERSION_MAJOR,
|
|
||||||
# ifdef SIMULATE_VERSION_MINOR
|
|
||||||
'.', SIMULATE_VERSION_MINOR,
|
|
||||||
# ifdef SIMULATE_VERSION_PATCH
|
|
||||||
'.', SIMULATE_VERSION_PATCH,
|
|
||||||
# ifdef SIMULATE_VERSION_TWEAK
|
|
||||||
'.', SIMULATE_VERSION_TWEAK,
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
']','\0'};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Construct the string literal in pieces to prevent the source from
|
|
||||||
getting matched. Store it in a pointer rather than an array
|
|
||||||
because some compilers will just produce instructions to fill the
|
|
||||||
array rather than assigning a pointer to a static array. */
|
|
||||||
char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]";
|
|
||||||
char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if !defined(__STDC__) && !defined(__clang__)
|
|
||||||
# if defined(_MSC_VER) || defined(__ibmxl__) || defined(__IBMC__)
|
|
||||||
# define C_VERSION "90"
|
|
||||||
# else
|
|
||||||
# define C_VERSION
|
|
||||||
# endif
|
|
||||||
#elif __STDC_VERSION__ > 201710L
|
|
||||||
# define C_VERSION "23"
|
|
||||||
#elif __STDC_VERSION__ >= 201710L
|
|
||||||
# define C_VERSION "17"
|
|
||||||
#elif __STDC_VERSION__ >= 201000L
|
|
||||||
# define C_VERSION "11"
|
|
||||||
#elif __STDC_VERSION__ >= 199901L
|
|
||||||
# define C_VERSION "99"
|
|
||||||
#else
|
|
||||||
# define C_VERSION "90"
|
|
||||||
#endif
|
|
||||||
const char* info_language_standard_default =
|
|
||||||
"INFO" ":" "standard_default[" C_VERSION "]";
|
|
||||||
|
|
||||||
const char* info_language_extensions_default = "INFO" ":" "extensions_default["
|
|
||||||
/* !defined(_MSC_VER) to exclude Clang's MSVC compatibility mode. */
|
|
||||||
#if (defined(__clang__) || defined(__GNUC__) || \
|
|
||||||
defined(__TI_COMPILER_VERSION__)) && \
|
|
||||||
!defined(__STRICT_ANSI__) && !defined(_MSC_VER)
|
|
||||||
"ON"
|
|
||||||
#else
|
|
||||||
"OFF"
|
|
||||||
#endif
|
|
||||||
"]";
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifdef ID_VOID_MAIN
|
|
||||||
void main() {}
|
|
||||||
#else
|
|
||||||
# if defined(__CLASSIC_C__)
|
|
||||||
int main(argc, argv) int argc; char *argv[];
|
|
||||||
# else
|
|
||||||
int main(int argc, char* argv[])
|
|
||||||
# endif
|
|
||||||
{
|
|
||||||
int require = 0;
|
|
||||||
require += info_compiler[argc];
|
|
||||||
require += info_platform[argc];
|
|
||||||
require += info_arch[argc];
|
|
||||||
#ifdef COMPILER_VERSION_MAJOR
|
|
||||||
require += info_version[argc];
|
|
||||||
#endif
|
|
||||||
#ifdef COMPILER_VERSION_INTERNAL
|
|
||||||
require += info_version_internal[argc];
|
|
||||||
#endif
|
|
||||||
#ifdef SIMULATE_ID
|
|
||||||
require += info_simulate[argc];
|
|
||||||
#endif
|
|
||||||
#ifdef SIMULATE_VERSION_MAJOR
|
|
||||||
require += info_simulate_version[argc];
|
|
||||||
#endif
|
|
||||||
#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
|
|
||||||
require += info_cray[argc];
|
|
||||||
#endif
|
|
||||||
require += info_language_standard_default[argc];
|
|
||||||
require += info_language_extensions_default[argc];
|
|
||||||
(void)argv;
|
|
||||||
return require;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
Binary file not shown.
@ -1,791 +0,0 @@
|
|||||||
/* This source file must have a .cpp extension so that all C++ compilers
|
|
||||||
recognize the extension without flags. Borland does not know .cxx for
|
|
||||||
example. */
|
|
||||||
#ifndef __cplusplus
|
|
||||||
# error "A C compiler has been selected for C++."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(__has_include)
|
|
||||||
/* If the compiler does not have __has_include, pretend the answer is
|
|
||||||
always no. */
|
|
||||||
# define __has_include(x) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Version number components: V=Version, R=Revision, P=Patch
|
|
||||||
Version date components: YYYY=Year, MM=Month, DD=Day */
|
|
||||||
|
|
||||||
#if defined(__COMO__)
|
|
||||||
# define COMPILER_ID "Comeau"
|
|
||||||
/* __COMO_VERSION__ = VRR */
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__COMO_VERSION__ / 100)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__COMO_VERSION__ % 100)
|
|
||||||
|
|
||||||
#elif defined(__INTEL_COMPILER) || defined(__ICC)
|
|
||||||
# define COMPILER_ID "Intel"
|
|
||||||
# if defined(_MSC_VER)
|
|
||||||
# define SIMULATE_ID "MSVC"
|
|
||||||
# endif
|
|
||||||
# if defined(__GNUC__)
|
|
||||||
# define SIMULATE_ID "GNU"
|
|
||||||
# endif
|
|
||||||
/* __INTEL_COMPILER = VRP prior to 2021, and then VVVV for 2021 and later,
|
|
||||||
except that a few beta releases use the old format with V=2021. */
|
|
||||||
# if __INTEL_COMPILER < 2021 || __INTEL_COMPILER == 202110 || __INTEL_COMPILER == 202111
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10)
|
|
||||||
# if defined(__INTEL_COMPILER_UPDATE)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER_UPDATE)
|
|
||||||
# else
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10)
|
|
||||||
# endif
|
|
||||||
# else
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER_UPDATE)
|
|
||||||
/* The third version component from --version is an update index,
|
|
||||||
but no macro is provided for it. */
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(0)
|
|
||||||
# endif
|
|
||||||
# if defined(__INTEL_COMPILER_BUILD_DATE)
|
|
||||||
/* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */
|
|
||||||
# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE)
|
|
||||||
# endif
|
|
||||||
# if defined(_MSC_VER)
|
|
||||||
/* _MSC_VER = VVRR */
|
|
||||||
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
|
|
||||||
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
|
|
||||||
# endif
|
|
||||||
# if defined(__GNUC__)
|
|
||||||
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
|
|
||||||
# elif defined(__GNUG__)
|
|
||||||
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
|
|
||||||
# endif
|
|
||||||
# if defined(__GNUC_MINOR__)
|
|
||||||
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
|
|
||||||
# endif
|
|
||||||
# if defined(__GNUC_PATCHLEVEL__)
|
|
||||||
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif (defined(__clang__) && defined(__INTEL_CLANG_COMPILER)) || defined(__INTEL_LLVM_COMPILER)
|
|
||||||
# define COMPILER_ID "IntelLLVM"
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
# define SIMULATE_ID "MSVC"
|
|
||||||
#endif
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
# define SIMULATE_ID "GNU"
|
|
||||||
#endif
|
|
||||||
/* __INTEL_LLVM_COMPILER = VVVVRP prior to 2021.2.0, VVVVRRPP for 2021.2.0 and
|
|
||||||
* later. Look for 6 digit vs. 8 digit version number to decide encoding.
|
|
||||||
* VVVV is no smaller than the current year when a version is released.
|
|
||||||
*/
|
|
||||||
#if __INTEL_LLVM_COMPILER < 1000000L
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/100)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/10 % 10)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 10)
|
|
||||||
#else
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/10000)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/100 % 100)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 100)
|
|
||||||
#endif
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
/* _MSC_VER = VVRR */
|
|
||||||
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
|
|
||||||
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
|
|
||||||
#endif
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
|
|
||||||
#elif defined(__GNUG__)
|
|
||||||
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
|
|
||||||
#endif
|
|
||||||
#if defined(__GNUC_MINOR__)
|
|
||||||
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
|
|
||||||
#endif
|
|
||||||
#if defined(__GNUC_PATCHLEVEL__)
|
|
||||||
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#elif defined(__PATHCC__)
|
|
||||||
# define COMPILER_ID "PathScale"
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__PATHCC__)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__)
|
|
||||||
# if defined(__PATHCC_PATCHLEVEL__)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__)
|
|
||||||
# define COMPILER_ID "Embarcadero"
|
|
||||||
# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF)
|
|
||||||
# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__CODEGEARC_VERSION__ & 0xFFFF)
|
|
||||||
|
|
||||||
#elif defined(__BORLANDC__)
|
|
||||||
# define COMPILER_ID "Borland"
|
|
||||||
/* __BORLANDC__ = 0xVRR */
|
|
||||||
# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8)
|
|
||||||
# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF)
|
|
||||||
|
|
||||||
#elif defined(__WATCOMC__) && __WATCOMC__ < 1200
|
|
||||||
# define COMPILER_ID "Watcom"
|
|
||||||
/* __WATCOMC__ = VVRR */
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
|
|
||||||
# if (__WATCOMC__ % 10) > 0
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__WATCOMC__)
|
|
||||||
# define COMPILER_ID "OpenWatcom"
|
|
||||||
/* __WATCOMC__ = VVRP + 1100 */
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC((__WATCOMC__ - 1100) / 100)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
|
|
||||||
# if (__WATCOMC__ % 10) > 0
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__SUNPRO_CC)
|
|
||||||
# define COMPILER_ID "SunPro"
|
|
||||||
# if __SUNPRO_CC >= 0x5100
|
|
||||||
/* __SUNPRO_CC = 0xVRRP */
|
|
||||||
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>12)
|
|
||||||
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xFF)
|
|
||||||
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF)
|
|
||||||
# else
|
|
||||||
/* __SUNPRO_CC = 0xVRP */
|
|
||||||
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>8)
|
|
||||||
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xF)
|
|
||||||
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__HP_aCC)
|
|
||||||
# define COMPILER_ID "HP"
|
|
||||||
/* __HP_aCC = VVRRPP */
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__HP_aCC/10000)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__HP_aCC/100 % 100)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__HP_aCC % 100)
|
|
||||||
|
|
||||||
#elif defined(__DECCXX)
|
|
||||||
# define COMPILER_ID "Compaq"
|
|
||||||
/* __DECCXX_VER = VVRRTPPPP */
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__DECCXX_VER/10000000)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__DECCXX_VER/100000 % 100)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__DECCXX_VER % 10000)
|
|
||||||
|
|
||||||
#elif defined(__IBMCPP__) && defined(__COMPILER_VER__)
|
|
||||||
# define COMPILER_ID "zOS"
|
|
||||||
/* __IBMCPP__ = VRP */
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
|
|
||||||
|
|
||||||
#elif defined(__ibmxl__) && defined(__clang__)
|
|
||||||
# define COMPILER_ID "XLClang"
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__ibmxl_version__)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__ibmxl_release__)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__ibmxl_modification__)
|
|
||||||
# define COMPILER_VERSION_TWEAK DEC(__ibmxl_ptf_fix_level__)
|
|
||||||
|
|
||||||
|
|
||||||
#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ >= 800
|
|
||||||
# define COMPILER_ID "XL"
|
|
||||||
/* __IBMCPP__ = VRP */
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
|
|
||||||
|
|
||||||
#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ < 800
|
|
||||||
# define COMPILER_ID "VisualAge"
|
|
||||||
/* __IBMCPP__ = VRP */
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
|
|
||||||
|
|
||||||
#elif defined(__NVCOMPILER)
|
|
||||||
# define COMPILER_ID "NVHPC"
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__NVCOMPILER_MAJOR__)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__NVCOMPILER_MINOR__)
|
|
||||||
# if defined(__NVCOMPILER_PATCHLEVEL__)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__NVCOMPILER_PATCHLEVEL__)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__PGI)
|
|
||||||
# define COMPILER_ID "PGI"
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__PGIC__)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__)
|
|
||||||
# if defined(__PGIC_PATCHLEVEL__)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(_CRAYC)
|
|
||||||
# define COMPILER_ID "Cray"
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(_RELEASE_MAJOR)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR)
|
|
||||||
|
|
||||||
#elif defined(__TI_COMPILER_VERSION__)
|
|
||||||
# define COMPILER_ID "TI"
|
|
||||||
/* __TI_COMPILER_VERSION__ = VVVRRRPPP */
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000)
|
|
||||||
|
|
||||||
#elif defined(__CLANG_FUJITSU)
|
|
||||||
# define COMPILER_ID "FujitsuClang"
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
|
|
||||||
# define COMPILER_VERSION_INTERNAL_STR __clang_version__
|
|
||||||
|
|
||||||
|
|
||||||
#elif defined(__FUJITSU)
|
|
||||||
# define COMPILER_ID "Fujitsu"
|
|
||||||
# if defined(__FCC_version__)
|
|
||||||
# define COMPILER_VERSION __FCC_version__
|
|
||||||
# elif defined(__FCC_major__)
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
|
|
||||||
# endif
|
|
||||||
# if defined(__fcc_version)
|
|
||||||
# define COMPILER_VERSION_INTERNAL DEC(__fcc_version)
|
|
||||||
# elif defined(__FCC_VERSION)
|
|
||||||
# define COMPILER_VERSION_INTERNAL DEC(__FCC_VERSION)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
|
|
||||||
#elif defined(__ghs__)
|
|
||||||
# define COMPILER_ID "GHS"
|
|
||||||
/* __GHS_VERSION_NUMBER = VVVVRP */
|
|
||||||
# ifdef __GHS_VERSION_NUMBER
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__GHS_VERSION_NUMBER / 100)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__GHS_VERSION_NUMBER / 10 % 10)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__GHS_VERSION_NUMBER % 10)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__SCO_VERSION__)
|
|
||||||
# define COMPILER_ID "SCO"
|
|
||||||
|
|
||||||
#elif defined(__ARMCC_VERSION) && !defined(__clang__)
|
|
||||||
# define COMPILER_ID "ARMCC"
|
|
||||||
#if __ARMCC_VERSION >= 1000000
|
|
||||||
/* __ARMCC_VERSION = VRRPPPP */
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/1000000)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 100)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
|
|
||||||
#else
|
|
||||||
/* __ARMCC_VERSION = VRPPPP */
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/100000)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 10)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#elif defined(__clang__) && defined(__apple_build_version__)
|
|
||||||
# define COMPILER_ID "AppleClang"
|
|
||||||
# if defined(_MSC_VER)
|
|
||||||
# define SIMULATE_ID "MSVC"
|
|
||||||
# endif
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
|
|
||||||
# if defined(_MSC_VER)
|
|
||||||
/* _MSC_VER = VVRR */
|
|
||||||
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
|
|
||||||
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
|
|
||||||
# endif
|
|
||||||
# define COMPILER_VERSION_TWEAK DEC(__apple_build_version__)
|
|
||||||
|
|
||||||
#elif defined(__clang__) && defined(__ARMCOMPILER_VERSION)
|
|
||||||
# define COMPILER_ID "ARMClang"
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__ARMCOMPILER_VERSION/1000000)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__ARMCOMPILER_VERSION/10000 % 100)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__ARMCOMPILER_VERSION % 10000)
|
|
||||||
# define COMPILER_VERSION_INTERNAL DEC(__ARMCOMPILER_VERSION)
|
|
||||||
|
|
||||||
#elif defined(__clang__)
|
|
||||||
# define COMPILER_ID "Clang"
|
|
||||||
# if defined(_MSC_VER)
|
|
||||||
# define SIMULATE_ID "MSVC"
|
|
||||||
# endif
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
|
|
||||||
# if defined(_MSC_VER)
|
|
||||||
/* _MSC_VER = VVRR */
|
|
||||||
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
|
|
||||||
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__GNUC__) || defined(__GNUG__)
|
|
||||||
# define COMPILER_ID "GNU"
|
|
||||||
# if defined(__GNUC__)
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__GNUC__)
|
|
||||||
# else
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(__GNUG__)
|
|
||||||
# endif
|
|
||||||
# if defined(__GNUC_MINOR__)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__)
|
|
||||||
# endif
|
|
||||||
# if defined(__GNUC_PATCHLEVEL__)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
# define COMPILER_ID "MSVC"
|
|
||||||
/* _MSC_VER = VVRR */
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100)
|
|
||||||
# if defined(_MSC_FULL_VER)
|
|
||||||
# if _MSC_VER >= 1400
|
|
||||||
/* _MSC_FULL_VER = VVRRPPPPP */
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000)
|
|
||||||
# else
|
|
||||||
/* _MSC_FULL_VER = VVRRPPPP */
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000)
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# if defined(_MSC_BUILD)
|
|
||||||
# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__VISUALDSPVERSION__) || defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__)
|
|
||||||
# define COMPILER_ID "ADSP"
|
|
||||||
#if defined(__VISUALDSPVERSION__)
|
|
||||||
/* __VISUALDSPVERSION__ = 0xVVRRPP00 */
|
|
||||||
# define COMPILER_VERSION_MAJOR HEX(__VISUALDSPVERSION__>>24)
|
|
||||||
# define COMPILER_VERSION_MINOR HEX(__VISUALDSPVERSION__>>16 & 0xFF)
|
|
||||||
# define COMPILER_VERSION_PATCH HEX(__VISUALDSPVERSION__>>8 & 0xFF)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
|
|
||||||
# define COMPILER_ID "IAR"
|
|
||||||
# if defined(__VER__) && defined(__ICCARM__)
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 1000000)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC(((__VER__) / 1000) % 1000)
|
|
||||||
# define COMPILER_VERSION_PATCH DEC((__VER__) % 1000)
|
|
||||||
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
|
|
||||||
# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__) || defined(__ICCRISCV__) || defined(__ICCV850__) || defined(__ICC8051__) || defined(__ICCSTM8__))
|
|
||||||
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 100)
|
|
||||||
# define COMPILER_VERSION_MINOR DEC((__VER__) - (((__VER__) / 100)*100))
|
|
||||||
# define COMPILER_VERSION_PATCH DEC(__SUBVERSION__)
|
|
||||||
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
|
|
||||||
/* These compilers are either not known or too old to define an
|
|
||||||
identification macro. Try to identify the platform and guess that
|
|
||||||
it is the native compiler. */
|
|
||||||
#elif defined(__hpux) || defined(__hpua)
|
|
||||||
# define COMPILER_ID "HP"
|
|
||||||
|
|
||||||
#else /* unknown compiler */
|
|
||||||
# define COMPILER_ID ""
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Construct the string literal in pieces to prevent the source from
|
|
||||||
getting matched. Store it in a pointer rather than an array
|
|
||||||
because some compilers will just produce instructions to fill the
|
|
||||||
array rather than assigning a pointer to a static array. */
|
|
||||||
char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
|
|
||||||
#ifdef SIMULATE_ID
|
|
||||||
char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __QNXNTO__
|
|
||||||
char const* qnxnto = "INFO" ":" "qnxnto[]";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
|
|
||||||
char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define STRINGIFY_HELPER(X) #X
|
|
||||||
#define STRINGIFY(X) STRINGIFY_HELPER(X)
|
|
||||||
|
|
||||||
/* Identify known platforms by name. */
|
|
||||||
#if defined(__linux) || defined(__linux__) || defined(linux)
|
|
||||||
# define PLATFORM_ID "Linux"
|
|
||||||
|
|
||||||
#elif defined(__MSYS__)
|
|
||||||
# define PLATFORM_ID "MSYS"
|
|
||||||
|
|
||||||
#elif defined(__CYGWIN__)
|
|
||||||
# define PLATFORM_ID "Cygwin"
|
|
||||||
|
|
||||||
#elif defined(__MINGW32__)
|
|
||||||
# define PLATFORM_ID "MinGW"
|
|
||||||
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
# define PLATFORM_ID "Darwin"
|
|
||||||
|
|
||||||
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
|
|
||||||
# define PLATFORM_ID "Windows"
|
|
||||||
|
|
||||||
#elif defined(__FreeBSD__) || defined(__FreeBSD)
|
|
||||||
# define PLATFORM_ID "FreeBSD"
|
|
||||||
|
|
||||||
#elif defined(__NetBSD__) || defined(__NetBSD)
|
|
||||||
# define PLATFORM_ID "NetBSD"
|
|
||||||
|
|
||||||
#elif defined(__OpenBSD__) || defined(__OPENBSD)
|
|
||||||
# define PLATFORM_ID "OpenBSD"
|
|
||||||
|
|
||||||
#elif defined(__sun) || defined(sun)
|
|
||||||
# define PLATFORM_ID "SunOS"
|
|
||||||
|
|
||||||
#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__)
|
|
||||||
# define PLATFORM_ID "AIX"
|
|
||||||
|
|
||||||
#elif defined(__hpux) || defined(__hpux__)
|
|
||||||
# define PLATFORM_ID "HP-UX"
|
|
||||||
|
|
||||||
#elif defined(__HAIKU__)
|
|
||||||
# define PLATFORM_ID "Haiku"
|
|
||||||
|
|
||||||
#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
|
|
||||||
# define PLATFORM_ID "BeOS"
|
|
||||||
|
|
||||||
#elif defined(__QNX__) || defined(__QNXNTO__)
|
|
||||||
# define PLATFORM_ID "QNX"
|
|
||||||
|
|
||||||
#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__)
|
|
||||||
# define PLATFORM_ID "Tru64"
|
|
||||||
|
|
||||||
#elif defined(__riscos) || defined(__riscos__)
|
|
||||||
# define PLATFORM_ID "RISCos"
|
|
||||||
|
|
||||||
#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__)
|
|
||||||
# define PLATFORM_ID "SINIX"
|
|
||||||
|
|
||||||
#elif defined(__UNIX_SV__)
|
|
||||||
# define PLATFORM_ID "UNIX_SV"
|
|
||||||
|
|
||||||
#elif defined(__bsdos__)
|
|
||||||
# define PLATFORM_ID "BSDOS"
|
|
||||||
|
|
||||||
#elif defined(_MPRAS) || defined(MPRAS)
|
|
||||||
# define PLATFORM_ID "MP-RAS"
|
|
||||||
|
|
||||||
#elif defined(__osf) || defined(__osf__)
|
|
||||||
# define PLATFORM_ID "OSF1"
|
|
||||||
|
|
||||||
#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv)
|
|
||||||
# define PLATFORM_ID "SCO_SV"
|
|
||||||
|
|
||||||
#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX)
|
|
||||||
# define PLATFORM_ID "ULTRIX"
|
|
||||||
|
|
||||||
#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX)
|
|
||||||
# define PLATFORM_ID "Xenix"
|
|
||||||
|
|
||||||
#elif defined(__WATCOMC__)
|
|
||||||
# if defined(__LINUX__)
|
|
||||||
# define PLATFORM_ID "Linux"
|
|
||||||
|
|
||||||
# elif defined(__DOS__)
|
|
||||||
# define PLATFORM_ID "DOS"
|
|
||||||
|
|
||||||
# elif defined(__OS2__)
|
|
||||||
# define PLATFORM_ID "OS2"
|
|
||||||
|
|
||||||
# elif defined(__WINDOWS__)
|
|
||||||
# define PLATFORM_ID "Windows3x"
|
|
||||||
|
|
||||||
# elif defined(__VXWORKS__)
|
|
||||||
# define PLATFORM_ID "VxWorks"
|
|
||||||
|
|
||||||
# else /* unknown platform */
|
|
||||||
# define PLATFORM_ID
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__INTEGRITY)
|
|
||||||
# if defined(INT_178B)
|
|
||||||
# define PLATFORM_ID "Integrity178"
|
|
||||||
|
|
||||||
# else /* regular Integrity */
|
|
||||||
# define PLATFORM_ID "Integrity"
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#else /* unknown platform */
|
|
||||||
# define PLATFORM_ID
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* For windows compilers MSVC and Intel we can determine
|
|
||||||
the architecture of the compiler being used. This is because
|
|
||||||
the compilers do not have flags that can change the architecture,
|
|
||||||
but rather depend on which compiler is being used
|
|
||||||
*/
|
|
||||||
#if defined(_WIN32) && defined(_MSC_VER)
|
|
||||||
# if defined(_M_IA64)
|
|
||||||
# define ARCHITECTURE_ID "IA64"
|
|
||||||
|
|
||||||
# elif defined(_M_ARM64EC)
|
|
||||||
# define ARCHITECTURE_ID "ARM64EC"
|
|
||||||
|
|
||||||
# elif defined(_M_X64) || defined(_M_AMD64)
|
|
||||||
# define ARCHITECTURE_ID "x64"
|
|
||||||
|
|
||||||
# elif defined(_M_IX86)
|
|
||||||
# define ARCHITECTURE_ID "X86"
|
|
||||||
|
|
||||||
# elif defined(_M_ARM64)
|
|
||||||
# define ARCHITECTURE_ID "ARM64"
|
|
||||||
|
|
||||||
# elif defined(_M_ARM)
|
|
||||||
# if _M_ARM == 4
|
|
||||||
# define ARCHITECTURE_ID "ARMV4I"
|
|
||||||
# elif _M_ARM == 5
|
|
||||||
# define ARCHITECTURE_ID "ARMV5I"
|
|
||||||
# else
|
|
||||||
# define ARCHITECTURE_ID "ARMV" STRINGIFY(_M_ARM)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# elif defined(_M_MIPS)
|
|
||||||
# define ARCHITECTURE_ID "MIPS"
|
|
||||||
|
|
||||||
# elif defined(_M_SH)
|
|
||||||
# define ARCHITECTURE_ID "SHx"
|
|
||||||
|
|
||||||
# else /* unknown architecture */
|
|
||||||
# define ARCHITECTURE_ID ""
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__WATCOMC__)
|
|
||||||
# if defined(_M_I86)
|
|
||||||
# define ARCHITECTURE_ID "I86"
|
|
||||||
|
|
||||||
# elif defined(_M_IX86)
|
|
||||||
# define ARCHITECTURE_ID "X86"
|
|
||||||
|
|
||||||
# else /* unknown architecture */
|
|
||||||
# define ARCHITECTURE_ID ""
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
|
|
||||||
# if defined(__ICCARM__)
|
|
||||||
# define ARCHITECTURE_ID "ARM"
|
|
||||||
|
|
||||||
# elif defined(__ICCRX__)
|
|
||||||
# define ARCHITECTURE_ID "RX"
|
|
||||||
|
|
||||||
# elif defined(__ICCRH850__)
|
|
||||||
# define ARCHITECTURE_ID "RH850"
|
|
||||||
|
|
||||||
# elif defined(__ICCRL78__)
|
|
||||||
# define ARCHITECTURE_ID "RL78"
|
|
||||||
|
|
||||||
# elif defined(__ICCRISCV__)
|
|
||||||
# define ARCHITECTURE_ID "RISCV"
|
|
||||||
|
|
||||||
# elif defined(__ICCAVR__)
|
|
||||||
# define ARCHITECTURE_ID "AVR"
|
|
||||||
|
|
||||||
# elif defined(__ICC430__)
|
|
||||||
# define ARCHITECTURE_ID "MSP430"
|
|
||||||
|
|
||||||
# elif defined(__ICCV850__)
|
|
||||||
# define ARCHITECTURE_ID "V850"
|
|
||||||
|
|
||||||
# elif defined(__ICC8051__)
|
|
||||||
# define ARCHITECTURE_ID "8051"
|
|
||||||
|
|
||||||
# elif defined(__ICCSTM8__)
|
|
||||||
# define ARCHITECTURE_ID "STM8"
|
|
||||||
|
|
||||||
# else /* unknown architecture */
|
|
||||||
# define ARCHITECTURE_ID ""
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__ghs__)
|
|
||||||
# if defined(__PPC64__)
|
|
||||||
# define ARCHITECTURE_ID "PPC64"
|
|
||||||
|
|
||||||
# elif defined(__ppc__)
|
|
||||||
# define ARCHITECTURE_ID "PPC"
|
|
||||||
|
|
||||||
# elif defined(__ARM__)
|
|
||||||
# define ARCHITECTURE_ID "ARM"
|
|
||||||
|
|
||||||
# elif defined(__x86_64__)
|
|
||||||
# define ARCHITECTURE_ID "x64"
|
|
||||||
|
|
||||||
# elif defined(__i386__)
|
|
||||||
# define ARCHITECTURE_ID "X86"
|
|
||||||
|
|
||||||
# else /* unknown architecture */
|
|
||||||
# define ARCHITECTURE_ID ""
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(__TI_COMPILER_VERSION__)
|
|
||||||
# if defined(__TI_ARM__)
|
|
||||||
# define ARCHITECTURE_ID "ARM"
|
|
||||||
|
|
||||||
# elif defined(__MSP430__)
|
|
||||||
# define ARCHITECTURE_ID "MSP430"
|
|
||||||
|
|
||||||
# elif defined(__TMS320C28XX__)
|
|
||||||
# define ARCHITECTURE_ID "TMS320C28x"
|
|
||||||
|
|
||||||
# elif defined(__TMS320C6X__) || defined(_TMS320C6X)
|
|
||||||
# define ARCHITECTURE_ID "TMS320C6x"
|
|
||||||
|
|
||||||
# else /* unknown architecture */
|
|
||||||
# define ARCHITECTURE_ID ""
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
# define ARCHITECTURE_ID
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Convert integer to decimal digit literals. */
|
|
||||||
#define DEC(n) \
|
|
||||||
('0' + (((n) / 10000000)%10)), \
|
|
||||||
('0' + (((n) / 1000000)%10)), \
|
|
||||||
('0' + (((n) / 100000)%10)), \
|
|
||||||
('0' + (((n) / 10000)%10)), \
|
|
||||||
('0' + (((n) / 1000)%10)), \
|
|
||||||
('0' + (((n) / 100)%10)), \
|
|
||||||
('0' + (((n) / 10)%10)), \
|
|
||||||
('0' + ((n) % 10))
|
|
||||||
|
|
||||||
/* Convert integer to hex digit literals. */
|
|
||||||
#define HEX(n) \
|
|
||||||
('0' + ((n)>>28 & 0xF)), \
|
|
||||||
('0' + ((n)>>24 & 0xF)), \
|
|
||||||
('0' + ((n)>>20 & 0xF)), \
|
|
||||||
('0' + ((n)>>16 & 0xF)), \
|
|
||||||
('0' + ((n)>>12 & 0xF)), \
|
|
||||||
('0' + ((n)>>8 & 0xF)), \
|
|
||||||
('0' + ((n)>>4 & 0xF)), \
|
|
||||||
('0' + ((n) & 0xF))
|
|
||||||
|
|
||||||
/* Construct a string literal encoding the version number. */
|
|
||||||
#ifdef COMPILER_VERSION
|
|
||||||
char const* info_version = "INFO" ":" "compiler_version[" COMPILER_VERSION "]";
|
|
||||||
|
|
||||||
/* Construct a string literal encoding the version number components. */
|
|
||||||
#elif defined(COMPILER_VERSION_MAJOR)
|
|
||||||
char const info_version[] = {
|
|
||||||
'I', 'N', 'F', 'O', ':',
|
|
||||||
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[',
|
|
||||||
COMPILER_VERSION_MAJOR,
|
|
||||||
# ifdef COMPILER_VERSION_MINOR
|
|
||||||
'.', COMPILER_VERSION_MINOR,
|
|
||||||
# ifdef COMPILER_VERSION_PATCH
|
|
||||||
'.', COMPILER_VERSION_PATCH,
|
|
||||||
# ifdef COMPILER_VERSION_TWEAK
|
|
||||||
'.', COMPILER_VERSION_TWEAK,
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
']','\0'};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Construct a string literal encoding the internal version number. */
|
|
||||||
#ifdef COMPILER_VERSION_INTERNAL
|
|
||||||
char const info_version_internal[] = {
|
|
||||||
'I', 'N', 'F', 'O', ':',
|
|
||||||
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','_',
|
|
||||||
'i','n','t','e','r','n','a','l','[',
|
|
||||||
COMPILER_VERSION_INTERNAL,']','\0'};
|
|
||||||
#elif defined(COMPILER_VERSION_INTERNAL_STR)
|
|
||||||
char const* info_version_internal = "INFO" ":" "compiler_version_internal[" COMPILER_VERSION_INTERNAL_STR "]";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Construct a string literal encoding the version number components. */
|
|
||||||
#ifdef SIMULATE_VERSION_MAJOR
|
|
||||||
char const info_simulate_version[] = {
|
|
||||||
'I', 'N', 'F', 'O', ':',
|
|
||||||
's','i','m','u','l','a','t','e','_','v','e','r','s','i','o','n','[',
|
|
||||||
SIMULATE_VERSION_MAJOR,
|
|
||||||
# ifdef SIMULATE_VERSION_MINOR
|
|
||||||
'.', SIMULATE_VERSION_MINOR,
|
|
||||||
# ifdef SIMULATE_VERSION_PATCH
|
|
||||||
'.', SIMULATE_VERSION_PATCH,
|
|
||||||
# ifdef SIMULATE_VERSION_TWEAK
|
|
||||||
'.', SIMULATE_VERSION_TWEAK,
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
']','\0'};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Construct the string literal in pieces to prevent the source from
|
|
||||||
getting matched. Store it in a pointer rather than an array
|
|
||||||
because some compilers will just produce instructions to fill the
|
|
||||||
array rather than assigning a pointer to a static array. */
|
|
||||||
char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]";
|
|
||||||
char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(__INTEL_COMPILER) && defined(_MSVC_LANG) && _MSVC_LANG < 201403L
|
|
||||||
# if defined(__INTEL_CXX11_MODE__)
|
|
||||||
# if defined(__cpp_aggregate_nsdmi)
|
|
||||||
# define CXX_STD 201402L
|
|
||||||
# else
|
|
||||||
# define CXX_STD 201103L
|
|
||||||
# endif
|
|
||||||
# else
|
|
||||||
# define CXX_STD 199711L
|
|
||||||
# endif
|
|
||||||
#elif defined(_MSC_VER) && defined(_MSVC_LANG)
|
|
||||||
# define CXX_STD _MSVC_LANG
|
|
||||||
#else
|
|
||||||
# define CXX_STD __cplusplus
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const char* info_language_standard_default = "INFO" ":" "standard_default["
|
|
||||||
#if CXX_STD > 202002L
|
|
||||||
"23"
|
|
||||||
#elif CXX_STD > 201703L
|
|
||||||
"20"
|
|
||||||
#elif CXX_STD >= 201703L
|
|
||||||
"17"
|
|
||||||
#elif CXX_STD >= 201402L
|
|
||||||
"14"
|
|
||||||
#elif CXX_STD >= 201103L
|
|
||||||
"11"
|
|
||||||
#else
|
|
||||||
"98"
|
|
||||||
#endif
|
|
||||||
"]";
|
|
||||||
|
|
||||||
const char* info_language_extensions_default = "INFO" ":" "extensions_default["
|
|
||||||
/* !defined(_MSC_VER) to exclude Clang's MSVC compatibility mode. */
|
|
||||||
#if (defined(__clang__) || defined(__GNUC__) || \
|
|
||||||
defined(__TI_COMPILER_VERSION__)) && \
|
|
||||||
!defined(__STRICT_ANSI__) && !defined(_MSC_VER)
|
|
||||||
"ON"
|
|
||||||
#else
|
|
||||||
"OFF"
|
|
||||||
#endif
|
|
||||||
"]";
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
|
||||||
{
|
|
||||||
int require = 0;
|
|
||||||
require += info_compiler[argc];
|
|
||||||
require += info_platform[argc];
|
|
||||||
#ifdef COMPILER_VERSION_MAJOR
|
|
||||||
require += info_version[argc];
|
|
||||||
#endif
|
|
||||||
#ifdef COMPILER_VERSION_INTERNAL
|
|
||||||
require += info_version_internal[argc];
|
|
||||||
#endif
|
|
||||||
#ifdef SIMULATE_ID
|
|
||||||
require += info_simulate[argc];
|
|
||||||
#endif
|
|
||||||
#ifdef SIMULATE_VERSION_MAJOR
|
|
||||||
require += info_simulate_version[argc];
|
|
||||||
#endif
|
|
||||||
#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
|
|
||||||
require += info_cray[argc];
|
|
||||||
#endif
|
|
||||||
require += info_language_standard_default[argc];
|
|
||||||
require += info_language_extensions_default[argc];
|
|
||||||
(void)argv;
|
|
||||||
return require;
|
|
||||||
}
|
|
||||||
Binary file not shown.
@ -1,3 +0,0 @@
|
|||||||
/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/appmodules.dir
|
|
||||||
/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/edit_cache.dir
|
|
||||||
/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/rebuild_cache.dir
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
# CMAKE generated file: DO NOT EDIT!
|
|
||||||
# Generated by CMake Version 3.22
|
|
||||||
cmake_policy(SET CMP0009 NEW)
|
|
||||||
|
|
||||||
# input_SRC at /home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake:55 (file)
|
|
||||||
file(GLOB NEW_GLOB LIST_DIRECTORIES true "/home/echo/dev/prototype/apps/mobile/android/app/build/generated/autolinking/src/main/jni/*.cpp")
|
|
||||||
set(OLD_GLOB
|
|
||||||
)
|
|
||||||
if(NOT "${NEW_GLOB}" STREQUAL "${OLD_GLOB}")
|
|
||||||
message("-- GLOB mismatch!")
|
|
||||||
file(TOUCH_NOCREATE "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/cmake.verify_globs")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# override_cpp_SRC at /home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake:50 (file)
|
|
||||||
# input_SRC at /home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake:55 (file)
|
|
||||||
file(GLOB NEW_GLOB LIST_DIRECTORIES true "/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/default-app-setup/*.cpp")
|
|
||||||
set(OLD_GLOB
|
|
||||||
"/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/default-app-setup/OnLoad.cpp"
|
|
||||||
)
|
|
||||||
if(NOT "${NEW_GLOB}" STREQUAL "${OLD_GLOB}")
|
|
||||||
message("-- GLOB mismatch!")
|
|
||||||
file(TOUCH_NOCREATE "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/cmake.verify_globs")
|
|
||||||
endif()
|
|
||||||
Binary file not shown.
@ -1,4 +0,0 @@
|
|||||||
# ninja log v5
|
|
||||||
0 17 1764608951217248929 CMakeFiles/foo.dir/foo.cpp.o cf03112569101c0d
|
|
||||||
0 17 1764608951217248929 CMakeFiles/boo.dir/main.cpp.o a40c4ac8f9333fbb
|
|
||||||
17 47 1764608951246597989 libfoo.a 46ab43a90edc58a3
|
|
||||||
@ -1,281 +0,0 @@
|
|||||||
# This is the CMakeCache file.
|
|
||||||
# For build in directory: /home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/bin
|
|
||||||
# It was generated by CMake: /home/echo/Android/Sdk/cmake/3.22.1/bin/cmake
|
|
||||||
# You can edit this file to change values found and used by cmake.
|
|
||||||
# If you do not want to change any of the values, simply exit the editor.
|
|
||||||
# If you do want to change a value, simply edit, save, and exit the editor.
|
|
||||||
# The syntax for the file is as follows:
|
|
||||||
# KEY:TYPE=VALUE
|
|
||||||
# KEY is the name of a variable in the cache.
|
|
||||||
# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!.
|
|
||||||
# VALUE is the current value for the KEY.
|
|
||||||
|
|
||||||
########################
|
|
||||||
# EXTERNAL cache entries
|
|
||||||
########################
|
|
||||||
|
|
||||||
//Archiver
|
|
||||||
CMAKE_AR:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar
|
|
||||||
|
|
||||||
//Flags used by the compiler during all build types.
|
|
||||||
CMAKE_ASM_FLAGS:STRING=
|
|
||||||
|
|
||||||
//Flags used by the compiler during debug builds.
|
|
||||||
CMAKE_ASM_FLAGS_DEBUG:STRING=
|
|
||||||
|
|
||||||
//Flags used by the compiler during release builds.
|
|
||||||
CMAKE_ASM_FLAGS_RELEASE:STRING=
|
|
||||||
|
|
||||||
//Choose the type of build, options are: None Debug Release RelWithDebInfo
|
|
||||||
// MinSizeRel ...
|
|
||||||
CMAKE_BUILD_TYPE:STRING=
|
|
||||||
|
|
||||||
//Flags used by the compiler during all build types.
|
|
||||||
CMAKE_CXX_FLAGS:STRING=
|
|
||||||
|
|
||||||
//Flags used by the compiler during debug builds.
|
|
||||||
CMAKE_CXX_FLAGS_DEBUG:STRING=
|
|
||||||
|
|
||||||
//Flags used by the CXX compiler during MINSIZEREL builds.
|
|
||||||
CMAKE_CXX_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
|
|
||||||
|
|
||||||
//Flags used by the compiler during release builds.
|
|
||||||
CMAKE_CXX_FLAGS_RELEASE:STRING=
|
|
||||||
|
|
||||||
//Flags used by the CXX compiler during RELWITHDEBINFO builds.
|
|
||||||
CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
|
|
||||||
|
|
||||||
//Libraries linked by default with all C++ applications.
|
|
||||||
CMAKE_CXX_STANDARD_LIBRARIES:STRING=-latomic -lm
|
|
||||||
|
|
||||||
//Flags used by the compiler during all build types.
|
|
||||||
CMAKE_C_FLAGS:STRING=
|
|
||||||
|
|
||||||
//Flags used by the compiler during debug builds.
|
|
||||||
CMAKE_C_FLAGS_DEBUG:STRING=
|
|
||||||
|
|
||||||
//Flags used by the compiler during release builds.
|
|
||||||
CMAKE_C_FLAGS_RELEASE:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker.
|
|
||||||
CMAKE_EXE_LINKER_FLAGS:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during DEBUG builds.
|
|
||||||
CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during MINSIZEREL builds.
|
|
||||||
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during RELEASE builds.
|
|
||||||
CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during RELWITHDEBINFO builds.
|
|
||||||
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
|
|
||||||
|
|
||||||
//Enable/Disable output of compile commands during generation.
|
|
||||||
CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=
|
|
||||||
|
|
||||||
//Install path prefix, prepended onto install directories.
|
|
||||||
CMAKE_INSTALL_PREFIX:PATH=/usr/local
|
|
||||||
|
|
||||||
//No help, variable specified on the command line.
|
|
||||||
CMAKE_INTERPROCEDURAL_OPTIMIZATION:UNINITIALIZED=ON
|
|
||||||
|
|
||||||
//make program
|
|
||||||
CMAKE_MAKE_PROGRAM:FILEPATH=/home/echo/Android/Sdk/cmake/3.22.1/bin/ninja
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of modules.
|
|
||||||
CMAKE_MODULE_LINKER_FLAGS:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of modules during
|
|
||||||
// DEBUG builds.
|
|
||||||
CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of modules during
|
|
||||||
// MINSIZEREL builds.
|
|
||||||
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of modules during
|
|
||||||
// RELEASE builds.
|
|
||||||
CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of modules during
|
|
||||||
// RELWITHDEBINFO builds.
|
|
||||||
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
|
|
||||||
|
|
||||||
//Value Computed by CMake
|
|
||||||
CMAKE_PROJECT_DESCRIPTION:STATIC=
|
|
||||||
|
|
||||||
//Value Computed by CMake
|
|
||||||
CMAKE_PROJECT_HOMEPAGE_URL:STATIC=
|
|
||||||
|
|
||||||
//Value Computed by CMake
|
|
||||||
CMAKE_PROJECT_NAME:STATIC=lto-test
|
|
||||||
|
|
||||||
//Ranlib
|
|
||||||
CMAKE_RANLIB:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of dll's.
|
|
||||||
CMAKE_SHARED_LINKER_FLAGS:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of shared libraries
|
|
||||||
// during DEBUG builds.
|
|
||||||
CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of shared libraries
|
|
||||||
// during MINSIZEREL builds.
|
|
||||||
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of shared libraries
|
|
||||||
// during RELEASE builds.
|
|
||||||
CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of shared libraries
|
|
||||||
// during RELWITHDEBINFO builds.
|
|
||||||
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING=
|
|
||||||
|
|
||||||
//If set, runtime paths are not added when installing shared libraries,
|
|
||||||
// but are added when building.
|
|
||||||
CMAKE_SKIP_INSTALL_RPATH:BOOL=NO
|
|
||||||
|
|
||||||
//If set, runtime paths are not added when using shared libraries.
|
|
||||||
CMAKE_SKIP_RPATH:BOOL=NO
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of static libraries
|
|
||||||
// during all build types.
|
|
||||||
CMAKE_STATIC_LINKER_FLAGS:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of static libraries
|
|
||||||
// during DEBUG builds.
|
|
||||||
CMAKE_STATIC_LINKER_FLAGS_DEBUG:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of static libraries
|
|
||||||
// during MINSIZEREL builds.
|
|
||||||
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of static libraries
|
|
||||||
// during RELEASE builds.
|
|
||||||
CMAKE_STATIC_LINKER_FLAGS_RELEASE:STRING=
|
|
||||||
|
|
||||||
//Flags used by the linker during the creation of static libraries
|
|
||||||
// during RELWITHDEBINFO builds.
|
|
||||||
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING=
|
|
||||||
|
|
||||||
//Strip
|
|
||||||
CMAKE_STRIP:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip
|
|
||||||
|
|
||||||
//If this value is on, makefiles will be generated without the
|
|
||||||
// .SILENT directive, and all commands will be echoed to the console
|
|
||||||
// during the make. This is useful for debugging only. With Visual
|
|
||||||
// Studio IDE projects all commands are done without /nologo.
|
|
||||||
CMAKE_VERBOSE_MAKEFILE:BOOL=ON
|
|
||||||
|
|
||||||
//Value Computed by CMake
|
|
||||||
lto-test_BINARY_DIR:STATIC=/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/bin
|
|
||||||
|
|
||||||
//Value Computed by CMake
|
|
||||||
lto-test_IS_TOP_LEVEL:STATIC=ON
|
|
||||||
|
|
||||||
//Value Computed by CMake
|
|
||||||
lto-test_SOURCE_DIR:STATIC=/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/src
|
|
||||||
|
|
||||||
|
|
||||||
########################
|
|
||||||
# INTERNAL cache entries
|
|
||||||
########################
|
|
||||||
|
|
||||||
//This is the directory where this CMakeCache.txt was created
|
|
||||||
CMAKE_CACHEFILE_DIR:INTERNAL=/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/bin
|
|
||||||
//Major version of cmake used to create the current loaded cache
|
|
||||||
CMAKE_CACHE_MAJOR_VERSION:INTERNAL=3
|
|
||||||
//Minor version of cmake used to create the current loaded cache
|
|
||||||
CMAKE_CACHE_MINOR_VERSION:INTERNAL=22
|
|
||||||
//Patch version of cmake used to create the current loaded cache
|
|
||||||
CMAKE_CACHE_PATCH_VERSION:INTERNAL=1
|
|
||||||
//Path to CMake executable.
|
|
||||||
CMAKE_COMMAND:INTERNAL=/home/echo/Android/Sdk/cmake/3.22.1/bin/cmake
|
|
||||||
//Path to cpack program executable.
|
|
||||||
CMAKE_CPACK_COMMAND:INTERNAL=/home/echo/Android/Sdk/cmake/3.22.1/bin/cpack
|
|
||||||
//Path to ctest program executable.
|
|
||||||
CMAKE_CTEST_COMMAND:INTERNAL=/home/echo/Android/Sdk/cmake/3.22.1/bin/ctest
|
|
||||||
//ADVANCED property for variable: CMAKE_CXX_FLAGS
|
|
||||||
CMAKE_CXX_FLAGS-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_CXX_FLAGS_DEBUG
|
|
||||||
CMAKE_CXX_FLAGS_DEBUG-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_CXX_FLAGS_MINSIZEREL
|
|
||||||
CMAKE_CXX_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELEASE
|
|
||||||
CMAKE_CXX_FLAGS_RELEASE-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
|
||||||
CMAKE_CXX_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_CXX_STANDARD_LIBRARIES
|
|
||||||
CMAKE_CXX_STANDARD_LIBRARIES-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS
|
|
||||||
CMAKE_EXE_LINKER_FLAGS-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_DEBUG
|
|
||||||
CMAKE_EXE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_MINSIZEREL
|
|
||||||
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELEASE
|
|
||||||
CMAKE_EXE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO
|
|
||||||
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_EXPORT_COMPILE_COMMANDS
|
|
||||||
CMAKE_EXPORT_COMPILE_COMMANDS-ADVANCED:INTERNAL=1
|
|
||||||
//Name of external makefile project generator.
|
|
||||||
CMAKE_EXTRA_GENERATOR:INTERNAL=
|
|
||||||
//Name of generator.
|
|
||||||
CMAKE_GENERATOR:INTERNAL=Ninja
|
|
||||||
//Generator instance identifier.
|
|
||||||
CMAKE_GENERATOR_INSTANCE:INTERNAL=
|
|
||||||
//Name of generator platform.
|
|
||||||
CMAKE_GENERATOR_PLATFORM:INTERNAL=
|
|
||||||
//Name of generator toolset.
|
|
||||||
CMAKE_GENERATOR_TOOLSET:INTERNAL=
|
|
||||||
//Source directory with the top level CMakeLists.txt file for this
|
|
||||||
// project
|
|
||||||
CMAKE_HOME_DIRECTORY:INTERNAL=/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/src
|
|
||||||
//Install .so files without execute permission.
|
|
||||||
CMAKE_INSTALL_SO_NO_EXE:INTERNAL=0
|
|
||||||
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS
|
|
||||||
CMAKE_MODULE_LINKER_FLAGS-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_DEBUG
|
|
||||||
CMAKE_MODULE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL
|
|
||||||
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELEASE
|
|
||||||
CMAKE_MODULE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO
|
|
||||||
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
|
|
||||||
//number of local generators
|
|
||||||
CMAKE_NUMBER_OF_MAKEFILES:INTERNAL=1
|
|
||||||
//Path to CMake installation.
|
|
||||||
CMAKE_ROOT:INTERNAL=/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22
|
|
||||||
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS
|
|
||||||
CMAKE_SHARED_LINKER_FLAGS-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_DEBUG
|
|
||||||
CMAKE_SHARED_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL
|
|
||||||
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELEASE
|
|
||||||
CMAKE_SHARED_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO
|
|
||||||
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_SKIP_INSTALL_RPATH
|
|
||||||
CMAKE_SKIP_INSTALL_RPATH-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_SKIP_RPATH
|
|
||||||
CMAKE_SKIP_RPATH-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS
|
|
||||||
CMAKE_STATIC_LINKER_FLAGS-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_DEBUG
|
|
||||||
CMAKE_STATIC_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL
|
|
||||||
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELEASE
|
|
||||||
CMAKE_STATIC_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
|
|
||||||
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO
|
|
||||||
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
|
|
||||||
CMAKE_SUPPRESS_DEVELOPER_WARNINGS:INTERNAL=FALSE
|
|
||||||
//ADVANCED property for variable: CMAKE_VERBOSE_MAKEFILE
|
|
||||||
CMAKE_VERBOSE_MAKEFILE-ADVANCED:INTERNAL=1
|
|
||||||
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/bin/CMakeFiles/foo.dir
|
|
||||||
/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/bin/CMakeFiles/boo.dir
|
|
||||||
/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/bin/CMakeFiles/edit_cache.dir
|
|
||||||
/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/bin/CMakeFiles/rebuild_cache.dir
|
|
||||||
Binary file not shown.
@ -1 +0,0 @@
|
|||||||
# This file is generated by cmake for dependency checking of the CMakeCache.txt file
|
|
||||||
Binary file not shown.
@ -1,83 +0,0 @@
|
|||||||
# CMAKE generated file: DO NOT EDIT!
|
|
||||||
# Generated by "Ninja" Generator, CMake Version 3.22
|
|
||||||
|
|
||||||
# This file contains all the rules used to get the outputs files
|
|
||||||
# built from the input files.
|
|
||||||
# It is included in the main 'build.ninja'.
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Project: lto-test
|
|
||||||
# Configurations:
|
|
||||||
# =============================================================================
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Rule for compiling CXX files.
|
|
||||||
|
|
||||||
rule CXX_COMPILER__foo_
|
|
||||||
depfile = $DEP_FILE
|
|
||||||
deps = gcc
|
|
||||||
command = /home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --target=armv7-none-linux-androideabi21 --sysroot=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot $DEFINES $INCLUDES $FLAGS -MD -MT $out -MF $DEP_FILE -o $out -c $in
|
|
||||||
description = Building CXX object $out
|
|
||||||
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Rule for linking CXX static library.
|
|
||||||
|
|
||||||
rule CXX_STATIC_LIBRARY_LINKER__foo_
|
|
||||||
command = $PRE_LINK && /home/echo/Android/Sdk/cmake/3.22.1/bin/cmake -E rm -f $TARGET_FILE && "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar" cr $TARGET_FILE $LINK_FLAGS $in && "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib" $TARGET_FILE && $POST_BUILD
|
|
||||||
description = Linking CXX static library $TARGET_FILE
|
|
||||||
restat = $RESTAT
|
|
||||||
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Rule for compiling CXX files.
|
|
||||||
|
|
||||||
rule CXX_COMPILER__boo_
|
|
||||||
depfile = $DEP_FILE
|
|
||||||
deps = gcc
|
|
||||||
command = /home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --target=armv7-none-linux-androideabi21 --sysroot=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot $DEFINES $INCLUDES $FLAGS -MD -MT $out -MF $DEP_FILE -o $out -c $in
|
|
||||||
description = Building CXX object $out
|
|
||||||
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Rule for linking CXX executable.
|
|
||||||
|
|
||||||
rule CXX_EXECUTABLE_LINKER__boo_
|
|
||||||
command = $PRE_LINK && /home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --target=armv7-none-linux-androideabi21 --sysroot=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot $FLAGS $LINK_FLAGS $in -o $TARGET_FILE $LINK_PATH $LINK_LIBRARIES && $POST_BUILD
|
|
||||||
description = Linking CXX executable $TARGET_FILE
|
|
||||||
restat = $RESTAT
|
|
||||||
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Rule for running custom commands.
|
|
||||||
|
|
||||||
rule CUSTOM_COMMAND
|
|
||||||
command = $COMMAND
|
|
||||||
description = $DESC
|
|
||||||
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Rule for re-running cmake.
|
|
||||||
|
|
||||||
rule RERUN_CMAKE
|
|
||||||
command = /home/echo/Android/Sdk/cmake/3.22.1/bin/cmake --regenerate-during-build -S/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/src -B/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/bin
|
|
||||||
description = Re-running CMake...
|
|
||||||
generator = 1
|
|
||||||
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Rule for cleaning all built files.
|
|
||||||
|
|
||||||
rule CLEAN
|
|
||||||
command = /home/echo/Android/Sdk/cmake/3.22.1/bin/ninja $FILE_ARG -t clean $TARGETS
|
|
||||||
description = Cleaning all built files...
|
|
||||||
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Rule for printing all primary targets available.
|
|
||||||
|
|
||||||
rule HELP
|
|
||||||
command = /home/echo/Android/Sdk/cmake/3.22.1/bin/ninja -t targets
|
|
||||||
description = All primary targets available:
|
|
||||||
|
|
||||||
@ -1,172 +0,0 @@
|
|||||||
# CMAKE generated file: DO NOT EDIT!
|
|
||||||
# Generated by "Ninja" Generator, CMake Version 3.22
|
|
||||||
|
|
||||||
# This file contains all the build statements describing the
|
|
||||||
# compilation DAG.
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Write statements declared in CMakeLists.txt:
|
|
||||||
#
|
|
||||||
# Which is the root file.
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Project: lto-test
|
|
||||||
# Configurations:
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Minimal version of Ninja required by this file
|
|
||||||
|
|
||||||
ninja_required_version = 1.5
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Include auxiliary files.
|
|
||||||
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Include rules file.
|
|
||||||
|
|
||||||
include CMakeFiles/rules.ninja
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Logical path to working directory; prefix for absolute paths.
|
|
||||||
|
|
||||||
cmake_ninja_workdir = /home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/bin/
|
|
||||||
# =============================================================================
|
|
||||||
# Object build statements for STATIC_LIBRARY target foo
|
|
||||||
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Order-only phony target for foo
|
|
||||||
|
|
||||||
build cmake_object_order_depends_target_foo: phony || CMakeFiles/foo.dir
|
|
||||||
|
|
||||||
build CMakeFiles/foo.dir/foo.cpp.o: CXX_COMPILER__foo_ /home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/src/foo.cpp || cmake_object_order_depends_target_foo
|
|
||||||
DEP_FILE = CMakeFiles/foo.dir/foo.cpp.o.d
|
|
||||||
FLAGS = -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -march=armv7-a -mthumb -Wformat -Werror=format-security -flto=thin -fPIC
|
|
||||||
OBJECT_DIR = CMakeFiles/foo.dir
|
|
||||||
OBJECT_FILE_DIR = CMakeFiles/foo.dir
|
|
||||||
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Link build statements for STATIC_LIBRARY target foo
|
|
||||||
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Link the static library libfoo.a
|
|
||||||
|
|
||||||
build libfoo.a: CXX_STATIC_LIBRARY_LINKER__foo_ CMakeFiles/foo.dir/foo.cpp.o
|
|
||||||
LANGUAGE_COMPILE_FLAGS = -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -march=armv7-a -mthumb -Wformat -Werror=format-security -flto=thin
|
|
||||||
OBJECT_DIR = CMakeFiles/foo.dir
|
|
||||||
POST_BUILD = :
|
|
||||||
PRE_LINK = :
|
|
||||||
TARGET_FILE = libfoo.a
|
|
||||||
TARGET_PDB = foo.a.dbg
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Object build statements for EXECUTABLE target boo
|
|
||||||
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Order-only phony target for boo
|
|
||||||
|
|
||||||
build cmake_object_order_depends_target_boo: phony || cmake_object_order_depends_target_foo
|
|
||||||
|
|
||||||
build CMakeFiles/boo.dir/main.cpp.o: CXX_COMPILER__boo_ /home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/src/main.cpp || cmake_object_order_depends_target_boo
|
|
||||||
DEP_FILE = CMakeFiles/boo.dir/main.cpp.o.d
|
|
||||||
FLAGS = -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -march=armv7-a -mthumb -Wformat -Werror=format-security -flto=thin -fPIE
|
|
||||||
OBJECT_DIR = CMakeFiles/boo.dir
|
|
||||||
OBJECT_FILE_DIR = CMakeFiles/boo.dir
|
|
||||||
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Link build statements for EXECUTABLE target boo
|
|
||||||
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Link the executable boo
|
|
||||||
|
|
||||||
build boo: CXX_EXECUTABLE_LINKER__boo_ CMakeFiles/boo.dir/main.cpp.o | libfoo.a || libfoo.a
|
|
||||||
FLAGS = -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -march=armv7-a -mthumb -Wformat -Werror=format-security -flto=thin
|
|
||||||
LINK_FLAGS = -static-libstdc++ -Wl,--build-id=sha1 -Wl,--no-rosegment -Wl,--no-undefined-version -Wl,--fatal-warnings -Wl,--no-undefined -Qunused-arguments -fuse-ld=gold
|
|
||||||
LINK_LIBRARIES = libfoo.a -latomic -lm
|
|
||||||
OBJECT_DIR = CMakeFiles/boo.dir
|
|
||||||
POST_BUILD = :
|
|
||||||
PRE_LINK = :
|
|
||||||
TARGET_FILE = boo
|
|
||||||
TARGET_PDB = boo.dbg
|
|
||||||
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Utility command for edit_cache
|
|
||||||
|
|
||||||
build CMakeFiles/edit_cache.util: CUSTOM_COMMAND
|
|
||||||
COMMAND = cd /home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/bin && /home/echo/Android/Sdk/cmake/3.22.1/bin/cmake -E echo No\ interactive\ CMake\ dialog\ available.
|
|
||||||
DESC = No interactive CMake dialog available...
|
|
||||||
restat = 1
|
|
||||||
|
|
||||||
build edit_cache: phony CMakeFiles/edit_cache.util
|
|
||||||
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Utility command for rebuild_cache
|
|
||||||
|
|
||||||
build CMakeFiles/rebuild_cache.util: CUSTOM_COMMAND
|
|
||||||
COMMAND = cd /home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/bin && /home/echo/Android/Sdk/cmake/3.22.1/bin/cmake --regenerate-during-build -S/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/src -B/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/bin
|
|
||||||
DESC = Running CMake to regenerate build system...
|
|
||||||
pool = console
|
|
||||||
restat = 1
|
|
||||||
|
|
||||||
build rebuild_cache: phony CMakeFiles/rebuild_cache.util
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Target aliases.
|
|
||||||
|
|
||||||
build foo: phony libfoo.a
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Folder targets.
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Folder: /home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/bin
|
|
||||||
|
|
||||||
build all: phony libfoo.a boo
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Built-in targets
|
|
||||||
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Re-run CMake if any of its inputs changed.
|
|
||||||
|
|
||||||
build build.ninja: RERUN_CMAKE | /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCXXInformation.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCommonLanguageInclude.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeGenericSystem.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeInitializeConfigs.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeLanguageInformation.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeSystemSpecificInformation.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeSystemSpecificInitialize.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/CMakeCommonCompilerMacros.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang-CXX.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/GNU.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android-Clang-CXX.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android-Clang.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android-Initialize.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Linux.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/UnixPaths.cmake /home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/abis.cmake /home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/android-legacy.toolchain.cmake /home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/android.toolchain.cmake /home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/flags.cmake /home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/hooks/pre/Android-Clang.cmake /home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/hooks/pre/Android-Initialize.cmake /home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/hooks/pre/Android.cmake /home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/platforms.cmake /home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/3.22.1-g37088a8/CMakeCXXCompiler.cmake /home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/3.22.1-g37088a8/CMakeSystem.cmake /home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/src/CMakeLists.txt CMakeCache.txt
|
|
||||||
pool = console
|
|
||||||
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# A missing CMake input file is not an error.
|
|
||||||
|
|
||||||
build /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCXXInformation.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCommonLanguageInclude.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeGenericSystem.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeInitializeConfigs.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeLanguageInformation.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeSystemSpecificInformation.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeSystemSpecificInitialize.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/CMakeCommonCompilerMacros.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang-CXX.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/GNU.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android-Clang-CXX.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android-Clang.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android-Initialize.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Linux.cmake /home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/UnixPaths.cmake /home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/abis.cmake /home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/android-legacy.toolchain.cmake /home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/android.toolchain.cmake /home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/flags.cmake /home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/hooks/pre/Android-Clang.cmake /home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/hooks/pre/Android-Initialize.cmake /home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/hooks/pre/Android.cmake /home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/platforms.cmake /home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/3.22.1-g37088a8/CMakeCXXCompiler.cmake /home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/3.22.1-g37088a8/CMakeSystem.cmake /home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/src/CMakeLists.txt CMakeCache.txt: phony
|
|
||||||
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Clean all the built files.
|
|
||||||
|
|
||||||
build clean: CLEAN
|
|
||||||
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Print all primary targets available.
|
|
||||||
|
|
||||||
build help: HELP
|
|
||||||
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Make the all target the default.
|
|
||||||
|
|
||||||
default all
|
|
||||||
@ -1,49 +0,0 @@
|
|||||||
# Install script for directory: /home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/src
|
|
||||||
|
|
||||||
# Set the install prefix
|
|
||||||
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
|
||||||
set(CMAKE_INSTALL_PREFIX "/usr/local")
|
|
||||||
endif()
|
|
||||||
string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
|
|
||||||
|
|
||||||
# Set the install configuration name.
|
|
||||||
if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
|
|
||||||
if(BUILD_TYPE)
|
|
||||||
string(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
|
|
||||||
CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
|
|
||||||
else()
|
|
||||||
set(CMAKE_INSTALL_CONFIG_NAME "")
|
|
||||||
endif()
|
|
||||||
message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Set the component getting installed.
|
|
||||||
if(NOT CMAKE_INSTALL_COMPONENT)
|
|
||||||
if(COMPONENT)
|
|
||||||
message(STATUS "Install component: \"${COMPONENT}\"")
|
|
||||||
set(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
|
|
||||||
else()
|
|
||||||
set(CMAKE_INSTALL_COMPONENT)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Install shared libraries without execute permission?
|
|
||||||
if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)
|
|
||||||
set(CMAKE_INSTALL_SO_NO_EXE "0")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Is this installation the result of a crosscompile?
|
|
||||||
if(NOT DEFINED CMAKE_CROSSCOMPILING)
|
|
||||||
set(CMAKE_CROSSCOMPILING "TRUE")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CMAKE_INSTALL_COMPONENT)
|
|
||||||
set(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt")
|
|
||||||
else()
|
|
||||||
set(CMAKE_INSTALL_MANIFEST "install_manifest.txt")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
string(REPLACE ";" "\n" CMAKE_INSTALL_MANIFEST_CONTENT
|
|
||||||
"${CMAKE_INSTALL_MANIFEST_FILES}")
|
|
||||||
file(WRITE "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/bin/${CMAKE_INSTALL_MANIFEST}"
|
|
||||||
"${CMAKE_INSTALL_MANIFEST_CONTENT}")
|
|
||||||
Binary file not shown.
@ -1,8 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION "3.22.1-g37088a8")
|
|
||||||
project("lto-test" LANGUAGES CXX)
|
|
||||||
|
|
||||||
cmake_policy(SET CMP0069 NEW)
|
|
||||||
|
|
||||||
add_library(foo foo.cpp)
|
|
||||||
add_executable(boo main.cpp)
|
|
||||||
target_link_libraries(boo PUBLIC foo)
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
int foo()
|
|
||||||
{
|
|
||||||
return 0x42;
|
|
||||||
}
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
int foo();
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
return foo();
|
|
||||||
}
|
|
||||||
@ -1 +0,0 @@
|
|||||||
# This file is generated by cmake for dependency checking of the CMakeCache.txt file
|
|
||||||
@ -1 +0,0 @@
|
|||||||
# This file is generated by CMake for checking of the VerifyGlobs.cmake file
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
# CMAKE generated file: DO NOT EDIT!
|
|
||||||
# Generated by "Ninja" Generator, CMake Version 3.22
|
|
||||||
|
|
||||||
# This file contains all the rules used to get the outputs files
|
|
||||||
# built from the input files.
|
|
||||||
# It is included in the main 'build.ninja'.
|
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Project: appmodules
|
|
||||||
# Configurations: Debug
|
|
||||||
# =============================================================================
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Rule for compiling CXX files.
|
|
||||||
|
|
||||||
rule CXX_COMPILER__appmodules_Debug
|
|
||||||
depfile = $DEP_FILE
|
|
||||||
deps = gcc
|
|
||||||
command = /home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --target=i686-none-linux-android26 --sysroot=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot $DEFINES $INCLUDES $FLAGS -MD -MT $out -MF $DEP_FILE -o $out -c $in
|
|
||||||
description = Building CXX object $out
|
|
||||||
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Rule for linking CXX shared library.
|
|
||||||
|
|
||||||
rule CXX_SHARED_LIBRARY_LINKER__appmodules_Debug
|
|
||||||
command = $PRE_LINK && /home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --target=i686-none-linux-android26 --sysroot=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fPIC $LANGUAGE_COMPILE_FLAGS $ARCH_FLAGS $LINK_FLAGS -shared $SONAME_FLAG$SONAME -o $TARGET_FILE $in $LINK_PATH $LINK_LIBRARIES && $POST_BUILD
|
|
||||||
description = Linking CXX shared library $TARGET_FILE
|
|
||||||
restat = $RESTAT
|
|
||||||
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Rule for running custom commands.
|
|
||||||
|
|
||||||
rule CUSTOM_COMMAND
|
|
||||||
command = $COMMAND
|
|
||||||
description = $DESC
|
|
||||||
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Rule for re-running cmake.
|
|
||||||
|
|
||||||
rule RERUN_CMAKE
|
|
||||||
command = /home/echo/Android/Sdk/cmake/3.22.1/bin/cmake --regenerate-during-build -S/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/default-app-setup -B/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86
|
|
||||||
description = Re-running CMake...
|
|
||||||
generator = 1
|
|
||||||
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Rule for re-checking globbed directories.
|
|
||||||
|
|
||||||
rule VERIFY_GLOBS
|
|
||||||
command = /home/echo/Android/Sdk/cmake/3.22.1/bin/cmake -P /home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/VerifyGlobs.cmake
|
|
||||||
description = Re-checking globbed directories...
|
|
||||||
generator = 1
|
|
||||||
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Rule for cleaning all built files.
|
|
||||||
|
|
||||||
rule CLEAN
|
|
||||||
command = /home/echo/Android/Sdk/cmake/3.22.1/bin/ninja $FILE_ARG -t clean $TARGETS
|
|
||||||
description = Cleaning all built files...
|
|
||||||
|
|
||||||
|
|
||||||
#############################################
|
|
||||||
# Rule for printing all primary targets available.
|
|
||||||
|
|
||||||
rule HELP
|
|
||||||
command = /home/echo/Android/Sdk/cmake/3.22.1/bin/ninja -t targets
|
|
||||||
description = All primary targets available:
|
|
||||||
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
{
|
|
||||||
"buildFiles": [
|
|
||||||
"/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/default-app-setup/CMakeLists.txt"
|
|
||||||
],
|
|
||||||
"cleanCommandsComponents": [
|
|
||||||
[
|
|
||||||
"/home/echo/Android/Sdk/cmake/3.22.1/bin/ninja",
|
|
||||||
"-C",
|
|
||||||
"/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86",
|
|
||||||
"clean"
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"buildTargetsCommandComponents": [
|
|
||||||
"/home/echo/Android/Sdk/cmake/3.22.1/bin/ninja",
|
|
||||||
"-C",
|
|
||||||
"/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86",
|
|
||||||
"{LIST_OF_TARGETS_TO_BUILD}"
|
|
||||||
],
|
|
||||||
"libraries": {
|
|
||||||
"appmodules::@6890427a1f51a3e7e1df": {
|
|
||||||
"toolchain": "toolchain",
|
|
||||||
"abi": "x86",
|
|
||||||
"artifactName": "appmodules",
|
|
||||||
"output": "/home/echo/dev/prototype/apps/mobile/android/app/build/intermediates/cxx/Debug/2z472e3c/obj/x86/libappmodules.so",
|
|
||||||
"runtimeFiles": [
|
|
||||||
"/home/echo/.gradle/caches/8.14.3/transforms/488fe6e480efb97ec75859f6e274282f/transformed/fbjni-0.7.0/prefab/modules/fbjni/libs/android.x86/libfbjni.so",
|
|
||||||
"/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/jsi/libs/android.x86/libjsi.so",
|
|
||||||
"/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/reactnative/libs/android.x86/libreactnative.so"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"toolchains": {
|
|
||||||
"toolchain": {
|
|
||||||
"cCompilerExecutable": "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/clang.lld",
|
|
||||||
"cppCompilerExecutable": "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++.lld"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"cFileExtensions": [],
|
|
||||||
"cppFileExtensions": [
|
|
||||||
"cpp"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
{
|
|
||||||
"buildFiles": [
|
|
||||||
"/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/default-app-setup/CMakeLists.txt"
|
|
||||||
],
|
|
||||||
"cleanCommandsComponents": [
|
|
||||||
[
|
|
||||||
"/home/echo/Android/Sdk/cmake/3.22.1/bin/ninja",
|
|
||||||
"-C",
|
|
||||||
"/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86",
|
|
||||||
"clean"
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"buildTargetsCommandComponents": [
|
|
||||||
"/home/echo/Android/Sdk/cmake/3.22.1/bin/ninja",
|
|
||||||
"-C",
|
|
||||||
"/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86",
|
|
||||||
"{LIST_OF_TARGETS_TO_BUILD}"
|
|
||||||
],
|
|
||||||
"libraries": {
|
|
||||||
"appmodules::@6890427a1f51a3e7e1df": {
|
|
||||||
"artifactName": "appmodules",
|
|
||||||
"abi": "x86",
|
|
||||||
"output": "/home/echo/dev/prototype/apps/mobile/android/app/build/intermediates/cxx/Debug/2z472e3c/obj/x86/libappmodules.so",
|
|
||||||
"runtimeFiles": [
|
|
||||||
"/home/echo/.gradle/caches/8.14.3/transforms/488fe6e480efb97ec75859f6e274282f/transformed/fbjni-0.7.0/prefab/modules/fbjni/libs/android.x86/libfbjni.so",
|
|
||||||
"/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/jsi/libs/android.x86/libjsi.so",
|
|
||||||
"/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/reactnative/libs/android.x86/libreactnative.so"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
|||||||
/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/default-app-setup/CMakeLists.txt
|
|
||||||
@ -1,54 +0,0 @@
|
|||||||
# Install script for directory: /home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/default-app-setup
|
|
||||||
|
|
||||||
# Set the install prefix
|
|
||||||
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
|
||||||
set(CMAKE_INSTALL_PREFIX "/usr/local")
|
|
||||||
endif()
|
|
||||||
string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
|
|
||||||
|
|
||||||
# Set the install configuration name.
|
|
||||||
if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
|
|
||||||
if(BUILD_TYPE)
|
|
||||||
string(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
|
|
||||||
CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
|
|
||||||
else()
|
|
||||||
set(CMAKE_INSTALL_CONFIG_NAME "Debug")
|
|
||||||
endif()
|
|
||||||
message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Set the component getting installed.
|
|
||||||
if(NOT CMAKE_INSTALL_COMPONENT)
|
|
||||||
if(COMPONENT)
|
|
||||||
message(STATUS "Install component: \"${COMPONENT}\"")
|
|
||||||
set(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
|
|
||||||
else()
|
|
||||||
set(CMAKE_INSTALL_COMPONENT)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Install shared libraries without execute permission?
|
|
||||||
if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)
|
|
||||||
set(CMAKE_INSTALL_SO_NO_EXE "0")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Is this installation the result of a crosscompile?
|
|
||||||
if(NOT DEFINED CMAKE_CROSSCOMPILING)
|
|
||||||
set(CMAKE_CROSSCOMPILING "TRUE")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Set default install directory permissions.
|
|
||||||
if(NOT DEFINED CMAKE_OBJDUMP)
|
|
||||||
set(CMAKE_OBJDUMP "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-objdump")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CMAKE_INSTALL_COMPONENT)
|
|
||||||
set(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt")
|
|
||||||
else()
|
|
||||||
set(CMAKE_INSTALL_MANIFEST "install_manifest.txt")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
string(REPLACE ";" "\n" CMAKE_INSTALL_MANIFEST_CONTENT
|
|
||||||
"${CMAKE_INSTALL_MANIFEST_FILES}")
|
|
||||||
file(WRITE "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/${CMAKE_INSTALL_MANIFEST}"
|
|
||||||
"${CMAKE_INSTALL_MANIFEST_CONTENT}")
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user