@openapi-typescript-infra/service 3.0.3 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/types.d.ts CHANGED
@@ -8,7 +8,6 @@ import type { Request, Response } from 'express';
8
8
  import type { Application } from 'express-serve-static-core';
9
9
  import type { middleware } from 'express-openapi-validator';
10
10
  import type { Meter } from '@opentelemetry/api';
11
- import { Confit } from '@sesamecare-oss/confit';
12
11
  import { ConfigurationSchema } from './config/schema';
13
12
  export interface InternalLocals<SLocals extends AnyServiceLocals = ServiceLocals<ConfigurationSchema>> extends Record<string, unknown> {
14
13
  server?: Server;
@@ -19,7 +18,7 @@ export interface ServiceLocals<Config extends ConfigurationSchema = Configuratio
19
18
  service: Service;
20
19
  name: string;
21
20
  logger: ServiceLogger;
22
- config: Confit<Config>;
21
+ config: Config;
23
22
  meter: Meter;
24
23
  internalApp: Application<InternalLocals<this>>;
25
24
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openapi-typescript-infra/service",
3
- "version": "3.0.3",
3
+ "version": "4.0.0",
4
4
  "description": "An opinionated framework for building configuration driven services - web, api, or ob. Uses OpenAPI, pino logging, express, confit, Typescript and vitest.",
5
5
  "main": "build/index.js",
6
6
  "scripts": {
@@ -80,11 +80,10 @@
80
80
  "@opentelemetry/sdk-node": "^0.43.0",
81
81
  "@opentelemetry/sdk-trace-base": "^1.17.1",
82
82
  "@opentelemetry/semantic-conventions": "^1.17.1",
83
- "@sesamecare-oss/confit": "^1.1.0",
83
+ "@sesamecare-oss/confit": "^2.0.0",
84
84
  "@sesamecare-oss/opentelemetry-node-metrics": "^1.0.1",
85
85
  "cookie-parser": "^1.4.6",
86
86
  "dotenv": "^16.3.1",
87
- "eventsource": "^1.1.2",
88
87
  "express": "next",
89
88
  "express-openapi-validator": "^5.0.6",
90
89
  "glob": "^8.1.0",
@@ -104,12 +103,11 @@
104
103
  "@semantic-release/git": "^10.0.1",
105
104
  "@semantic-release/release-notes-generator": "^12.0.0",
106
105
  "@types/cookie-parser": "^1.4.5",
107
- "@types/eventsource": "1.1.12",
108
- "@types/express": "^4.17.19",
106
+ "@types/express": "^4.17.20",
109
107
  "@types/glob": "^8.1.0",
110
- "@types/lodash": "^4.14.199",
111
- "@types/minimist": "^1.2.3",
112
- "@types/node": "^20.8.6",
108
+ "@types/lodash": "^4.14.200",
109
+ "@types/minimist": "^1.2.4",
110
+ "@types/node": "^20.8.7",
113
111
  "@types/supertest": "^2.0.14",
114
112
  "@typescript-eslint/eslint-plugin": "^6.8.0",
115
113
  "@typescript-eslint/parser": "^6.8.0",
@@ -1,7 +1,7 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
3
 
4
- import { BaseConfitType, Confit, Factory, confit } from '@sesamecare-oss/confit';
4
+ import { BaseConfitSchema, Confit, Factory, confit } from '@sesamecare-oss/confit';
5
5
 
6
6
  import { findPort } from '../development/port-finder';
7
7
 
@@ -28,11 +28,11 @@ async function pathExists(f: string) {
28
28
  async function addDefaultConfiguration<Config extends ConfigurationSchema = ConfigurationSchema>(
29
29
  configFactory: Factory<Config>,
30
30
  directory: string,
31
- envConfit: Confit<BaseConfitType>,
31
+ envConfit: Confit<BaseConfitSchema>,
32
32
  ) {
33
33
  const addIfEnv = async (e: (typeof ENVIRONMENTS)[number]) => {
34
34
  const c = path.join(directory, `${e}.json`);
35
- if (envConfit.get(`env:${e}`) && (await pathExists(c))) {
35
+ if (envConfit.get().env[e] && (await pathExists(c))) {
36
36
  configFactory.addDefault(c);
37
37
  return true;
38
38
  }
@@ -63,13 +63,13 @@ export async function loadConfiguration<Config extends ConfigurationSchema>({
63
63
  name,
64
64
  configurationDirectories: dirs,
65
65
  sourceDirectory,
66
- }: ServiceConfigurationSpec): Promise<Confit<Config>> {
66
+ }: ServiceConfigurationSpec): Promise<Config> {
67
67
  const defaultProtocols = shortstops({ name }, sourceDirectory);
68
68
  const specificConfig = dirs[dirs.length - 1];
69
69
 
70
70
  // This confit version just gets us environment info
71
71
  const envConfit = await confit({ basedir: specificConfig }).create();
72
- const configFactory = confit<ConfigurationSchema>({
72
+ const configFactory = confit<Config>({
73
73
  basedir: specificConfig,
74
74
  protocols: defaultProtocols,
75
75
  });
@@ -90,17 +90,19 @@ export async function loadConfiguration<Config extends ConfigurationSchema>({
90
90
 
91
91
  // Because other things need to know the port we choose, we pick it here if it's
92
92
  // configured to auto-select
93
- const serverConfig = loaded.get('server');
93
+ const serverConfig = loaded.get().server;
94
94
  if (serverConfig.port === 0) {
95
95
  const port = (await findPort(8001)) as number;
96
- loaded.set('server:port', port);
96
+ const store = loaded.get();
97
+ store.server = store.server || {};
98
+ store.server.port = port;
97
99
  }
98
100
 
99
101
  // TODO init other stuff based on config here, such as key management or
100
102
  // other cloud-aware shortstop handlers
101
103
 
102
104
  // Not sure why this is necessary, but it is
103
- return loaded as unknown as Confit<Config>;
105
+ return loaded.get();
104
106
  }
105
107
 
106
108
  export function insertConfigurationBefore(
@@ -1,4 +1,4 @@
1
- import type { BaseConfitType } from '@sesamecare-oss/confit';
1
+ import type { BaseConfitSchema } from '@sesamecare-oss/confit';
2
2
  import type { Level } from 'pino';
3
3
 
4
4
  export interface ServiceConfiguration {
@@ -13,7 +13,7 @@ export interface ConfigurationItemEnabled {
13
13
  enabled?: boolean;
14
14
  }
15
15
 
16
- export interface ConfigurationSchema extends BaseConfitType {
16
+ export interface ConfigurationSchema extends BaseConfitSchema {
17
17
  trustProxy?: string[];
18
18
  logging?: {
19
19
  level?: Level;
@@ -10,7 +10,6 @@ import { metrics } from '@opentelemetry/api';
10
10
  import { setupNodeMetrics } from '@sesamecare-oss/opentelemetry-node-metrics';
11
11
  import { createTerminus } from '@godaddy/terminus';
12
12
  import type { RequestHandler, Response } from 'express';
13
- import { Confit } from '@sesamecare-oss/confit';
14
13
 
15
14
  import { loadConfiguration } from '../config/index';
16
15
  import { openApi } from '../openapi';
@@ -88,12 +87,12 @@ export async function startApp<
88
87
  sourceDirectory: path.join(rootDirectory, codepath),
89
88
  });
90
89
 
91
- const logging = config.get('logging');
90
+ const logging = config.logging;
92
91
  logger.level = logging?.level || 'info';
93
92
 
94
93
  // Concentrate the Typescript ugliness...
95
94
  const app = express() as unknown as ServiceExpress<SLocals>;
96
- const routing = config.get('routing');
95
+ const routing = config.routing;
97
96
 
98
97
  app.disable('x-powered-by');
99
98
  if (routing?.etag !== true) {
@@ -114,8 +113,8 @@ export async function startApp<
114
113
  app.locals.meter = metrics.getMeterProvider().getMeter(name);
115
114
  setupNodeMetrics(app.locals.meter, {});
116
115
 
117
- if (config.get('trustProxy')) {
118
- app.set('trust proxy', config.get('trustProxy'));
116
+ if (config.trustProxy) {
117
+ app.set('trust proxy', config.trustProxy);
119
118
  }
120
119
 
121
120
  app.use(loggerMiddleware(app, logging?.logRequestBody, logging?.logResponseBody));
@@ -220,7 +219,7 @@ export async function startApp<
220
219
  if (routing?.routes) {
221
220
  await loadRoutes(
222
221
  app,
223
- path.resolve(rootDirectory, codepath, config.get<string>('routing:routes') || 'routes'),
222
+ path.resolve(rootDirectory, codepath, config.routing?.routes || 'routes'),
224
223
  codePattern,
225
224
  );
226
225
  }
@@ -288,10 +287,7 @@ export async function listen<SLocals extends AnyServiceLocals = ServiceLocals<Co
288
287
  app: ServiceExpress<SLocals>,
289
288
  shutdownHandler?: () => Promise<void>,
290
289
  ) {
291
- // TODO I don't know why this is necessary, but TS can't quite figure this out
292
- // otherwise.
293
- const typedConfig = app.locals.config as unknown as Confit<ConfigurationSchema>;
294
- const config = typedConfig.get('server') as Required<ConfigurationSchema['server']>;
290
+ const config = app.locals.config.server || {};
295
291
  const { port } = config;
296
292
 
297
293
  const { service, logger } = app.locals;
@@ -348,7 +344,7 @@ export async function listen<SLocals extends AnyServiceLocals = ServiceLocals<Co
348
344
  const { locals } = app;
349
345
  locals.logger.info({ url: url(config, port), service: locals.name }, 'express listening');
350
346
 
351
- const serverConfig = typedConfig.get('server');
347
+ const serverConfig = app.locals.config.server;
352
348
  // Ok now start the internal port if we have one.
353
349
  if (serverConfig?.internalPort || serverConfig?.internalPort === 0) {
354
350
  startInternalApp(app, serverConfig.internalPort)
package/src/types.ts CHANGED
@@ -6,7 +6,6 @@ import type { Request, Response } from 'express';
6
6
  import type { Application } from 'express-serve-static-core';
7
7
  import type { middleware } from 'express-openapi-validator';
8
8
  import type { Meter } from '@opentelemetry/api';
9
- import { Confit } from '@sesamecare-oss/confit';
10
9
 
11
10
  import { ConfigurationSchema } from './config/schema';
12
11
 
@@ -26,7 +25,7 @@ export interface ServiceLocals<Config extends ConfigurationSchema = Configuratio
26
25
  service: Service;
27
26
  name: string;
28
27
  logger: ServiceLogger;
29
- config: Confit<Config>;
28
+ config: Config;
30
29
  meter: Meter;
31
30
  internalApp: Application<InternalLocals<this>>;
32
31
  }