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
6 changes: 1 addition & 5 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,9 @@
}
},
"customizations": {
"codespaces": {
"openFiles": [
"codespaces.md"
]
},
"vscode": {
"extensions": [
"angular.ng-template",
"mongodb.mongodb-vscode"
]
}
Expand Down
13 changes: 13 additions & 0 deletions .mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"mcpServers": {
"MongoDB": {
"command": "npx",
"args": [
"-y",
"mongodb-mcp-server@latest",
"--connectionString",
"mongodb://localhost:27017/meanStackExample"
]
}
}
}
4 changes: 4 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846
"recommendations": ["angular.ng-template", "mongodb.mongodb-vscode"]
}
20 changes: 20 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "ng serve",
"type": "pwa-chrome",
"request": "launch",
"preLaunchTask": "npm: start - client",
"url": "http://localhost:4200/"
},
{
"name": "ng test",
"type": "chrome",
"request": "launch",
"preLaunchTask": "npm: test - client",
"url": "http://localhost:9876/debug.html"
}
]
}
10 changes: 10 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"mdb.presetConnections": [
{
"name": "Local Database",
"connectionString": "mongodb://localhost:27017"
}
],
"mdb.showOverviewPageAfterInstall": false,
"workbench.secondarySideBar.defaultVisibility": "hidden"
}
46 changes: 46 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "start",
"path": "client",
"label": "npm: start - client",
"isBackground": true,
"problemMatcher": {
"owner": "typescript",
"pattern": "$tsc",
"background": {
"activeOnStart": true,
"beginsPattern": {
"regexp": "(.*?)"
},
"endsPattern": {
"regexp": "bundle generation complete"
}
}
}
},
{
"type": "npm",
"script": "test",
"path": "client",
"label": "npm: test - client",
"isBackground": true,
"problemMatcher": {
"owner": "typescript",
"pattern": "$tsc",
"background": {
"activeOnStart": true,
"beginsPattern": {
"regexp": "(.*?)"
},
"endsPattern": {
"regexp": "bundle generation complete"
}
}
}
}
]
}
12 changes: 8 additions & 4 deletions client/src/app/api-config.service.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { Service, PLATFORM_ID, inject } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { resolveApiBaseUrl } from './api-url';

@Service()
export class ApiConfigService {
// In browser (including Codespaces), target current host on API port.
// During SSR/build contexts, fall back to localhost for deterministic behavior.
readonly baseUrl = isPlatformBrowser(inject(PLATFORM_ID))
? `${window.location.protocol}//${window.location.hostname}:5300`
private readonly platformId = inject(PLATFORM_ID);

// In the browser, derive the API URL from the current location so it works
// across local dev and hosted/forwarded environments. During SSR/build,
// fall back to localhost for deterministic behavior.
readonly baseUrl = isPlatformBrowser(this.platformId)
? resolveApiBaseUrl(window.location)
: 'http://localhost:5300';
}
32 changes: 32 additions & 0 deletions client/src/app/api-url.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const API_PORT = 5300;

/**
* Resolves the API base URL for a given browser location.
*
* In most environments the API is reached on the same host at `API_PORT`.
* Hosting platforms that forward each port as its own subdomain are handled
* transparently, so callers never need to know about them.
*/
export function resolveApiBaseUrl(location: {
protocol: string;
hostname: string;
}): string {
const { protocol, hostname } = location;
const forwardedHost = forwardedApiHost(hostname);

return forwardedHost
? `${protocol}//${forwardedHost}`
: `${protocol}//${hostname}:${API_PORT}`;
}

/**
* GitHub Codespaces forwards each port as its own subdomain
* (e.g. `name-4200.app.github.dev`) served over 443 rather than as
* `host:port`. Rewrite the client's port segment to the API port.
* Returns `null` for hosts that don't use this scheme.
*/
function forwardedApiHost(hostname: string): string | null {
const match = /^(.*)-\d+\.app\.github\.dev$/.exec(hostname);

return match ? `${match[1]}-${API_PORT}.app.github.dev` : null;
}
78 changes: 0 additions & 78 deletions codespaces.md

This file was deleted.

Loading