buildHandler function

Handler buildHandler(
  1. String projectRoot
)

Build the Shelf Handler for projectRoot. Pulled out of the serve command so tests can drive it without binding a real port.

Implementation

Handler buildHandler(String projectRoot) {
  final router = Router();

  router.get('/api/config', (Request _) {
    final project = _loadOrFail(projectRoot);
    return configHandler(project);
  });

  router.get('/api/glossary', (Request _) {
    final project = _loadOrFail(projectRoot);
    return glossaryHandler(project);
  });

  router.get('/api/status', (Request _) {
    final project = _loadOrFail(projectRoot);
    return statusHandler(project);
  });

  router.get('/api/strings', (Request req) {
    final project = _loadOrFail(projectRoot);
    return stringsListHandler(project, req);
  });

  router.put('/api/strings/<key>', (Request req, String key) async {
    final project = _loadOrFail(projectRoot);
    return stringsPutHandler(project, req, key);
  });

  // Unknown /api/* paths return JSON 404 rather than falling through
  // to the SPA handler (which would happily serve HTML).
  router.all('/api/<rest|.*>', (Request _) {
    return Response.notFound(
      jsonEncode({'error': 'No such API endpoint.'}),
      headers: const {'content-type': 'application/json; charset=utf-8'},
    );
  });

  // Static assets — index.html + bundled JS/CSS — fall through to the
  // SPA handler. Anything outside /api/* gets served from the embedded
  // bundle; unknown paths return index.html so client-side routing
  // works ("/strings", "/glossary", …).
  router.all('/<rest|.*>', _staticAssetHandler);

  return const Pipeline()
      .addMiddleware(_corsHeaders())
      .addMiddleware(_errorAsJson())
      .addHandler(router.call);
}