Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
NEXT_PUBLIC_SITE_URL: https://devglobe.dev
NEXT_PUBLIC_SITE_URL: https://www.devglobe.dev

jobs:
deploy:
Expand All @@ -21,7 +21,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: npm

- name: Install dependencies
Expand Down
12 changes: 2 additions & 10 deletions app/api/card/route.jsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,17 @@
import { ImageResponse } from '@vercel/og';
import { CosmosClient } from '@azure/cosmos';
import { unstable_cache } from 'next/cache';
import { promises as fs } from 'fs';
import path from 'path';
import { classifyAgent, getPowerTier } from '../../../lib/agent-class.js';
import { scoreAll } from '../../../lib/scoring.js';
import { getSiteHostname } from '../../../lib/site.js';
import { addDeveloperRanks } from '../../../lib/ranking.js';
import { getCosmosContainer } from '../../../lib/cosmos.js';

export const runtime = 'nodejs';

const COSMOS_ENDPOINT = process.env.COSMOS_ENDPOINT;
const COSMOS_KEY = process.env.COSMOS_KEY;
const DATABASE = process.env.COSMOS_DATABASE || 'devglobe';
const CONTAINER = process.env.COSMOS_CONTAINER || 'developers';
const cosmosClient = COSMOS_ENDPOINT && COSMOS_KEY
? new CosmosClient({ endpoint: COSMOS_ENDPOINT, key: COSMOS_KEY })
: null;
const cosmosContainer = cosmosClient?.database(DATABASE).container(CONTAINER);

async function loadRankedDevelopers() {
const cosmosContainer = getCosmosContainer();
if (cosmosContainer) {
try {
const { resources } = await cosmosContainer.items.query({
Expand Down
12 changes: 2 additions & 10 deletions app/api/card/social/route.jsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
import { ImageResponse } from '@vercel/og';
import { CosmosClient } from '@azure/cosmos';
import { promises as fs } from 'fs';
import path from 'path';
import { getCosmosContainer } from '../../../../lib/cosmos.js';

export const runtime = 'nodejs';

const COSMOS_ENDPOINT = process.env.COSMOS_ENDPOINT;
const COSMOS_KEY = process.env.COSMOS_KEY;
const DATABASE = process.env.COSMOS_DATABASE || 'devglobe';
const CONTAINER = process.env.COSMOS_CONTAINER || 'developers';
const cosmosClient = COSMOS_ENDPOINT && COSMOS_KEY
? new CosmosClient({ endpoint: COSMOS_ENDPOINT, key: COSMOS_KEY })
: null;
const cosmosContainer = cosmosClient?.database(DATABASE).container(CONTAINER);

async function getDeveloper(login) {
const cosmosContainer = getCosmosContainer();
if (cosmosContainer) {
try {
const { resources } = await cosmosContainer.items.query({
Expand Down
11 changes: 3 additions & 8 deletions app/sitemap.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,21 @@
import { CosmosClient } from '@azure/cosmos';
import { promises as fs } from 'fs';
import path from 'path';
import { getCosmosContainer } from '../lib/cosmos.js';
import { getSiteUrl } from '../lib/site.js';

const siteUrl = getSiteUrl();
const cosmosEndpoint = process.env.COSMOS_ENDPOINT;
const cosmosKey = process.env.COSMOS_KEY;
const databaseName = process.env.COSMOS_DATABASE || 'devglobe';
const containerName = process.env.COSMOS_CONTAINER || 'developers';

export const revalidate = 86400;

async function getProfileLogins() {
if (!cosmosEndpoint || !cosmosKey) {
const container = getCosmosContainer();
if (!container) {
const filePath = path.join(process.cwd(), 'data', 'developers-sample.json');
const developers = JSON.parse(await fs.readFile(filePath, 'utf-8'));
return developers.map(developer => developer.login).filter(Boolean);
}

try {
const client = new CosmosClient({ endpoint: cosmosEndpoint, key: cosmosKey });
const container = client.database(databaseName).container(containerName);
const { resources } = await container.items
.query("SELECT VALUE c.login FROM c WHERE c.claimed = true AND (NOT IS_DEFINED(c.nomination) OR c.nomination.status = 'approved')")
.fetchAll();
Expand Down
26 changes: 26 additions & 0 deletions lib/cosmos.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { CosmosClient } from '@azure/cosmos';

const containers = new Map();

export function getCosmosContainer() {
const endpoint = process.env.COSMOS_ENDPOINT?.trim();
const key = process.env.COSMOS_KEY?.trim();
if (!endpoint || !key) return null;

try {
const url = new URL(endpoint);
if (url.protocol !== 'https:' && url.protocol !== 'http:') return null;
} catch {
return null;
}

const database = process.env.COSMOS_DATABASE || 'devglobe';
const container = process.env.COSMOS_CONTAINER || 'developers';
const cacheKey = `${endpoint}|${database}|${container}`;
if (containers.has(cacheKey)) return containers.get(cacheKey);

const client = new CosmosClient({ endpoint, key });
const cosmosContainer = client.database(database).container(container);
containers.set(cacheKey, cosmosContainer);
return cosmosContainer;
}
3 changes: 3 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
"version": "2.0.0",
"type": "module",
"description": "Interactive 3D globe visualization of top GitHub developers",
"engines": {
"node": ">=22.0.0"
},
"scripts": {
"dev": "next dev",
"build": "next build",
Expand Down
Loading