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