feat(beacon): ✨ Implement BeaconController with HTTP endpoints and BeaconModule providers for beacon data processing
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
7f91ccc3a5
commit
e1f469b6f1
2 changed files with 51 additions and 0 deletions
44
services/collector/src/beacon/beacon.controller.ts
Normal file
44
services/collector/src/beacon/beacon.controller.ts
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import { readFileSync } from 'node:fs';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { Controller, Get, Header, Logger, NotFoundException, SetMetadata } from '@nestjs/common';
|
||||
import { IS_PUBLIC_KEY } from '../auth/write-key.guard';
|
||||
|
||||
/**
|
||||
* Serves the static beacon.js script at `/beacon.js` (carved out of the
|
||||
* `/analytics` global prefix in main.ts, and marked public to bypass
|
||||
* the WriteKeyGuard). Loaded cross-origin via
|
||||
* `<script defer src="https://data.transquinnftw.com/beacon.js" data-site="...">`
|
||||
* from ATT, Sansonnet, Cocotte, and SEO bait surfaces. Source of truth for
|
||||
* the script lives in this service at public/beacon.js.
|
||||
*/
|
||||
@Controller()
|
||||
@SetMetadata(IS_PUBLIC_KEY, true)
|
||||
export class BeaconController {
|
||||
private readonly logger = new Logger(BeaconController.name);
|
||||
private readonly cached: string;
|
||||
|
||||
constructor() {
|
||||
// ESM-safe path resolution. From dist/beacon/beacon.controller.js,
|
||||
// ../../public/beacon.js resolves to /app/public/beacon.js in the container.
|
||||
const path = fileURLToPath(new URL('../../public/beacon.js', import.meta.url));
|
||||
try {
|
||||
this.cached = readFileSync(path, 'utf8');
|
||||
this.logger.log(`Loaded beacon.js (${this.cached.length} bytes) from ${path}`);
|
||||
} catch (cause) {
|
||||
const message = cause instanceof Error ? cause.message : String(cause);
|
||||
throw new Error(`BeaconController: failed to load ${path}: ${message}`);
|
||||
}
|
||||
}
|
||||
|
||||
@Get('beacon.js')
|
||||
@Header('Content-Type', 'application/javascript; charset=utf-8')
|
||||
@Header('Cache-Control', 'public, max-age=300, stale-while-revalidate=600')
|
||||
@Header('Access-Control-Allow-Origin', '*')
|
||||
@Header('Cross-Origin-Resource-Policy', 'cross-origin')
|
||||
serve(): string {
|
||||
if (this.cached === undefined || this.cached.length === 0) {
|
||||
throw new NotFoundException('beacon.js not loaded');
|
||||
}
|
||||
return this.cached;
|
||||
}
|
||||
}
|
||||
7
services/collector/src/beacon/beacon.module.ts
Normal file
7
services/collector/src/beacon/beacon.module.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { BeaconController } from './beacon.controller';
|
||||
|
||||
@Module({
|
||||
controllers: [BeaconController],
|
||||
})
|
||||
export class BeaconModule {}
|
||||
Loading…
Add table
Reference in a new issue