diff --git a/.changeset/extract-express-adapter.md b/.changeset/extract-express-adapter.md new file mode 100644 index 000000000..ee8f5d0de --- /dev/null +++ b/.changeset/extract-express-adapter.md @@ -0,0 +1,8 @@ +--- +'oc-express-server-adapter': minor +'oc': patch +--- + +Extract the Express HTTP server adapter into `oc-express-server-adapter`. + +The Express adapter remains the default registry server. This package split makes it possible to drop Express from core later and treat it as an opt-in adapter, matching `oc-fastify-server-adapter`. diff --git a/.gitignore b/.gitignore index 79d783827..638bf7f70 100644 --- a/.gitignore +++ b/.gitignore @@ -57,6 +57,7 @@ packages/oc-azure-storage-adapter/dist/ packages/oc-gs-storage-adapter/dist/ packages/oc-riak-storage-adapter/dist/ packages/oc-fastify-server-adapter/dist/ +packages/oc-express-server-adapter/dist/ packages/oc/test-components/ packages/oc-client-browser/playwright-report/ packages/oc-client-browser/test-results/ diff --git a/biome.json b/biome.json index 0d46cb382..722aa5999 100644 --- a/biome.json +++ b/biome.json @@ -25,6 +25,9 @@ "packages/oc-fastify-server-adapter/**/*", "!packages/oc-fastify-server-adapter/dist/**/*", "!packages/oc-fastify-server-adapter/node_modules/**/*", + "packages/oc-express-server-adapter/**/*", + "!packages/oc-express-server-adapter/dist/**/*", + "!packages/oc-express-server-adapter/node_modules/**/*", "packages/oc-client-browser/**/*", "!packages/oc-client-browser/dist/**/*", "!packages/oc-client-browser/vendor/**/*", diff --git a/package-lock.json b/package-lock.json index 459e00cff..34259d675 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13521,6 +13521,10 @@ "integrity": "sha512-iO6sbQU7ztAnXaf6J4cT73JDIcpmvYuQgwhFsI4TzaV3Spd4rxzb/ZgvWcFmLVFXN2O7m65eqBOWn756FCZVbw==", "license": "MIT" }, + "node_modules/oc-express-server-adapter": { + "resolved": "packages/oc-express-server-adapter", + "link": true + }, "node_modules/oc-external-dependencies-handler": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/oc-external-dependencies-handler/-/oc-external-dependencies-handler-1.1.0.tgz", @@ -18172,7 +18176,7 @@ } }, "packages/oc": { - "version": "0.50.57", + "version": "0.50.58", "license": "MIT", "dependencies": { "@kitajs/html": "^4.2.13", @@ -18185,11 +18189,9 @@ "builtin-modules": "^3.3.0", "chokidar": "^4.0.3", "colors": "^1.4.0", - "cookie-parser": "^1.4.7", "cross-spawn": "^7.0.6", "dependency-graph": "^1.0.0", "dotenv": "^17.4.2", - "errorhandler": "^1.5.2", "esbuild": "^0.25.12", "express": "^5.2.1", "form-data": "^4.0.6", @@ -18197,12 +18199,11 @@ "getport": "^0.1.0", "livereload": "^0.10.3", "lodash.isequal": "^4.5.0", - "morgan": "^1.11.0", - "multer": "^2.0.2", "nice-cache": "^0.0.5", "oc-client": "^4.0.3", "oc-client-browser": "^2.1.11", "oc-empty-response-handler": "^1.0.2", + "oc-express-server-adapter": "^0.1.0", "oc-get-unix-utc-timestamp": "^1.0.6", "oc-metadata-adapters-utils": "^0.1.1", "oc-s3-storage-adapter": "^2.2.3", @@ -18217,7 +18218,6 @@ "parse-author": "^2.0.0", "read": "^1.0.7", "require-package-name": "^2.0.1", - "response-time": "^2.3.4", "semver": "^7.8.4", "semver-extra": "^3.0.0", "serialize-error": "^12.0.0", @@ -18236,18 +18236,13 @@ "@types/accept-language-parser": "^1.5.8", "@types/async": "^3.2.25", "@types/bun": "^1.3.14", - "@types/cookie-parser": "^1.4.10", "@types/cross-spawn": "^6.0.6", - "@types/errorhandler": "^1.5.3", "@types/express": "^5.0.6", "@types/fs-extra": "^11.0.4", "@types/livereload": "^0.9.5", - "@types/morgan": "^1.9.10", - "@types/multer": "^2.1.0", "@types/node": "^25.9.3", "@types/parse-author": "^2.0.3", "@types/read": "^0.0.32", - "@types/response-time": "^2.3.9", "@types/semver": "^7.7.1", "@types/targz": "^1.0.5", "@types/yargs": "^17.0.35", @@ -18890,8 +18885,49 @@ "@esbuild/win32-x64": "0.28.1" } }, + "packages/oc-express-server-adapter": { + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "cookie-parser": "^1.4.7", + "errorhandler": "^1.5.2", + "express": "^5.2.1", + "morgan": "^1.11.0", + "multer": "^2.0.2", + "response-time": "^2.3.4" + }, + "devDependencies": { + "@biomejs/biome": "^2.5.0", + "@types/cookie-parser": "^1.4.10", + "@types/errorhandler": "^1.5.3", + "@types/express": "^5.0.6", + "@types/jest": "^29.5.14", + "@types/morgan": "^1.9.10", + "@types/multer": "^2.1.0", + "@types/node": "^25.9.3", + "@types/response-time": "^2.3.9", + "jest": "^29.7.0", + "rimraf": "^6.1.3", + "ts-jest": "^29.2.5", + "typescript": "^6.0.3" + } + }, + "packages/oc-express-server-adapter/node_modules/typescript": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "packages/oc-fastify-server-adapter": { - "version": "0.1.4", + "version": "0.1.6", "license": "MIT", "dependencies": { "@fastify/cookie": "^11.0.2", diff --git a/packages/oc-express-server-adapter/README.md b/packages/oc-express-server-adapter/README.md new file mode 100644 index 000000000..6aba78ae2 --- /dev/null +++ b/packages/oc-express-server-adapter/README.md @@ -0,0 +1,60 @@ +# oc-express-server-adapter + +Express HTTP server adapter for the OC registry. Implements OC's neutral +`HttpServerAdapter` interface and is the **default** adapter used by `oc` when +no custom `server.adapter` is configured. + +## Installation + +```sh +npm install oc-express-server-adapter express +``` + +`oc` already depends on this package and uses it by default, so most registry +users do not need to install it directly. Install it yourself when you want to +configure the adapter explicitly or share the factory across projects. + +## Usage + +```js +const oc = require('oc'); +const createExpressAdapter = require('oc-express-server-adapter').default; + +const registry = oc.Registry({ + // regular OC registry options... + server: { + adapter: createExpressAdapter, + options: { + port: 3030 + } + } +}); +``` + +## Options + +| Option | Type | Description | +| --- | --- | --- | +| `port` | `number \| string` | Optional. Stored on the Express app via `app.set('port', port)` so startup logs can read it. The registry still passes the listen port to `adapter.listen()`. | + +`options` may also be a bare `number` or `string` port for convenience. + +## Contract + +- `registry.start()` returns a real Express application as `app`. +- `server.httpServer()` and the `{ server }` value returned by `registry.start()` + are the underlying Node `http.Server`. +- User-supplied Connect/Express middleware (`beforePublish`, auth packages, + custom `routes[]`) is accepted through `fromConnect()` without wrapping + overhead when already Express-native. +- JSON bodies use `express.json({ inflate: true })` and urlencoded bodies use + `express.urlencoded({ extended: true })`. +- Strong ETags (`app.set('etag', 'strong')`) and `json spaces = 0` match the + historical registry behavior. +- File uploads use `multer` disk storage and populate `req.files`. + +## Future + +This package exists so Express can eventually become an **opt-in** dependency +of `oc` (the same way Fastify already is via `oc-fastify-server-adapter`), +instead of living inside the core package. diff --git a/packages/oc-express-server-adapter/package.json b/packages/oc-express-server-adapter/package.json new file mode 100644 index 000000000..fccf17f00 --- /dev/null +++ b/packages/oc-express-server-adapter/package.json @@ -0,0 +1,67 @@ +{ + "name": "oc-express-server-adapter", + "version": "0.1.0", + "description": "Express HTTP server adapter for OC", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/opencomponents/oc.git", + "directory": "packages/oc-express-server-adapter" + }, + "bugs": { + "url": "https://github.com/opencomponents/oc/issues" + }, + "homepage": "https://github.com/opencomponents/oc/tree/master/packages/oc-express-server-adapter#readme", + "keywords": [ + "oc", + "opencomponents", + "express", + "server", + "adapter" + ], + "author": "Matteo Figus", + "license": "MIT", + "files": [ + "dist", + "!dist/test/**" + ], + "scripts": { + "prebuild": "rimraf dist", + "build": "npm run lint && tsc", + "lint": "npx @biomejs/biome check src test", + "lint:apply": "npx @biomejs/biome check --write src test", + "test": "jest --runInBand", + "test-silent": "jest --runInBand --silent" + }, + "jest": { + "preset": "ts-jest", + "testEnvironment": "node", + "testPathIgnorePatterns": [ + "/dist/" + ] + }, + "dependencies": { + "cookie-parser": "^1.4.7", + "errorhandler": "^1.5.2", + "express": "^5.2.1", + "morgan": "^1.11.0", + "multer": "^2.0.2", + "response-time": "^2.3.4" + }, + "devDependencies": { + "@biomejs/biome": "^2.5.0", + "@types/cookie-parser": "^1.4.10", + "@types/errorhandler": "^1.5.3", + "@types/express": "^5.0.6", + "@types/jest": "^29.5.14", + "@types/morgan": "^1.9.10", + "@types/multer": "^2.1.0", + "@types/node": "^25.9.3", + "@types/response-time": "^2.3.9", + "jest": "^29.7.0", + "rimraf": "^6.1.3", + "ts-jest": "^29.2.5", + "typescript": "^6.0.3" + } +} diff --git a/packages/oc/src/registry/domain/http-server/express-adapter.ts b/packages/oc-express-server-adapter/src/index.ts similarity index 63% rename from packages/oc/src/registry/domain/http-server/express-adapter.ts rename to packages/oc-express-server-adapter/src/index.ts index 859a458fa..95cebde6b 100644 --- a/packages/oc/src/registry/domain/http-server/express-adapter.ts +++ b/packages/oc-express-server-adapter/src/index.ts @@ -6,14 +6,126 @@ import morgan from 'morgan'; import multer from 'multer'; import responseTime from 'response-time'; -import type { - ExpressMiddleware, - HttpServerAdapter, - Method, - OcHandler, - OcRequest, - OcResponse -} from './types'; +type CookieOptions = { + domain?: string; + encode?: (value: string) => string; + expires?: Date; + httpOnly?: boolean; + maxAge?: number; + partitioned?: boolean; + path?: string; + priority?: 'low' | 'medium' | 'high'; + sameSite?: boolean | 'lax' | 'strict' | 'none'; + secure?: boolean; + signed?: boolean; +}; + +type Method = 'get' | 'post' | 'put' | 'patch' | 'head' | 'delete'; + +type UploadedFile = { + fieldname: string; + originalname: string; + encoding: string; + mimetype: string; + size: number; + destination: string; + filename: string; + path: string; + buffer?: Buffer; + stream?: NodeJS.ReadableStream; + truncated?: boolean; +}; + +type OcRequest = { + method: string; + url: string; + path: string; + originalUrl: string; + protocol: string; + secure: boolean; + ip: string; + headers: http.IncomingHttpHeaders; + params: Record; + query: Record; + body: unknown; + cookies: Record; + files?: UploadedFile[] | Record; + user?: string; + routeId: string; + get(header: string): string | undefined; + raw: http.IncomingMessage; +}; + +type OcResponse = { + conf: any; + errorCode?: string; + errorDetails?: string; + statusCode: number; + status(code: number): OcResponse; + json(body: unknown): void; + send(body: unknown): void; + set(field: string | Record, value?: string): OcResponse; + header(name: string, value: string): OcResponse; + setHeader(name: string, value: string): OcResponse; + removeHeader(name: string): OcResponse; + type(mime: string): OcResponse; + cookie(name: string, value: string, opts?: CookieOptions): OcResponse; + redirect(url: string): void; + end(chunk?: unknown): void; + stream(readable: NodeJS.ReadableStream): void; + raw: http.ServerResponse; +}; + +type OcHandler = (req: OcRequest, res: OcResponse) => void | Promise; + +type ExpressMiddleware = ( + req: any, + res: any, + next: (err?: unknown) => void +) => void; + +export type HttpServerAdapter = { + name: string; + enableBodyParser(opts: { limit?: number | string }): void; + enableCookies(): void; + enableFileUploads(opts: { + tempDir: string; + filename: (originalName: string) => string; + }): void; + enableRequestTiming( + onDone: (req: OcRequest, res: OcResponse, ms: number) => void + ): void; + enableLogging(opts: { + skip: (req: OcRequest, res: OcResponse) => boolean; + }): void; + enableErrorHandler(): void; + use(handler: OcHandler): void; + route(method: Method, path: string, id: string, handlers: OcHandler[]): void; + fromConnect(handler: ExpressMiddleware): OcHandler; + listen( + opts: { port: number | string; timeout: number; keepAliveTimeout?: number }, + cb: (err?: Error) => void + ): void; + onServerError(cb: (err: Error) => void): void; + close(cb: (err?: Error) => void): void; + isListening(): boolean; + native(): TNative; + httpServer(): http.Server; +}; + +export interface ExpressServerAdapterOptions { + port?: number | string; +} + +export type HttpServerAdapterFactory = { + (options?: unknown): HttpServerAdapter; + readonly __serverAdapterOptions?: TOptions; +}; + +type ExpressServerAdapterFactory = HttpServerAdapterFactory< + ExpressServerAdapterOptions | number | string, + Express +>; const expressMiddleware = Symbol('expressMiddleware'); const ocResponseSym = Symbol('ocResponse'); @@ -40,19 +152,25 @@ function normaliseParams(raw: Record): Record { return params; } -export default function createExpressAdapter( +function toExpressAdapterOptions( options?: unknown -): HttpServerAdapter { - const adapterOptions = options as - | { port?: number | string } - | number - | string - | undefined; - return new ExpressHttpServerAdapter( - typeof adapterOptions === 'object' ? adapterOptions.port : adapterOptions - ); +): ExpressServerAdapterOptions { + if (typeof options === 'number' || typeof options === 'string') { + return { port: options }; + } + if (options && typeof options === 'object') { + return options as ExpressServerAdapterOptions; + } + return {}; } +const createExpressAdapter = ((options?: unknown): HttpServerAdapter => + new ExpressHttpServerAdapter( + toExpressAdapterOptions(options).port + )) as ExpressServerAdapterFactory; + +export default createExpressAdapter; + class ExpressHttpServerAdapter implements HttpServerAdapter { name = 'express'; diff --git a/packages/oc-express-server-adapter/test/index.test.ts b/packages/oc-express-server-adapter/test/index.test.ts new file mode 100644 index 000000000..4b93da44e --- /dev/null +++ b/packages/oc-express-server-adapter/test/index.test.ts @@ -0,0 +1,200 @@ +import type http from 'node:http'; +import type { Express } from 'express'; +import type { HttpServerAdapter } from '../src'; +import createExpressAdapter from '../src'; + +const asExpress = (adapter: HttpServerAdapter): Express => + adapter.native() as Express; + +const closeAdapter = (adapter: HttpServerAdapter): Promise => + new Promise((resolve, reject) => { + adapter.close((err) => (err ? reject(err) : resolve())); + }); + +const listen = ( + adapter: HttpServerAdapter, + port: number | string = 0 +): Promise => + new Promise((resolve, reject) => { + adapter.listen({ port, timeout: 120000 }, (err) => + err ? reject(err) : resolve() + ); + }); + +const request = async ( + adapter: HttpServerAdapter, + method: string, + url: string, + opts: { + headers?: Record; + body?: string | Buffer; + } = {} +): Promise<{ + statusCode: number; + headers: http.IncomingHttpHeaders; + body: string; +}> => { + const { default: nodeHttp } = await import('node:http'); + const address = adapter.httpServer().address(); + if (!address || typeof address === 'string') { + throw new Error('Expected TCP server address'); + } + + return new Promise((resolve, reject) => { + const req = nodeHttp.request( + { + hostname: '127.0.0.1', + port: address.port, + method, + path: url, + headers: opts.headers + }, + (res) => { + const chunks: Buffer[] = []; + res.on('data', (chunk) => chunks.push(Buffer.from(chunk))); + res.on('end', () => { + resolve({ + statusCode: res.statusCode ?? 0, + headers: res.headers, + body: Buffer.concat(chunks).toString('utf8') + }); + }); + } + ); + req.on('error', reject); + if (opts.body) { + req.write(opts.body); + } + req.end(); + }); +}; + +test('exposes express as the native app and sets strong etags', () => { + const adapter = createExpressAdapter({ port: 3030 }); + const app = asExpress(adapter); + + expect(adapter.name).toBe('express'); + expect(app.get('port')).toBe(3030); + expect(app.get('etag')).toBe('strong'); + expect(app.get('json spaces')).toBe(0); +}); + +test('returns strong etags and honours conditional requests', async () => { + const adapter = createExpressAdapter(); + adapter.route('get', '/component', 'component', [ + (_req, res) => { + res.status(200).json({ ok: true }); + } + ]); + + await listen(adapter); + + const first = await request(adapter, 'GET', '/component'); + const etag = first.headers.etag; + + expect(first.statusCode).toBe(200); + expect(JSON.parse(first.body)).toEqual({ ok: true }); + expect(etag).toMatch(/^"/); + expect(String(etag)).not.toMatch(/^W\//); + + const second = await request(adapter, 'GET', '/component', { + headers: { 'if-none-match': String(etag) } + }); + + expect(second.statusCode).toBe(304); + expect(second.body).toBe(''); + + await closeAdapter(adapter); +}); + +test('parses json and urlencoded bodies', async () => { + const adapter = createExpressAdapter(); + adapter.enableBodyParser({ limit: '1mb' }); + adapter.route('post', '/json', 'json', [ + (req, res) => { + res.json(req.body); + } + ]); + adapter.route('post', '/form', 'form', [ + (req, res) => { + res.json(req.body); + } + ]); + + await listen(adapter); + + const json = await request(adapter, 'POST', '/json', { + headers: { 'content-type': 'application/json' }, + body: JSON.stringify({ hello: 'world' }) + }); + expect(json.statusCode).toBe(200); + expect(JSON.parse(json.body)).toEqual({ hello: 'world' }); + + const form = await request(adapter, 'POST', '/form', { + headers: { 'content-type': 'application/x-www-form-urlencoded' }, + body: 'a[b]=1&a[c]=2' + }); + expect(form.statusCode).toBe(200); + expect(JSON.parse(form.body)).toEqual({ a: { b: '1', c: '2' } }); + + await closeAdapter(adapter); +}); + +test('normalises splat params to a single path string', async () => { + const adapter = createExpressAdapter(); + let seen: Record | undefined; + + adapter.route('get', '/files/*splat', 'files', [ + (req, res) => { + seen = req.params; + res.send('ok'); + } + ]); + + await listen(adapter); + + const response = await request(adapter, 'GET', '/files/a/b/c'); + expect(response.statusCode).toBe(200); + expect(seen?.['splat']).toBe('a/b/c'); + + await closeAdapter(adapter); +}); + +test('fromConnect preserves native connect middleware', async () => { + const adapter = createExpressAdapter(); + const handler = adapter.fromConnect((req, res, next) => { + res.setHeader('x-from-connect', '1'); + if (req.url === '/stop') { + res.end('stopped'); + return; + } + next(); + }); + + adapter.route('get', '/continue', 'continue', [ + handler, + (_req, res) => { + res.send('continued'); + } + ]); + adapter.route('get', '/stop', 'stop', [handler]); + + await listen(adapter); + + const continued = await request(adapter, 'GET', '/continue'); + expect(continued.statusCode).toBe(200); + expect(continued.headers['x-from-connect']).toBe('1'); + expect(continued.body).toBe('continued'); + + const stopped = await request(adapter, 'GET', '/stop'); + expect(stopped.statusCode).toBe(200); + expect(stopped.headers['x-from-connect']).toBe('1'); + expect(stopped.body).toBe('stopped'); + + await closeAdapter(adapter); +}); + +test('accepts a bare port option', () => { + const adapter = createExpressAdapter(4321); + expect(asExpress(adapter).get('port')).toBe(4321); +}); diff --git a/packages/oc-express-server-adapter/tsconfig.json b/packages/oc-express-server-adapter/tsconfig.json new file mode 100644 index 000000000..2ebc04d72 --- /dev/null +++ b/packages/oc-express-server-adapter/tsconfig.json @@ -0,0 +1,33 @@ +{ + "include": ["src"], + "exclude": ["node_modules"], + "compilerOptions": { + "target": "ES2022", + "module": "commonjs", + "moduleResolution": "bundler", + "types": ["node", "jest"], + "declaration": true, + "rootDir": "./src", + "outDir": "./dist", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitAny": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "strictBindCallApply": true, + "strictPropertyInitialization": true, + "noImplicitThis": true, + "useUnknownInCatchVariables": true, + "alwaysStrict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "allowUnusedLabels": false, + "allowUnreachableCode": false, + "skipLibCheck": true + } +} diff --git a/packages/oc-express-server-adapter/tsconfig.test.json b/packages/oc-express-server-adapter/tsconfig.test.json new file mode 100644 index 000000000..a2bd6818b --- /dev/null +++ b/packages/oc-express-server-adapter/tsconfig.test.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "include": ["test/registry-node.ts"], + "compilerOptions": { + "rootDir": "./test", + "outDir": "./dist/test", + "noEmit": false + } +} diff --git a/packages/oc/package.json b/packages/oc/package.json index 207cd6fcb..f6a22a3d1 100644 --- a/packages/oc/package.json +++ b/packages/oc/package.json @@ -41,18 +41,13 @@ "@types/accept-language-parser": "^1.5.8", "@types/async": "^3.2.25", "@types/bun": "^1.3.14", - "@types/cookie-parser": "^1.4.10", "@types/cross-spawn": "^6.0.6", - "@types/errorhandler": "^1.5.3", "@types/express": "^5.0.6", "@types/fs-extra": "^11.0.4", "@types/livereload": "^0.9.5", - "@types/morgan": "^1.9.10", - "@types/multer": "^2.1.0", "@types/node": "^25.9.3", "@types/parse-author": "^2.0.3", "@types/read": "^0.0.32", - "@types/response-time": "^2.3.9", "@types/semver": "^7.7.1", "@types/targz": "^1.0.5", "@types/yargs": "^17.0.35", @@ -79,11 +74,9 @@ "builtin-modules": "^3.3.0", "chokidar": "^4.0.3", "colors": "^1.4.0", - "cookie-parser": "^1.4.7", "cross-spawn": "^7.0.6", "dependency-graph": "^1.0.0", "dotenv": "^17.4.2", - "errorhandler": "^1.5.2", "esbuild": "^0.25.12", "express": "^5.2.1", "form-data": "^4.0.6", @@ -91,12 +84,11 @@ "getport": "^0.1.0", "livereload": "^0.10.3", "lodash.isequal": "^4.5.0", - "morgan": "^1.11.0", - "multer": "^2.0.2", "nice-cache": "^0.0.5", "oc-client": "^4.0.3", "oc-client-browser": "^2.1.11", "oc-empty-response-handler": "^1.0.2", + "oc-express-server-adapter": "^0.1.0", "oc-get-unix-utc-timestamp": "^1.0.6", "oc-metadata-adapters-utils": "^0.1.1", "oc-s3-storage-adapter": "^2.2.3", @@ -111,7 +103,6 @@ "parse-author": "^2.0.0", "read": "^1.0.7", "require-package-name": "^2.0.1", - "response-time": "^2.3.4", "semver": "^7.8.4", "semver-extra": "^3.0.0", "serialize-error": "^12.0.0", diff --git a/packages/oc/src/registry/domain/options-sanitiser.ts b/packages/oc/src/registry/domain/options-sanitiser.ts index 6edcaacf6..2b14d63c4 100644 --- a/packages/oc/src/registry/domain/options-sanitiser.ts +++ b/packages/oc/src/registry/domain/options-sanitiser.ts @@ -1,9 +1,9 @@ import zlib from 'node:zlib'; import { compileSync } from 'oc-client-browser'; +import createExpressAdapter from 'oc-express-server-adapter'; import settings from '../../resources/settings'; import type { Config } from '../../types'; import * as auth from './authentication'; -import createExpressAdapter from './http-server/express-adapter'; import type { HttpServerAdapterFactory } from './http-server/types'; const DEFAULT_NODE_KEEPALIVE_MS = 5000; diff --git a/packages/oc/test/unit/registry-domain-options-sanitiser.js b/packages/oc/test/unit/registry-domain-options-sanitiser.js index fd692810d..a0eeefdea 100644 --- a/packages/oc/test/unit/registry-domain-options-sanitiser.js +++ b/packages/oc/test/unit/registry-domain-options-sanitiser.js @@ -23,7 +23,7 @@ describe('registry : domain : options-sanitiser', () => { it('should default to the Express HTTP server adapter', () => { expect(sanitise(options).server.adapter).to.equal( - require('../../dist/registry/domain/http-server/express-adapter').default + require('oc-express-server-adapter').default ); expect(sanitise(options).server.options).to.eql({ port: 3000 }); }); @@ -35,8 +35,7 @@ describe('registry : domain : options-sanitiser', () => { it('should default to the Express HTTP server adapter', () => { expect(sanitise(options).server.adapter).to.equal( - require('../../dist/registry/domain/http-server/express-adapter') - .default + require('oc-express-server-adapter').default ); }); });