From 9bf4e85b34f355dd71870c87df77bd1fc2b5d8bc Mon Sep 17 00:00:00 2001 From: Pagan Gazzard Date: Mon, 30 Dec 2024 13:20:32 +0000 Subject: [PATCH] Convert to ESM Change-type: patch --- Gruntfile.ts => Gruntfile.cts | 31 +++------ bin/abstract-sql-compiler.js | 2 +- bin/odata-compiler.js | 2 +- bin/sbvr-compiler.js | 2 +- build/{browser.ts => browser.cts} | 2 +- build/{config.ts => config.cts} | 6 +- build/{module.ts => module.cts} | 2 +- build/{server.ts => server.cts} | 2 +- package.json | 16 ++--- src/bin/abstract-sql-compiler.ts | 6 +- src/bin/odata-compiler.ts | 6 +- src/bin/sbvr-compiler.ts | 2 +- src/bin/utils.ts | 30 ++++---- src/config-loader/config-loader.ts | 18 ++--- src/config-loader/env.ts | 4 +- src/data-server/sbvr-server.ts | 8 +-- src/database-layer/db.ts | 29 +++++--- .../extended-sbvr-parser.ts | 10 +-- src/http-transactions/transactions.js | 8 +-- src/migrator/async.ts | 10 +-- src/migrator/sync.ts | 16 ++--- src/migrator/utils.ts | 14 ++-- .../odata-metadata-generator.ts | 5 +- src/passport-pinejs/mount-login-router.ts | 6 +- src/passport-pinejs/passport-pinejs.ts | 6 +- .../pinejs-session-store.ts | 8 +-- src/sbvr-api/abstract-sql.ts | 10 +-- src/sbvr-api/cached-compile.ts | 2 +- src/sbvr-api/control-flow.ts | 2 +- src/sbvr-api/errors.ts | 2 +- src/sbvr-api/express-extension.ts | 4 +- src/sbvr-api/hooks.ts | 10 +-- src/sbvr-api/odata-response.ts | 12 ++-- src/sbvr-api/permissions.ts | 32 ++++----- src/sbvr-api/sbvr-utils.ts | 68 ++++++++++--------- src/sbvr-api/translations.ts | 2 +- src/sbvr-api/uri-parser.ts | 18 ++--- src/server-glue/global-ext.d.ts | 3 - src/server-glue/module.ts | 38 +++++------ src/server-glue/sbvr-loader.ts | 42 ++++-------- src/server-glue/server.ts | 37 ++++------ src/tasks/common.ts | 2 +- src/tasks/index.ts | 26 +++---- src/tasks/worker.ts | 16 ++--- .../handlers/NoopHandler.ts | 6 +- src/webresource-handler/handlers/S3Handler.ts | 2 +- src/webresource-handler/handlers/index.ts | 4 +- src/webresource-handler/index.ts | 16 ++--- test/00-basic.test.ts | 4 +- test/01-constrain.test.ts | 4 +- test/02-sync-migrator.test.ts | 4 +- test/03-async-migrator.test.ts | 8 +-- test/04-translations.test.ts | 9 +-- test/05-request-cancellation.test.ts | 11 +-- test/06-webresource.test.ts | 12 ++-- test/07-permissions.test.ts | 8 +-- test/08-tasks.test.ts | 10 +-- test/fixtures/00-basic/config.ts | 4 +- test/fixtures/01-constrain/config.ts | 4 +- .../02-sync-migrator/00-execute-model.ts | 6 +- .../02-sync-migrator/01-migrations.ts | 6 +- .../0002-test-migrations.sync.ts | 2 +- .../02-sync-migrator/02-migrations-error.ts | 6 +- .../0002-test-migrations.sync.ts | 2 +- .../02-sync-migrator/03-exclusive-category.ts | 6 +- .../04-new-model-with-init.ts | 8 +-- .../03-async-migrator/00-execute-model.ts | 6 +- .../03-async-migrator/01-migrations.ts | 6 +- .../migrations/0002-test-migrations.async.ts | 2 +- .../0003-finalized-test-migration.async.ts | 2 +- .../02-parallel-migrations.ts | 7 +- .../migrations/0001-migrate-testa.async.ts | 2 +- .../migrations/0002-migrate-testb.async.ts | 2 +- .../03-async-migrator/03-finalize-async.ts | 6 +- .../migrations/m0001-data-copy.async.ts | 2 +- .../migrations/m0002-data-copy.async.ts | 2 +- .../03-async-migrator/04-migration-errors.ts | 6 +- .../0001-successful-migration.async.ts | 2 +- .../migrations/0002-table-not-exists.async.ts | 2 +- .../migrations/0003-error-unique-key.async.ts | 2 +- .../03-async-migrator/05-massive-data.ts | 6 +- .../05-massive-data/00-execute-model.ts | 6 +- .../0001-massive-migration.async.ts | 2 +- .../03-async-migrator/06-setup-errors.ts | 6 +- .../0001-error-async-sync-pair.async.ts | 2 +- .../07-setup-error-mixed-migrations.ts | 2 +- .../08-01-async-lock-taker.ts | 4 +- .../08-02-sync-lock-starvation.ts | 6 +- test/fixtures/04-translations/config.ts | 21 +++--- .../04-translations/translations/hooks.ts | 6 +- .../04-translations/translations/v1/hooks.ts | 2 +- .../04-translations/translations/v1/index.ts | 8 +-- .../04-translations/translations/v2/hooks.ts | 4 +- .../04-translations/translations/v2/index.ts | 8 +-- .../04-translations/translations/v3/hooks.ts | 2 +- .../04-translations/translations/v3/index.ts | 8 +-- .../04-translations/translations/v4/index.ts | 6 +- .../04-translations/translations/v5/index.ts | 6 +- .../05-request-cancellation/config.ts | 4 +- .../fixtures/05-request-cancellation/hooks.ts | 4 +- .../05-request-cancellation/routes.ts | 8 +-- test/fixtures/05-request-cancellation/util.ts | 2 +- test/fixtures/06-webresource/config.ts | 10 +-- .../06-webresource/translations/hooks.ts | 2 +- .../06-webresource/translations/v1/hooks.ts | 2 +- .../06-webresource/translations/v1/index.ts | 8 +-- test/fixtures/07-permissions/config.ts | 4 +- test/fixtures/08-tasks/config.ts | 8 +-- test/fixtures/08-tasks/task-handlers.ts | 2 +- test/lib/pine-in-process.ts | 18 ++--- test/lib/pine-init.ts | 2 +- test/lib/test-init.ts | 8 +-- tsconfig.dev.json | 6 +- tsconfig.json | 2 +- typings/lf-to-abstract-sql.d.ts | 4 +- typings/memoizee.d.ts | 2 +- 116 files changed, 484 insertions(+), 485 deletions(-) rename Gruntfile.ts => Gruntfile.cts (85%) rename build/{browser.ts => browser.cts} (95%) rename build/{config.ts => config.cts} (91%) rename build/{module.ts => module.cts} (93%) rename build/{server.ts => server.cts} (91%) diff --git a/Gruntfile.ts b/Gruntfile.cts similarity index 85% rename from Gruntfile.ts rename to Gruntfile.cts index 74f3e1228..c3d79c66f 100644 --- a/Gruntfile.ts +++ b/Gruntfile.cts @@ -3,9 +3,9 @@ import type { WebpackPluginInstance } from 'webpack'; import _ from 'lodash'; import TerserPlugin from 'terser-webpack-plugin'; -import browserConfig from './build/browser'; -import moduleConfig from './build/module'; -import serverConfig from './build/server'; +import browserConfig from './build/browser.cts'; +import moduleConfig from './build/module.cts'; +import serverConfig from './build/server.cts'; const serverConfigs = { browser: browserConfig, @@ -110,30 +110,18 @@ export = (grunt: typeof Grunt) => { return renames; })(), - replace: { - 'pine.js': { + replace: _.mapValues(serverConfigs, (_config, task) => { + return { src: 'out/pine.js', overwrite: true, replacements: [ { - from: /nodeRequire/g, - to: 'require', + from: /sourceMappingURL=pine.js.map/g, + to: `sourceMappingURL=pine-${task}-<%= grunt.option('version') %>.js.map`, }, ], - }, - ..._.mapValues(serverConfigs, (_config, task) => { - return { - src: 'out/pine.js', - overwrite: true, - replacements: [ - { - from: /sourceMappingURL=pine.js.map/g, - to: `sourceMappingURL=pine-${task}-<%= grunt.option('version') %>.js.map`, - }, - ], - }; - }), - }, + }; + }), webpack: serverConfigs, @@ -167,7 +155,6 @@ export = (grunt: typeof Grunt) => { 'webpack:' + task, 'gitinfo:describe', 'version', - 'replace:pine.js', `replace:${task}`, `concat:${task}`, `rename:${task}`, diff --git a/bin/abstract-sql-compiler.js b/bin/abstract-sql-compiler.js index 594fd1936..67781b1a1 100755 --- a/bin/abstract-sql-compiler.js +++ b/bin/abstract-sql-compiler.js @@ -1,2 +1,2 @@ #!/usr/bin/env node -require('../out/bin/abstract-sql-compiler'); +import '../out/bin/abstract-sql-compiler.js'; diff --git a/bin/odata-compiler.js b/bin/odata-compiler.js index e58f90d2d..8082df797 100755 --- a/bin/odata-compiler.js +++ b/bin/odata-compiler.js @@ -1,2 +1,2 @@ #!/usr/bin/env node -require('../out/bin/odata-compiler'); +import '../out/bin/odata-compiler.js'; diff --git a/bin/sbvr-compiler.js b/bin/sbvr-compiler.js index e9b0e2dc6..547bb82ba 100755 --- a/bin/sbvr-compiler.js +++ b/bin/sbvr-compiler.js @@ -1,2 +1,2 @@ #!/usr/bin/env node -require('../out/bin/sbvr-compiler'); +import '../out/bin/sbvr-compiler.js'; diff --git a/build/browser.ts b/build/browser.cts similarity index 95% rename from build/browser.ts rename to build/browser.cts index e2364d522..9007344e9 100644 --- a/build/browser.ts +++ b/build/browser.cts @@ -1,6 +1,6 @@ import * as webpack from 'webpack'; import type { Configuration } from 'webpack'; -import sharedConfig from './config'; +import sharedConfig from './config.cts'; if (typeof sharedConfig.externals !== 'object') { throw new Error('Expected externals to be an object'); diff --git a/build/config.ts b/build/config.cts similarity index 91% rename from build/config.ts rename to build/config.cts index 8d900c3a5..2a4159df1 100644 --- a/build/config.ts +++ b/build/config.cts @@ -1,4 +1,4 @@ -import type { RequiredField } from '../src/sbvr-api/common-types'; +import type { RequiredField } from '../src/sbvr-api/common-types.js' with { 'resolution-mode': 'import' }; import * as path from 'path'; import * as webpack from 'webpack'; @@ -46,6 +46,10 @@ const config: RequiredField< }, resolve: { extensions: ['.js', '.ts'], + extensionAlias: { + '.js': ['.ts', '.js'], + '.mjs': ['.mts', '.mjs'], + }, }, plugins: [new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 })], module: { diff --git a/build/module.ts b/build/module.cts similarity index 93% rename from build/module.ts rename to build/module.cts index eafb8d19d..25f924781 100644 --- a/build/module.ts +++ b/build/module.cts @@ -1,6 +1,6 @@ import * as webpack from 'webpack'; import type { Configuration } from 'webpack'; -import sharedConfig from './config'; +import sharedConfig from './config.cts'; const config: Configuration = { ...sharedConfig, diff --git a/build/server.ts b/build/server.cts similarity index 91% rename from build/server.ts rename to build/server.cts index e5d4c58c2..6154b34b7 100644 --- a/build/server.ts +++ b/build/server.cts @@ -1,6 +1,6 @@ import * as webpack from 'webpack'; import type { Configuration } from 'webpack'; -import sharedConfig from './config'; +import sharedConfig from './config.cts'; const config: Configuration = { ...sharedConfig, diff --git a/package.json b/package.json index 83d04a9e1..55977cd9f 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@balena/pinejs", "version": "19.7.1", "main": "out/server-glue/module", - "type": "commonjs", + "type": "module", "repository": "git@github.com:balena-io/pinejs.git", "license": "Apache-2.0", "bin": { @@ -13,17 +13,17 @@ "scripts": { "prepublish": "require-npm4-to-publish", "prepare": "node -e \"try { (await import('husky')).default() } catch (e) { if (e.code !== 'ERR_MODULE_NOT_FOUND') throw e }\" --input-type module && npm run build", - "build": "grunt build", - "webpack-browser": "grunt browser", - "webpack-module": "grunt module", - "webpack-server": "grunt server", + "build": "grunt --preload ts-node/register/transpile-only --gruntfile Gruntfile.cts build", + "webpack-browser": "grunt --preload ts-node/register/transpile-only --gruntfile Gruntfile.cts browser", + "webpack-module": "grunt --preload ts-node/register/transpile-only --gruntfile Gruntfile.cts module", + "webpack-server": "grunt --preload ts-node/register/transpile-only --gruntfile Gruntfile.cts server", "webpack-build": "npm run webpack-browser && npm run webpack-module && npm run webpack-server", - "lint": "balena-lint -t tsconfig.dev.json -e js -e ts src build typings Gruntfile.ts && npx tsc --project tsconfig.dev.json --noEmit", + "lint": "balena-lint -t tsconfig.dev.json -e js -e ts src build typings Gruntfile.cts && npx tsc --project tsconfig.dev.json --noEmit", "test": "npm run lint && npm run build && npm run webpack-build && npm run test:compose && npm run test:generated-types", "test:compose": "trap 'docker compose -f docker-compose.npm-test.yml down ; echo Stopped ; exit 0' INT; docker compose -f docker-compose.npm-test.yml up -d && sleep 2 && DATABASE_URL=postgres://docker:docker@localhost:5431/postgres PINEJS_WEBRESOURCE_MAXFILESIZE=1000000000 S3_ENDPOINT=http://localhost:43680 S3_ACCESS_KEY=USERNAME S3_SECRET_KEY=PASSWORD S3_STORAGE_ADAPTER_BUCKET=balena-pine-web-resources S3_REGION=us-east-1 PINEJS_QUEUE_CONCURRENCY=1 TZ=UTC npm run mocha", "test:generated-types": "npm run generate-types && git diff --exit-code ./src/sbvr-api/user.ts ./src/migrator/migrations.ts ./src/sbvr-api/dev.ts", "mocha": "TS_NODE_FILES=true mocha", - "lint-fix": "balena-lint -t tsconfig.dev.json -e js -e ts --fix src test build typings Gruntfile.ts", + "lint-fix": "balena-lint -t tsconfig.dev.json -e js -e ts --fix src test build typings Gruntfile.cts", "generate-types": "node ./bin/sbvr-compiler.js generate-types ./src/sbvr-api/user.sbvr ./src/sbvr-api/user.ts && node ./bin/sbvr-compiler.js generate-types ./src/migrator/migrations.sbvr ./src/migrator/migrations.ts && node ./bin/sbvr-compiler.js generate-types ./src/sbvr-api/dev.sbvr ./src/sbvr-api/dev.ts && node ./bin/sbvr-compiler.js generate-types ./src/tasks/tasks.sbvr ./src/tasks/tasks.ts && balena-lint -t tsconfig.dev.json --fix ./src/sbvr-api/user.ts ./src/migrator/migrations.ts ./src/sbvr-api/dev.ts" }, "dependencies": { @@ -141,7 +141,7 @@ "extension": [ ".test.ts" ], - "require": "ts-node/register/transpile-only", + "loader": "ts-node/esm/transpile-only", "exit": true, "timeout": 60000, "recursive": true diff --git a/src/bin/abstract-sql-compiler.ts b/src/bin/abstract-sql-compiler.ts index 6bc65575b..1e3d12bbf 100644 --- a/src/bin/abstract-sql-compiler.ts +++ b/src/bin/abstract-sql-compiler.ts @@ -3,13 +3,13 @@ import { version, writeAll, writeSqlModel, -} from './utils'; +} from './utils.js'; import { program } from 'commander'; const runCompile = async (inputFile: string, outputFile?: string) => { const { generateSqlModel } = await import('../sbvr-api/sbvr-utils.js'); - const abstractSql = getAbstractSqlModelFromFile( + const abstractSql = await getAbstractSqlModelFromFile( inputFile, program.opts().model, ); @@ -28,7 +28,7 @@ const generateTypes = async ( const { abstractSqlToTypescriptTypes } = await import( '@balena/abstract-sql-to-typescript/generate' ); - const abstractSql = getAbstractSqlModelFromFile( + const abstractSql = await getAbstractSqlModelFromFile( inputFile, program.opts().model, ); diff --git a/src/bin/odata-compiler.ts b/src/bin/odata-compiler.ts index 935ece8fd..d94e84e7a 100644 --- a/src/bin/odata-compiler.ts +++ b/src/bin/odata-compiler.ts @@ -1,4 +1,4 @@ -import { getAbstractSqlModelFromFile, version, writeAll } from './utils'; +import { getAbstractSqlModelFromFile, version, writeAll } from './utils.js'; import type { AbstractSqlModel, SqlResult, @@ -44,7 +44,7 @@ const translateOData = async ( outputFile?: string, ) => { const request = await generateAbstractSqlQuery( - getAbstractSqlModelFromFile(modelFile, program.opts().model), + await getAbstractSqlModelFromFile(modelFile, program.opts().model), odata, ); const json = JSON.stringify(request.abstractSqlQuery, null, 2); @@ -68,7 +68,7 @@ const compileOData = async ( outputFile?: string, ) => { const translatedRequest = await generateAbstractSqlQuery( - getAbstractSqlModelFromFile(modelFile, program.opts().model), + await getAbstractSqlModelFromFile(modelFile, program.opts().model), odata, ); const { compileRequest } = await import('../sbvr-api/abstract-sql.js'); diff --git a/src/bin/sbvr-compiler.ts b/src/bin/sbvr-compiler.ts index fa174b445..4036a3bdb 100644 --- a/src/bin/sbvr-compiler.ts +++ b/src/bin/sbvr-compiler.ts @@ -1,4 +1,4 @@ -import { version, writeAll, writeSqlModel } from './utils'; +import { version, writeAll, writeSqlModel } from './utils.js'; import { program } from 'commander'; import * as fs from 'fs'; diff --git a/src/bin/utils.ts b/src/bin/utils.ts index 4da558b89..a4c584541 100644 --- a/src/bin/utils.ts +++ b/src/bin/utils.ts @@ -1,16 +1,17 @@ process.env.PINEJS_CACHE_FILE = - process.env.PINEJS_CACHE_FILE || __dirname + '/.pinejs-cache.json'; + process.env.PINEJS_CACHE_FILE || + fileURLToPath(new URL('.pinejs-cache.json', import.meta.url)); import type { SqlModel } from '@balena/abstract-sql-compiler'; -import type { Config, Model } from '../config-loader/config-loader'; -import type * as SbvrUtils from '../sbvr-api/sbvr-utils'; +import type { Config, Model } from '../config-loader/config-loader.js'; import type { AbstractSqlModel } from '@balena/abstract-sql-compiler'; import * as fs from 'fs'; import * as path from 'path'; -import '../server-glue/sbvr-loader'; +import '../server-glue/sbvr-loader.js'; +import { fileURLToPath } from 'url'; -export { version } from '../config-loader/env'; +export { version } from '../config-loader/env.js'; export const writeAll = (output: string, outputFile?: string): void => { if (outputFile) { @@ -68,15 +69,15 @@ const getConfigModel = ( return fileContents; }; -export const getAbstractSqlModelFromFile = ( +export const getAbstractSqlModelFromFile = async ( modelFile: string, modelName: string | undefined, -): AbstractSqlModel => { +): Promise => { let fileContents: string | Model | AbstractSqlModel | Config; try { - fileContents = require(path.resolve(modelFile)); + fileContents = await import(path.resolve(modelFile)); } catch { - fileContents = fs.readFileSync(require.resolve(modelFile), 'utf8'); + fileContents = fs.readFileSync(import.meta.resolve(modelFile), 'utf8'); } let seModel: string; if (fileContents == null) { @@ -94,16 +95,19 @@ export const getAbstractSqlModelFromFile = ( } else if ('modelText' in configModel && configModel.modelText != null) { seModel = configModel.modelText; } else if ('modelFile' in configModel && configModel.modelFile != null) { - seModel = fs.readFileSync(require.resolve(configModel.modelFile), 'utf8'); + seModel = fs.readFileSync( + import.meta.resolve(configModel.modelFile), + 'utf8', + ); } else { throw new Error('Unrecognized config file'); } } else { throw new Error('Unrecognized config file'); } - const { generateLfModel, generateAbstractSqlModel } = - // eslint-disable-next-line @typescript-eslint/no-var-requires - require('../sbvr-api/sbvr-utils') as typeof SbvrUtils; + const { generateLfModel, generateAbstractSqlModel } = await import( + '../sbvr-api/sbvr-utils.js' + ); let lfModel; try { lfModel = generateLfModel(seModel); diff --git a/src/config-loader/config-loader.ts b/src/config-loader/config-loader.ts index c13ec35da..23c3ae43f 100644 --- a/src/config-loader/config-loader.ts +++ b/src/config-loader/config-loader.ts @@ -3,13 +3,13 @@ import type { AbstractSqlModel, Definition, } from '@balena/abstract-sql-compiler'; -import type { Database } from '../database-layer/db'; +import type { Database } from '../database-layer/db.js'; import type { AnyObject, Dictionary, RequiredField, Resolvable, -} from '../sbvr-api/common-types'; +} from '../sbvr-api/common-types.js'; import { type Migration, @@ -18,23 +18,23 @@ import { MigrationCategories, isSyncMigration, isAsyncMigration, -} from '../migrator/utils'; +} from '../migrator/utils.js'; import * as fs from 'fs'; import _ from 'lodash'; import * as path from 'path'; -import * as sbvrUtils from '../sbvr-api/sbvr-utils'; +import * as sbvrUtils from '../sbvr-api/sbvr-utils.js'; -import * as permissions from '../sbvr-api/permissions'; +import * as permissions from '../sbvr-api/permissions.js'; import { getDefaultHandler, getUploaderMiddlware, type WebResourceHandler, setupUploadHooks, setupWebresourceHandler, -} from '../webresource-handler'; -import type { AliasValidNodeType } from '../sbvr-api/translations'; +} from '../webresource-handler/index.js'; +import type { AliasValidNodeType } from '../sbvr-api/translations.js'; export type SetupFunction = ( app: Express.Application, @@ -256,7 +256,7 @@ export const setup = (app: Express.Application) => { let customCode: SetupFunction; if (typeof model.customServerCode === 'string') { try { - customCode = nodeRequire(model.customServerCode).setup; + customCode = (await import(model.customServerCode)).setup; } catch (e: any) { e.message = `Error loading custom server code: '${e.message}'`; throw e; @@ -291,7 +291,7 @@ export const setup = (app: Express.Application) => { let root: string; let configObj: Config; if (config == null) { - root = path.resolve(process.argv[2]) || __dirname; + root = path.resolve(process.argv[2]) || import.meta.dirname; configObj = await loadConfigFile(path.join(root, 'config.json')); } else if (typeof config === 'string') { root = path.dirname(config); diff --git a/src/config-loader/env.ts b/src/config-loader/env.ts index 4832a6bf6..df981541e 100644 --- a/src/config-loader/env.ts +++ b/src/config-loader/env.ts @@ -1,6 +1,6 @@ import * as fs from 'fs'; export const { version } = JSON.parse( - fs.readFileSync(require.resolve('../../package.json'), 'utf8'), + fs.readFileSync(new URL(import.meta.resolve('../../package.json')), 'utf8'), ); const { PINEJS_DEBUG } = process.env; @@ -56,7 +56,7 @@ export const cache = { import { boolVar, intVar } from '@balena/env-parsing'; import memoize from 'memoizee'; -import memoizeWeak from 'memoizee/weak'; +import memoizeWeak from 'memoizee/weak.js'; export const createCache = any>( cacheName: keyof typeof cache, fn: T, diff --git a/src/data-server/sbvr-server.ts b/src/data-server/sbvr-server.ts index b30367ee9..1527a2361 100644 --- a/src/data-server/sbvr-server.ts +++ b/src/data-server/sbvr-server.ts @@ -1,8 +1,8 @@ -import * as permissions from '../sbvr-api/permissions'; -import type { Resolvable } from '../sbvr-api/common-types'; +import * as permissions from '../sbvr-api/permissions.js'; +import type { Resolvable } from '../sbvr-api/common-types.js'; import type { Handler } from 'express'; -import type { Config, SetupFunction } from '../config-loader/config-loader'; -import type { Tx } from '../database-layer/db'; +import type { Config, SetupFunction } from '../config-loader/config-loader.js'; +import type { Tx } from '../database-layer/db.js'; const uiModel = `\ Vocabulary: ui diff --git a/src/database-layer/db.ts b/src/database-layer/db.ts index 5c5109e2f..97ec5dc5f 100644 --- a/src/database-layer/db.ts +++ b/src/database-layer/db.ts @@ -1,15 +1,15 @@ /// -import type * as Mysql from 'mysql'; -import type * as Pg from 'pg'; -import type * as PgConnectionString from 'pg-connection-string'; -import type { Dictionary, Resolvable } from '../sbvr-api/common-types'; +import type Mysql from 'mysql'; +import type Pg from 'pg'; +import type PgConnectionString from 'pg-connection-string'; +import type { Dictionary, Resolvable } from '../sbvr-api/common-types.js'; import { Engines } from '@balena/abstract-sql-compiler'; import { EventEmitter } from 'eventemitter3'; import _ from 'lodash'; import { TypedError } from 'typed-error'; -import * as env from '../config-loader/env'; -import { fromCallback, timeout } from '../sbvr-api/control-flow'; +import * as env from '../config-loader/env.js'; +import { fromCallback, timeout } from '../sbvr-api/control-flow.js'; export const metrics = new EventEmitter(); @@ -487,8 +487,10 @@ const createTransaction = (createFunc: CreateTransactionFn): TransactionFn => { }; let maybePg: typeof Pg | undefined; +let maybePgConnectionString: typeof PgConnectionString | undefined; try { - maybePg = require('pg'); + maybePg = (await import('pg')).default; + maybePgConnectionString = (await import('pg-connection-string')).default; } catch { // Ignore errors } @@ -543,10 +545,15 @@ if (maybePg != null) { let pool: Pg.Pool; let replica: Pg.Pool; if (typeof connectString === 'string') { - // eslint-disable-next-line @typescript-eslint/no-var-requires - const pgConnectionString: typeof PgConnectionString = require('pg-connection-string'); + if (maybePgConnectionString == null) { + throw new Error( + 'pg-connection-string is required for string connection strings', + ); + } // We have to cast because of the use of null vs undefined - const config = pgConnectionString.parse(connectString) as Pg.PoolConfig; + const config = maybePgConnectionString.parse( + connectString, + ) as Pg.PoolConfig; pool = initPool(config); } else { const config = connectString; @@ -728,7 +735,7 @@ if (maybePg != null) { let maybeMysql: typeof Mysql | undefined; try { - maybeMysql = require('mysql'); + maybeMysql = (await import('mysql')).default; } catch { // Ignore errors } diff --git a/src/extended-sbvr-parser/extended-sbvr-parser.ts b/src/extended-sbvr-parser/extended-sbvr-parser.ts index f1c710f97..de85ea3da 100644 --- a/src/extended-sbvr-parser/extended-sbvr-parser.ts +++ b/src/extended-sbvr-parser/extended-sbvr-parser.ts @@ -1,9 +1,9 @@ import { SBVRParser } from '@balena/sbvr-parser'; -import { requireSBVR } from '../server-glue/sbvr-loader'; -import { version as sbvrParserVersion } from '@balena/sbvr-parser/package.json'; -import { version } from '../config-loader/env'; +import { importSBVR } from '../server-glue/sbvr-loader.js'; +import SbvrParserPackage from '@balena/sbvr-parser/package.json' with { type: 'json' }; +import { version } from '../config-loader/env.js'; -const Types = requireSBVR('@balena/sbvr-types/Type.sbvr', require); +const Types = await importSBVR('@balena/sbvr-types/Type.sbvr', import.meta); export const ExtendedSBVRParser = SBVRParser._extend({ initialize() { @@ -13,5 +13,5 @@ export const ExtendedSBVRParser = SBVRParser._extend({ this.AddBuiltInVocab(Types); return this; }, - version: sbvrParserVersion + '+' + version, + version: SbvrParserPackage.version + '+' + version, }); diff --git a/src/http-transactions/transactions.js b/src/http-transactions/transactions.js index 34a297ec5..c861fde34 100644 --- a/src/http-transactions/transactions.js +++ b/src/http-transactions/transactions.js @@ -1,8 +1,8 @@ import { odataNameToSqlName } from '@balena/odata-to-abstract-sql'; -import { requireSBVR } from '../server-glue/sbvr-loader'; -const transactionModel = requireSBVR('./transaction.sbvr', require); +import { importSBVR } from '../server-glue/sbvr-loader.js'; +const transactionModel = await importSBVR('./transaction.sbvr', import.meta); -/** @type {import('../config-loader/config-loader').Config} */ +/** @type {import('../config-loader/config-loader.js').Config} */ export const config = { models: [ { @@ -53,7 +53,7 @@ ADD COLUMN IF NOT EXISTS "modified at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT N /** @type {(modelName: string) => void} */ export let addModelHooks; -/** @type { import('../config-loader/config-loader').SetupFunction } */ +/** @type { import('../config-loader/config-loader.js').SetupFunction } */ export function setup(app, sbvrUtils) { addModelHooks = (modelName) => { // TODO: Add checks on POST/PATCH requests as well. diff --git a/src/migrator/async.ts b/src/migrator/async.ts index 219fa0b51..053fc2856 100644 --- a/src/migrator/async.ts +++ b/src/migrator/async.ts @@ -1,8 +1,8 @@ -import type { Tx } from '../database-layer/db'; -import type { Model } from '../config-loader/config-loader'; +import type { Tx } from '../database-layer/db.js'; +import type { Model } from '../config-loader/config-loader.js'; import _ from 'lodash'; -import * as sbvrUtils from '../sbvr-api/sbvr-utils'; +import * as sbvrUtils from '../sbvr-api/sbvr-utils.js'; type ApiRootModel = Model & { apiRoot: string }; @@ -24,8 +24,8 @@ import { filterAndSortPendingMigrations, type MigrationStatus, type BaseAsyncMigration, -} from './utils'; -import { booleanToEnabledString } from '../config-loader/env'; +} from './utils.js'; +import { booleanToEnabledString } from '../config-loader/env.js'; export const run = async (tx: Tx, model: ApiRootModel): Promise => { const { migrations } = model; diff --git a/src/migrator/sync.ts b/src/migrator/sync.ts index 282b02df1..ff2cf62b0 100644 --- a/src/migrator/sync.ts +++ b/src/migrator/sync.ts @@ -1,4 +1,4 @@ -import type MigrationsModel from './migrations'; +import type MigrationsModel from './migrations.js'; import { type MigrationTuple, MigrationError, @@ -9,15 +9,15 @@ import { type RunnableMigrations, filterAndSortPendingMigrations, getRunnableSyncMigrations, -} from './utils'; -import type { Tx } from '../database-layer/db'; -import type { Config, Model } from '../config-loader/config-loader'; +} from './utils.js'; +import type { Tx } from '../database-layer/db.js'; +import type { Config, Model } from '../config-loader/config-loader.js'; import _ from 'lodash'; -import * as sbvrUtils from '../sbvr-api/sbvr-utils'; -import { requireSBVR } from '../server-glue/sbvr-loader'; +import * as sbvrUtils from '../sbvr-api/sbvr-utils.js'; +import { importSBVR } from '../server-glue/sbvr-loader.js'; -const migrationsModel = requireSBVR('./migrations.sbvr', require); +const migrationsModel = await importSBVR('./migrations.sbvr', import.meta); type ApiRootModel = Model & { apiRoot: string }; @@ -137,7 +137,7 @@ const executeMigration = async ( } }; -declare module '../sbvr-api/sbvr-utils' { +declare module '../sbvr-api/sbvr-utils.js' { export interface API { [migrationModelConfig.apiRoot]: PinejsClient; } diff --git a/src/migrator/utils.ts b/src/migrator/utils.ts index 061fcf530..cb934c056 100644 --- a/src/migrator/utils.ts +++ b/src/migrator/utils.ts @@ -1,16 +1,16 @@ -import type { Result, Tx } from '../database-layer/db'; -import type { Resolvable } from '../sbvr-api/common-types'; +import type { Result, Tx } from '../database-layer/db.js'; +import type { Resolvable } from '../sbvr-api/common-types.js'; import { createHash } from 'crypto'; import { Engines } from '@balena/abstract-sql-compiler'; import _ from 'lodash'; import { TypedError } from 'typed-error'; -import { migrator as migratorEnv } from '../config-loader/env'; -export { migrator as migratorEnv } from '../config-loader/env'; -import { PINEJS_ADVISORY_LOCK } from '../config-loader/env'; -import { delay } from '../sbvr-api/control-flow'; +import { migrator as migratorEnv } from '../config-loader/env.js'; +export { migrator as migratorEnv } from '../config-loader/env.js'; +import { PINEJS_ADVISORY_LOCK } from '../config-loader/env.js'; +import { delay } from '../sbvr-api/control-flow.js'; -import * as sbvrUtils from '../sbvr-api/sbvr-utils'; +import * as sbvrUtils from '../sbvr-api/sbvr-utils.js'; export enum MigrationCategories { 'sync' = 'sync', 'async' = 'async', diff --git a/src/odata-metadata/odata-metadata-generator.ts b/src/odata-metadata/odata-metadata-generator.ts index 3208067c1..efb674af0 100644 --- a/src/odata-metadata/odata-metadata-generator.ts +++ b/src/odata-metadata/odata-metadata-generator.ts @@ -3,8 +3,9 @@ import type { AbstractSqlTable, } from '@balena/abstract-sql-compiler'; -import sbvrTypes, { type SbvrType } from '@balena/sbvr-types'; -import { version } from '../config-loader/env'; +import type { SbvrType } from '@balena/sbvr-types'; +import { sbvrTypes } from '../sbvr-api/sbvr-utils.js'; +import { version } from '../config-loader/env.js'; const getResourceName = (resourceName: string): string => resourceName diff --git a/src/passport-pinejs/mount-login-router.ts b/src/passport-pinejs/mount-login-router.ts index a6c59bb96..aed8effed 100644 --- a/src/passport-pinejs/mount-login-router.ts +++ b/src/passport-pinejs/mount-login-router.ts @@ -1,7 +1,7 @@ -import * as passportPinejs from './passport-pinejs'; +import * as passportPinejs from './passport-pinejs.js'; import type { Express } from 'express'; -import { PinejsSessionStore } from '../pinejs-session-store/pinejs-session-store'; -import type { setup } from '../config-loader/config-loader'; +import { PinejsSessionStore } from '../pinejs-session-store/pinejs-session-store.js'; +import type { setup } from '../config-loader/config-loader.js'; export const mountLoginRouter = async ( configLoader: ReturnType, diff --git a/src/passport-pinejs/passport-pinejs.ts b/src/passport-pinejs/passport-pinejs.ts index ea3964f20..ce79fd4e0 100644 --- a/src/passport-pinejs/passport-pinejs.ts +++ b/src/passport-pinejs/passport-pinejs.ts @@ -1,10 +1,10 @@ import type * as Express from 'express'; import type * as Passport from 'passport'; import type * as PassportLocal from 'passport-local'; -import type * as ConfigLoader from '../config-loader/config-loader'; -import type { User } from '../sbvr-api/sbvr-utils'; +import type * as ConfigLoader from '../config-loader/config-loader.js'; +import type { User } from '../sbvr-api/sbvr-utils.js'; -import * as permissions from '../sbvr-api/permissions'; +import * as permissions from '../sbvr-api/permissions.js'; // Returns a middleware that will handle logging in using `username` and `password` body properties export let login: ( diff --git a/src/pinejs-session-store/pinejs-session-store.ts b/src/pinejs-session-store/pinejs-session-store.ts index ed855ca52..40d9ace86 100644 --- a/src/pinejs-session-store/pinejs-session-store.ts +++ b/src/pinejs-session-store/pinejs-session-store.ts @@ -1,9 +1,9 @@ -import type { Config } from '../config-loader/config-loader'; -import type { AnyObject } from '../sbvr-api/common-types'; +import type { Config } from '../config-loader/config-loader.js'; +import type { AnyObject } from '../sbvr-api/common-types.js'; import { Store } from 'express-session'; -import * as permissions from '../sbvr-api/permissions'; -import { api } from '../sbvr-api/sbvr-utils'; +import * as permissions from '../sbvr-api/permissions.js'; +import { api } from '../sbvr-api/sbvr-utils.js'; export { Store }; diff --git a/src/sbvr-api/abstract-sql.ts b/src/sbvr-api/abstract-sql.ts index f9da809fb..e56d99713 100644 --- a/src/sbvr-api/abstract-sql.ts +++ b/src/sbvr-api/abstract-sql.ts @@ -7,12 +7,12 @@ import { odataNameToSqlName, isBindReference, } from '@balena/odata-to-abstract-sql'; -import deepFreeze = require('deep-freeze'); +import deepFreeze from 'deep-freeze'; import memoize from 'memoizee'; -import * as env from '../config-loader/env'; -import { BadRequestError, SqlCompilationError } from './errors'; -import * as sbvrUtils from './sbvr-utils'; -import type { ODataRequest } from './uri-parser'; +import * as env from '../config-loader/env.js'; +import { BadRequestError, SqlCompilationError } from './errors.js'; +import * as sbvrUtils from './sbvr-utils.js'; +import type { ODataRequest } from './uri-parser.js'; const getMemoizedCompileRule = memoize( (engine: AbstractSQLCompiler.Engines) => diff --git a/src/sbvr-api/cached-compile.ts b/src/sbvr-api/cached-compile.ts index 5f5644585..6a74f07e6 100644 --- a/src/sbvr-api/cached-compile.ts +++ b/src/sbvr-api/cached-compile.ts @@ -12,7 +12,7 @@ let cache: null | { } = null; let fs: undefined | typeof Fs; try { - fs = require('fs'); + fs = await import('fs'); } catch { // Ignore error } diff --git a/src/sbvr-api/control-flow.ts b/src/sbvr-api/control-flow.ts index c608ab014..d8231cb41 100644 --- a/src/sbvr-api/control-flow.ts +++ b/src/sbvr-api/control-flow.ts @@ -1,4 +1,4 @@ -import type { Resolvable } from './common-types'; +import type { Resolvable } from './common-types.js'; import _ from 'lodash'; import { TypedError } from 'typed-error'; diff --git a/src/sbvr-api/errors.ts b/src/sbvr-api/errors.ts index 2a3959f99..057cbe5c4 100644 --- a/src/sbvr-api/errors.ts +++ b/src/sbvr-api/errors.ts @@ -1,4 +1,4 @@ -import type { AnyObject, Tail } from './common-types'; +import type { AnyObject, Tail } from './common-types.js'; import { TypedError } from 'typed-error'; diff --git a/src/sbvr-api/express-extension.ts b/src/sbvr-api/express-extension.ts index dddcad519..0c5b62a87 100644 --- a/src/sbvr-api/express-extension.ts +++ b/src/sbvr-api/express-extension.ts @@ -3,7 +3,7 @@ declare global { // eslint-disable-next-line @typescript-eslint/no-namespace namespace Express { - type PineUser = import('./sbvr-utils').User; + type PineUser = import('./sbvr-utils.js').User; // Augment Express.User to include the props of our PineUser. // eslint-disable-next-line @typescript-eslint/no-empty-interface @@ -11,7 +11,7 @@ declare global { interface Request { user?: User; - apiKey?: import('./sbvr-utils').ApiKey; + apiKey?: import('./sbvr-utils.js').ApiKey; } } } diff --git a/src/sbvr-api/hooks.ts b/src/sbvr-api/hooks.ts index 1be74db6c..b3b3b95c8 100644 --- a/src/sbvr-api/hooks.ts +++ b/src/sbvr-api/hooks.ts @@ -1,12 +1,12 @@ -import type { OptionalField, Resolvable } from './common-types'; -import type { Result, Tx } from '../database-layer/db'; -import type { ODataRequest, ParsedODataRequest } from './uri-parser'; +import type { OptionalField, Resolvable } from './common-types.js'; +import type { Result, Tx } from '../database-layer/db.js'; +import type { ODataRequest, ParsedODataRequest } from './uri-parser.js'; import type { AnyObject } from 'pinejs-client-core'; import type { TypedError } from 'typed-error'; import type { SupportedMethod } from '@balena/odata-to-abstract-sql'; import _ from 'lodash'; -import { settleMapSeries } from './control-flow'; +import { settleMapSeries } from './control-flow.js'; import memoize from 'memoizee'; import { type User, @@ -15,7 +15,7 @@ import { getAbstractSqlModel, api, type Response, -} from './sbvr-utils'; +} from './sbvr-utils.js'; export interface HookReq { user?: User; diff --git a/src/sbvr-api/odata-response.ts b/src/sbvr-api/odata-response.ts index d7a407e65..0dbea2481 100644 --- a/src/sbvr-api/odata-response.ts +++ b/src/sbvr-api/odata-response.ts @@ -18,13 +18,17 @@ declare module '@balena/abstract-sql-compiler' { } } -import type { Result, Row } from '../database-layer/db'; +import type { Result, Row } from '../database-layer/db.js'; import { sqlNameToODataName } from '@balena/odata-to-abstract-sql'; -import sbvrTypes, { type SbvrType } from '@balena/sbvr-types'; +import type { SbvrType } from '@balena/sbvr-types'; import _ from 'lodash'; -import { resolveNavigationResource, resolveSynonym } from './sbvr-utils'; -import { getWebresourceHandler } from '../webresource-handler'; +import { + sbvrTypes, + resolveNavigationResource, + resolveSynonym, +} from './sbvr-utils.js'; +import { getWebresourceHandler } from '../webresource-handler/index.js'; const checkForExpansion = async ( vocab: string, diff --git a/src/sbvr-api/permissions.ts b/src/sbvr-api/permissions.ts index 37f95192f..b50ed0320 100644 --- a/src/sbvr-api/permissions.ts +++ b/src/sbvr-api/permissions.ts @@ -1,4 +1,4 @@ -import type AuthModel from './user'; +import type AuthModel from './user.js'; import type { AbstractSqlModel, AbstractSqlQuery, @@ -14,16 +14,16 @@ import type { SelectNode, SelectQueryNode, } from '@balena/abstract-sql-compiler'; -import './express-extension'; +import './express-extension.js'; import type * as Express from 'express'; import type { ODataBinds, ODataQuery, SupportedMethod, } from '@balena/odata-parser'; -import type { Tx } from '../database-layer/db'; -import type { ApiKey, User } from '../sbvr-api/sbvr-utils'; -import type { AnyObject, Dictionary } from './common-types'; +import type { Tx } from '../database-layer/db.js'; +import type { ApiKey, User } from '../sbvr-api/sbvr-utils.js'; +import type { AnyObject, Dictionary } from './common-types.js'; import { isBindReference, @@ -37,27 +37,27 @@ import * as ODataParser from '@balena/odata-parser'; import _ from 'lodash'; import memoize from 'memoizee'; import * as randomstring from 'randomstring'; -import * as env from '../config-loader/env'; -import * as sbvrUtils from '../sbvr-api/sbvr-utils'; -import { type HookReq, addPureHook, addHook } from './hooks'; +import * as env from '../config-loader/env.js'; +import * as sbvrUtils from '../sbvr-api/sbvr-utils.js'; +import { type HookReq, addPureHook, addHook } from './hooks.js'; import { BadRequestError, PermissionError, PermissionParsingError, -} from './errors'; +} from './errors.js'; import { memoizedGetOData2AbstractSQL, memoizedParseOdata, metadataEndpoints, type ODataRequest, -} from './uri-parser'; -import memoizeWeak from 'memoizee/weak'; -import type { Config } from '../config-loader/config-loader'; +} from './uri-parser.js'; +import memoizeWeak from 'memoizee/weak.js'; +import type { Config } from '../config-loader/config-loader.js'; import type { ODataOptions } from 'pinejs-client-core'; -import type { Permission } from './user'; -import { requireSBVR } from '../server-glue/sbvr-loader'; +import type { Permission } from './user.js'; +import { importSBVR } from '../server-glue/sbvr-loader.js'; -const userModel = requireSBVR('./user.sbvr', require); +const userModel = await importSBVR('./user.sbvr', import.meta); const DEFAULT_ACTOR_BIND = '@__ACTOR_ID'; const DEFAULT_ACTOR_BIND_REGEX = new RegExp( @@ -1779,7 +1779,7 @@ export const addPermissions = async ( } }; -declare module './sbvr-utils' { +declare module './sbvr-utils.js' { export interface API { [authModelConfig.apiRoot]: PinejsClient; } diff --git a/src/sbvr-api/sbvr-utils.ts b/src/sbvr-api/sbvr-utils.ts index 5eae6d644..4892757f8 100644 --- a/src/sbvr-api/sbvr-utils.ts +++ b/src/sbvr-api/sbvr-utils.ts @@ -1,7 +1,7 @@ import type * as Express from 'express'; -import type * as Db from '../database-layer/db'; -import type { Model } from '../config-loader/config-loader'; -import type { AnyObject, RequiredField } from './common-types'; +import type * as Db from '../database-layer/db.js'; +import type { Model } from '../config-loader/config-loader.js'; +import type { AnyObject, RequiredField } from './common-types.js'; import type { PickDeferred, Resource, @@ -21,12 +21,14 @@ declare global { import _ from 'lodash'; import type { TypedError } from 'typed-error'; -import { cachedCompile } from './cached-compile'; +import { cachedCompile } from './cached-compile.js'; type LFModel = any[]; import * as AbstractSQLCompiler from '@balena/abstract-sql-compiler'; -import { version as AbstractSQLCompilerVersion } from '@balena/abstract-sql-compiler/package.json'; -import * as LF2AbstractSQL from '@balena/lf-to-abstract-sql'; +import AbstractSqlCompilerPackage from '@balena/abstract-sql-compiler/package.json' with { type: 'json' }; +const { version: AbstractSQLCompilerVersion } = AbstractSqlCompilerPackage; + +import LF2AbstractSQL from '@balena/lf-to-abstract-sql'; import { type ODataBinds, @@ -34,21 +36,22 @@ import { sqlNameToODataName, type SupportedMethod, } from '@balena/odata-to-abstract-sql'; -import sbvrTypes from '@balena/sbvr-types'; -import deepFreeze = require('deep-freeze'); +import $sbvrTypes from '@balena/sbvr-types'; +const { default: sbvrTypes } = $sbvrTypes; +import deepFreeze from 'deep-freeze'; import type { ODataOptions, Params } from 'pinejs-client-core'; import { PinejsClientCore, type PromiseResultTypes } from 'pinejs-client-core'; -import { ExtendedSBVRParser } from '../extended-sbvr-parser/extended-sbvr-parser'; +import { ExtendedSBVRParser } from '../extended-sbvr-parser/extended-sbvr-parser.js'; -import * as asyncMigrator from '../migrator/async'; -import * as syncMigrator from '../migrator/sync'; -import { generateODataMetadata } from '../odata-metadata/odata-metadata-generator'; -import { requireSBVR } from '../server-glue/sbvr-loader'; +import * as asyncMigrator from '../migrator/async.js'; +import * as syncMigrator from '../migrator/sync.js'; +import { generateODataMetadata } from '../odata-metadata/odata-metadata-generator.js'; +import { importSBVR } from '../server-glue/sbvr-loader.js'; -import type DevModel from './dev'; -const devModel = requireSBVR('./dev.sbvr', require); -import * as permissions from './permissions'; +import type DevModel from './dev.js'; +const devModel = await importSBVR('./dev.sbvr', import.meta); +import * as permissions from './permissions.js'; import { BadRequestError, ConflictError, @@ -63,9 +66,9 @@ import { statusCodeToError, TranslationError, UnauthorizedError, -} from './errors'; -import * as uriParser from './uri-parser'; -export type { ODataRequest } from './uri-parser'; +} from './errors.js'; +import * as uriParser from './uri-parser.js'; +export type { ODataRequest } from './uri-parser.js'; import { type HookReq, type HookArgs, @@ -73,7 +76,7 @@ import { getHooks, runHooks, type InstantiatedHooks, -} from './hooks'; +} from './hooks.js'; export { type HookReq, type HookArgs, @@ -81,30 +84,33 @@ export { type Hooks, addPureHook, addSideEffectHook, -} from './hooks'; +} from './hooks.js'; -import memoizeWeak from 'memoizee/weak'; -import * as controlFlow from './control-flow'; +import memoizeWeak from 'memoizee/weak.js'; +import * as controlFlow from './control-flow.js'; export let db = undefined as any as Db.Database; export { sbvrTypes }; -import { version as LF2AbstractSQLVersion } from '@balena/lf-to-abstract-sql/package.json'; -import { version as sbvrTypesVersion } from '@balena/sbvr-types/package.json'; +import LF2AbstractSQLPackage from '@balena/lf-to-abstract-sql/package.json' with { type: 'json' }; +const { version: LF2AbstractSQLVersion } = LF2AbstractSQLPackage; +import SbvrTypesPackage from '@balena/sbvr-types/package.json' with { type: 'json' }; +const { version: sbvrTypesVersion } = SbvrTypesPackage; + import { compileRequest, getAndCheckBindValues, isRuleAffected, -} from './abstract-sql'; -export { resolveOdataBind } from './abstract-sql'; -import * as odataResponse from './odata-response'; -import { env } from '../server-glue/module'; -import { translateAbstractSqlModel } from './translations'; +} from './abstract-sql.js'; +export { resolveOdataBind } from './abstract-sql.js'; +import * as odataResponse from './odata-response.js'; +import { env } from '../server-glue/module.js'; +import { translateAbstractSqlModel } from './translations.js'; import { type MigrationExecutionResult, setExecutedMigrations, -} from '../migrator/utils'; +} from '../migrator/utils.js'; const LF2AbstractSQLTranslator = LF2AbstractSQL.createTranslator(sbvrTypes); const LF2AbstractSQLTranslatorVersion = `${LF2AbstractSQLVersion}+${sbvrTypesVersion}`; diff --git a/src/sbvr-api/translations.ts b/src/sbvr-api/translations.ts index 44aa6470b..734fe1e79 100644 --- a/src/sbvr-api/translations.ts +++ b/src/sbvr-api/translations.ts @@ -14,7 +14,7 @@ import type { UnknownTypeNodes, NullNode, } from '@balena/abstract-sql-compiler'; -import type { Dictionary } from './common-types'; +import type { Dictionary } from './common-types.js'; export type AliasValidNodeType = | ReferencedFieldNode diff --git a/src/sbvr-api/uri-parser.ts b/src/sbvr-api/uri-parser.ts index 548523f75..898a49bbb 100644 --- a/src/sbvr-api/uri-parser.ts +++ b/src/sbvr-api/uri-parser.ts @@ -5,26 +5,26 @@ import type { ODataQuery, SupportedMethod, } from '@balena/odata-parser'; -import type { Tx } from '../database-layer/db'; -import type { InstantiatedHooks } from './hooks'; -import type { AnyObject } from './common-types'; +import type { Tx } from '../database-layer/db.js'; +import type { InstantiatedHooks } from './hooks.js'; +import type { AnyObject } from './common-types.js'; -import * as ODataParser from '@balena/odata-parser'; +import ODataParser from '@balena/odata-parser'; export const SyntaxError = ODataParser.SyntaxError; import { OData2AbstractSQL } from '@balena/odata-to-abstract-sql'; import _ from 'lodash'; -import memoizeWeak from 'memoizee/weak'; +import memoizeWeak from 'memoizee/weak.js'; -export { BadRequestError, ParsingError, TranslationError } from './errors'; +export { BadRequestError, ParsingError, TranslationError } from './errors.js'; import deepFreeze from 'deep-freeze'; -import * as env from '../config-loader/env'; +import * as env from '../config-loader/env.js'; import { BadRequestError, ParsingError, PermissionError, TranslationError, -} from './errors'; -import * as sbvrUtils from './sbvr-utils'; +} from './errors.js'; +import * as sbvrUtils from './sbvr-utils.js'; export type OdataBinds = ODataBinds; diff --git a/src/server-glue/global-ext.d.ts b/src/server-glue/global-ext.d.ts index 605910541..05434b7f5 100644 --- a/src/server-glue/global-ext.d.ts +++ b/src/server-glue/global-ext.d.ts @@ -5,7 +5,4 @@ declare namespace NodeJS { export interface Process { browser: boolean; } - export interface Global { - nodeRequire: NodeRequire; - } } diff --git a/src/server-glue/module.ts b/src/server-glue/module.ts index f022c8555..980e54026 100644 --- a/src/server-glue/module.ts +++ b/src/server-glue/module.ts @@ -1,27 +1,27 @@ import type * as Express from 'express'; -import './sbvr-loader'; +import './sbvr-loader.js'; -import * as dbModule from '../database-layer/db'; -import * as configLoader from '../config-loader/config-loader'; -import * as migrator from '../migrator/sync'; -import type * as migratorUtils from '../migrator/utils'; -import * as tasks from '../tasks'; +import * as dbModule from '../database-layer/db.js'; +import * as configLoader from '../config-loader/config-loader.js'; +import * as migrator from '../migrator/sync.js'; +import type * as migratorUtils from '../migrator/utils.js'; +import * as tasks from '../tasks/index.js'; -import * as sbvrUtils from '../sbvr-api/sbvr-utils'; -import { PINEJS_ADVISORY_LOCK } from '../config-loader/env'; +import * as sbvrUtils from '../sbvr-api/sbvr-utils.js'; +import { PINEJS_ADVISORY_LOCK } from '../config-loader/env.js'; -export * as dbModule from '../database-layer/db'; -export { PinejsSessionStore } from '../pinejs-session-store/pinejs-session-store'; -export { mountLoginRouter } from '../passport-pinejs/mount-login-router'; -export * as sbvrUtils from '../sbvr-api/sbvr-utils'; -export * as permissions from '../sbvr-api/permissions'; -export * as errors from '../sbvr-api/errors'; -export * as env from '../config-loader/env'; -export * as types from '../sbvr-api/common-types'; -export * as hooks from '../sbvr-api/hooks'; -export * as tasks from '../tasks'; -export * as webResourceHandler from '../webresource-handler'; +export * as dbModule from '../database-layer/db.js'; +export { PinejsSessionStore } from '../pinejs-session-store/pinejs-session-store.js'; +export { mountLoginRouter } from '../passport-pinejs/mount-login-router.js'; +export * as sbvrUtils from '../sbvr-api/sbvr-utils.js'; +export * as permissions from '../sbvr-api/permissions.js'; +export * as errors from '../sbvr-api/errors.js'; +export * as env from '../config-loader/env.js'; +export * as types from '../sbvr-api/common-types.js'; +export * as hooks from '../sbvr-api/hooks.js'; +export * as tasks from '../tasks/index.js'; +export * as webResourceHandler from '../webresource-handler/index.js'; export type { configLoader as ConfigLoader }; export type { migratorUtils as Migrator }; diff --git a/src/server-glue/sbvr-loader.ts b/src/server-glue/sbvr-loader.ts index 95f0c0d01..bc26953f5 100644 --- a/src/server-glue/sbvr-loader.ts +++ b/src/server-glue/sbvr-loader.ts @@ -1,35 +1,23 @@ -import type * as Fs from 'fs'; - -if (!process.browser) { - if (typeof nodeRequire === 'undefined' || nodeRequire == null) { - // `nodeRequire` is a special variable we use to bypass webpack's resolving of `require` - // statements on build for the cases where we need to always use the nodejs require, eg - // in the config-loader which dynamically loads code at runtime, and for adding custom - // filetype handlers - it works by being replaced with `require` after the webpack build - // finishes. - // In the case of `nodeRequire` being undefined it means we're being run in a nodejs - // environment directly, without a webpack build, and have to manually create it as an - // alias for the nodejs require so that things continue to work. - - // Alias require as nodeRequire for the config-loader hack. - global.nodeRequire = require; - } - // Register a .sbvr loader - // eslint-disable-next-line @typescript-eslint/no-var-requires - const fs: typeof Fs = require('fs'); - nodeRequire.extensions['.sbvr'] = (module: NodeModule, filename: string) => - (module.exports = fs.readFileSync(filename, 'utf8')); +/** + * + * @param filePath The module to load + * @param parentUrl Use import.meta.url + * @returns + */ +export async function loadSBVR(filePath: string, meta: ImportMeta) { + return await ( + await import('fs') + ).promises.readFile(new URL(meta.resolve(filePath)), 'utf8'); } /** * * @param filePath The module to load - * @param parentUrl Use `require` + * @param parentUrl Use `import.meta.url` * @returns The sbvr file contents */ -export function requireSBVR(filePath: string, require: NodeRequire) { - return (require('fs') as typeof import('fs')).readFileSync( - require.resolve(filePath), - 'utf8', - ); +export async function importSBVR(filePath: string, meta: ImportMeta) { + return await ( + await import('fs') + ).promises.readFile(new URL(meta.resolve(filePath)), 'utf8'); } diff --git a/src/server-glue/server.ts b/src/server-glue/server.ts index 5ce1e6089..1b054a09b 100644 --- a/src/server-glue/server.ts +++ b/src/server-glue/server.ts @@ -1,18 +1,9 @@ -import type BodyParser from 'body-parser'; -import type Compression from 'compression'; -import type CookieParser from 'cookie-parser'; -import type ExpressSession from 'express-session'; -import type MethodOverride from 'method-override'; -import type * as Passport from 'passport'; -import type * as Path from 'path'; -import type ServeStatic from 'serve-static'; +import * as Pinejs from './module.js'; +export { sbvrUtils, PinejsSessionStore } from './module.js'; -import * as Pinejs from './module'; -export { sbvrUtils, PinejsSessionStore } from './module'; +export { ExtendedSBVRParser } from '../extended-sbvr-parser/extended-sbvr-parser.js'; -export { ExtendedSBVRParser } from '../extended-sbvr-parser/extended-sbvr-parser'; - -import { mountLoginRouter } from '../passport-pinejs/mount-login-router'; +import { mountLoginRouter } from '../passport-pinejs/mount-login-router.js'; import express from 'express'; @@ -27,20 +18,18 @@ switch (app.get('env')) { } if (!process.browser) { - /* eslint-disable @typescript-eslint/no-var-requires */ - const passport: typeof Passport = require('passport'); - const path: typeof Path = require('path'); - const compression: typeof Compression = require('compression'); - const serveStatic: typeof ServeStatic = require('serve-static'); - const cookieParser: typeof CookieParser = require('cookie-parser'); - const bodyParser: typeof BodyParser = require('body-parser'); - const methodOverride: typeof MethodOverride = require('method-override'); - const expressSession: typeof ExpressSession = require('express-session'); - /* eslint-enable @typescript-eslint/no-var-requires */ + const { default: passport } = await import('passport'); + const { default: path } = await import('path'); + const { default: compression } = await import('compression'); + const { default: serveStatic } = await import('serve-static'); + const { default: cookieParser } = await import('cookie-parser'); + const { default: bodyParser } = await import('body-parser'); + const { default: methodOverride } = await import('method-override'); + const { default: expressSession } = await import('express-session'); app.use(compression()); - const root = process.argv[2] || __dirname; + const root = process.argv[2] || import.meta.dirname; app.use('/', serveStatic(path.join(root, 'static'))); app.use(cookieParser()); diff --git a/src/tasks/common.ts b/src/tasks/common.ts index f3faeb6b3..0ea86867b 100644 --- a/src/tasks/common.ts +++ b/src/tasks/common.ts @@ -3,4 +3,4 @@ import Ajv from 'ajv'; // Root path for the tasks API export const apiRoot = 'tasks'; -export const ajv = new Ajv(); +export const ajv = new Ajv.default(); diff --git a/src/tasks/index.ts b/src/tasks/index.ts index 96499d278..3a7f192fe 100644 --- a/src/tasks/index.ts +++ b/src/tasks/index.ts @@ -1,20 +1,20 @@ import type { Schema } from 'ajv'; import * as cronParser from 'cron-parser'; -import { tasks as tasksEnv } from '../config-loader/env'; -import { addPureHook } from '../sbvr-api/hooks'; -import * as sbvrUtils from '../sbvr-api/sbvr-utils'; -import type { ConfigLoader } from '../server-glue/module'; -import { ajv, apiRoot } from './common'; -import type { TaskHandler } from './worker'; -import { Worker } from './worker'; -import type TasksModel from './tasks'; -import type { Task } from './tasks'; +import { tasks as tasksEnv } from '../config-loader/env.js'; +import { addPureHook } from '../sbvr-api/hooks.js'; +import * as sbvrUtils from '../sbvr-api/sbvr-utils.js'; +import type { ConfigLoader } from '../server-glue/module.js'; +import { ajv, apiRoot } from './common.js'; +import type { TaskHandler } from './worker.js'; +import { Worker } from './worker.js'; +import type TasksModel from './tasks.js'; +import type { Task } from './tasks.js'; import type { FromSchema } from 'json-schema-to-ts'; -import { requireSBVR } from '../server-glue/sbvr-loader'; +import { importSBVR } from '../server-glue/sbvr-loader.js'; -export type * from './tasks'; +export type * from './tasks.js'; -const modelText = requireSBVR('./tasks.sbvr', require); +const modelText = await importSBVR('./tasks.sbvr', import.meta); // Create index for polling tasks table const initSql = ` @@ -25,7 +25,7 @@ CREATE INDEX IF NOT EXISTS idx_task_poll ON task USING btree ( ) WHERE status = 'queued'; `; -declare module '../sbvr-api/sbvr-utils' { +declare module '../sbvr-api/sbvr-utils.js' { export interface API { [apiRoot]: PinejsClient; } diff --git a/src/tasks/worker.ts b/src/tasks/worker.ts index 0f89ed00a..1d0ee05ac 100644 --- a/src/tasks/worker.ts +++ b/src/tasks/worker.ts @@ -1,14 +1,14 @@ import type { ValidateFunction } from 'ajv'; import { setTimeout } from 'node:timers/promises'; import type { AnyObject } from 'pinejs-client-core'; -import { tasks as tasksEnv } from '../config-loader/env'; -import type * as Db from '../database-layer/db'; -import * as permissions from '../sbvr-api/permissions'; -import { PinejsClient } from '../sbvr-api/sbvr-utils'; -import { sbvrUtils } from '../server-glue/module'; -import { ajv } from './common'; -import type { Task } from './tasks'; -import type TasksModel from './tasks'; +import { tasks as tasksEnv } from '../config-loader/env.js'; +import type * as Db from '../database-layer/db.js'; +import * as permissions from '../sbvr-api/permissions.js'; +import { PinejsClient } from '../sbvr-api/sbvr-utils.js'; +import { sbvrUtils } from '../server-glue/module.js'; +import { ajv } from './common.js'; +import type { Task } from './tasks.js'; +import type TasksModel from './tasks.js'; interface TaskArgs { api: PinejsClient; diff --git a/src/webresource-handler/handlers/NoopHandler.ts b/src/webresource-handler/handlers/NoopHandler.ts index 21f286fda..cb5fc6733 100644 --- a/src/webresource-handler/handlers/NoopHandler.ts +++ b/src/webresource-handler/handlers/NoopHandler.ts @@ -1,5 +1,9 @@ import type { WebResourceType as WebResource } from '@balena/sbvr-types'; -import type { IncomingFile, UploadResponse, WebResourceHandler } from '..'; +import type { + IncomingFile, + UploadResponse, + WebResourceHandler, +} from '../index.js'; export class NoopHandler implements WebResourceHandler { public async handleFile(resource: IncomingFile): Promise { diff --git a/src/webresource-handler/handlers/S3Handler.ts b/src/webresource-handler/handlers/S3Handler.ts index 222e4423a..d42b44a27 100644 --- a/src/webresource-handler/handlers/S3Handler.ts +++ b/src/webresource-handler/handlers/S3Handler.ts @@ -5,7 +5,7 @@ import { type UploadResponse, WebResourceError, type WebResourceHandler, -} from '..'; +} from '../index.js'; import { S3Client, type S3ClientConfig, diff --git a/src/webresource-handler/handlers/index.ts b/src/webresource-handler/handlers/index.ts index 39158864a..aadb43ddf 100644 --- a/src/webresource-handler/handlers/index.ts +++ b/src/webresource-handler/handlers/index.ts @@ -1,2 +1,2 @@ -export * from './NoopHandler'; -export * from './S3Handler'; +export * from './NoopHandler.js'; +export * from './S3Handler.js'; diff --git a/src/webresource-handler/index.ts b/src/webresource-handler/index.ts index cf7968cfb..f76dca0ec 100644 --- a/src/webresource-handler/index.ts +++ b/src/webresource-handler/index.ts @@ -1,21 +1,21 @@ import type * as Express from 'express'; import busboy from 'busboy'; import type * as stream from 'node:stream'; -import * as uriParser from '../sbvr-api/uri-parser'; -import * as sbvrUtils from '../sbvr-api/sbvr-utils'; -import type { HookArgs } from '../sbvr-api/hooks'; -import { getApiRoot, getModel } from '../sbvr-api/sbvr-utils'; -import { checkPermissions } from '../sbvr-api/permissions'; -import { NoopHandler } from './handlers/NoopHandler'; +import * as uriParser from '../sbvr-api/uri-parser.js'; +import * as sbvrUtils from '../sbvr-api/sbvr-utils.js'; +import type { HookArgs } from '../sbvr-api/hooks.js'; +import { getApiRoot, getModel } from '../sbvr-api/sbvr-utils.js'; +import { checkPermissions } from '../sbvr-api/permissions.js'; +import { NoopHandler } from './handlers/NoopHandler.js'; import { odataNameToSqlName, sqlNameToODataName, } from '@balena/odata-to-abstract-sql'; -import { errors, permissions } from '../server-glue/module'; +import { errors, permissions } from '../server-glue/module.js'; import type { WebResourceType as WebResource } from '@balena/sbvr-types'; import { TypedError } from 'typed-error'; -export * from './handlers'; +export * from './handlers/index.js'; export interface IncomingFile { fieldname: string; diff --git a/test/00-basic.test.ts b/test/00-basic.test.ts index 09b6ebe6e..fd50cb9f2 100644 --- a/test/00-basic.test.ts +++ b/test/00-basic.test.ts @@ -1,7 +1,7 @@ import supertest from 'supertest'; import { expect } from 'chai'; -const configPath = __dirname + '/fixtures/00-basic/config.js'; -import { testInit, testDeInit, testLocalServer } from './lib/test-init'; +const configPath = import.meta.dirname + '/fixtures/00-basic/config.js'; +import { testInit, testDeInit, testLocalServer } from './lib/test-init.js'; describe('00 basic tests', function () { let pineServer: Awaited>; diff --git a/test/01-constrain.test.ts b/test/01-constrain.test.ts index 9e432fdeb..f37170ff9 100644 --- a/test/01-constrain.test.ts +++ b/test/01-constrain.test.ts @@ -1,7 +1,7 @@ import supertest from 'supertest'; import { expect } from 'chai'; -const configPath = __dirname + '/fixtures/01-constrain/config.js'; -import { testInit, testDeInit, testLocalServer } from './lib/test-init'; +const configPath = import.meta.dirname + '/fixtures/01-constrain/config.js'; +import { testInit, testDeInit, testLocalServer } from './lib/test-init.js'; describe('01 basic constrain tests', function () { let pineServer: Awaited>; diff --git a/test/02-sync-migrator.test.ts b/test/02-sync-migrator.test.ts index ecd09e7e2..43f59b0b9 100644 --- a/test/02-sync-migrator.test.ts +++ b/test/02-sync-migrator.test.ts @@ -1,9 +1,9 @@ import supertest from 'supertest'; import type { ChildProcess } from 'child_process'; import { expect } from 'chai'; -import { testInit, testDeInit, testLocalServer } from './lib/test-init'; +import { testInit, testDeInit, testLocalServer } from './lib/test-init.js'; -const fixturesBasePath = __dirname + '/fixtures/02-sync-migrator/'; +const fixturesBasePath = import.meta.dirname + '/fixtures/02-sync-migrator/'; type TestDevice = { created_at: Date; diff --git a/test/03-async-migrator.test.ts b/test/03-async-migrator.test.ts index 031e53499..c7c12c57a 100644 --- a/test/03-async-migrator.test.ts +++ b/test/03-async-migrator.test.ts @@ -2,11 +2,11 @@ import supertest from 'supertest'; import type { ChildProcess } from 'child_process'; import { assert, expect } from 'chai'; import { setTimeout } from 'timers'; -import { dbModule } from '../src/server-glue/module'; -import { testInit, testDeInit, testLocalServer } from './lib/test-init'; -import type { MigrationStatus } from '../src/migrator/utils'; +import { dbModule } from '../src/server-glue/module.js'; +import { testInit, testDeInit, testLocalServer } from './lib/test-init.js'; +import type { MigrationStatus } from '../src/migrator/utils.js'; -const fixturesBasePath = __dirname + '/fixtures/03-async-migrator/'; +const fixturesBasePath = import.meta.dirname + '/fixtures/03-async-migrator/'; type TestDevice = { created_at: Date; diff --git a/test/04-translations.test.ts b/test/04-translations.test.ts index 4bdfc3fdd..f59e664fd 100644 --- a/test/04-translations.test.ts +++ b/test/04-translations.test.ts @@ -1,12 +1,13 @@ -const configPath = __dirname + '/fixtures/04-translations/config.js'; -const hooksPath = __dirname + '/fixtures/04-translations/translations/hooks.js'; -import { testInit, testDeInit, testLocalServer } from './lib/test-init'; +const configPath = import.meta.dirname + '/fixtures/04-translations/config.js'; +const hooksPath = + import.meta.dirname + '/fixtures/04-translations/translations/hooks.js'; +import { testInit, testDeInit, testLocalServer } from './lib/test-init.js'; import { faker } from '@faker-js/faker'; import { expect } from 'chai'; import type { AnyObject } from 'pinejs-client-core'; import { PineTest } from 'pinejs-client-supertest'; -import { assertExists } from './lib/common'; +import { assertExists } from './lib/common.js'; describe('04 native translation tests', function () { let pineServer: Awaited>; diff --git a/test/05-request-cancellation.test.ts b/test/05-request-cancellation.test.ts index 1de34fe8e..03f7556c1 100644 --- a/test/05-request-cancellation.test.ts +++ b/test/05-request-cancellation.test.ts @@ -1,8 +1,11 @@ import { expect } from 'chai'; -const configPath = __dirname + '/fixtures/05-request-cancellation/config.js'; -const hooksPath = __dirname + '/fixtures/05-request-cancellation/hooks.js'; -const routesPath = __dirname + '/fixtures/05-request-cancellation/routes.js'; -import { testInit, testDeInit, testLocalServer } from './lib/test-init'; +const configPath = + import.meta.dirname + '/fixtures/05-request-cancellation/config.js'; +const hooksPath = + import.meta.dirname + '/fixtures/05-request-cancellation/hooks.js'; +const routesPath = + import.meta.dirname + '/fixtures/05-request-cancellation/routes.js'; +import { testInit, testDeInit, testLocalServer } from './lib/test-init.js'; import { PineTest } from 'pinejs-client-supertest'; import request from 'request'; import { setTimeout } from 'timers/promises'; diff --git a/test/06-webresource.test.ts b/test/06-webresource.test.ts index 3be3cb5f5..a4a9ae9cf 100644 --- a/test/06-webresource.test.ts +++ b/test/06-webresource.test.ts @@ -1,8 +1,10 @@ import supertest from 'supertest'; import { expect } from 'chai'; -const configPath = __dirname + '/fixtures/06-webresource/config.js'; -const hooksPath = __dirname + '/fixtures/06-webresource/translations/hooks.js'; -const testResourcePath = __dirname + '/fixtures/06-webresource/resources/'; +const configPath = import.meta.dirname + '/fixtures/06-webresource/config.js'; +const hooksPath = + import.meta.dirname + '/fixtures/06-webresource/translations/hooks.js'; +const testResourcePath = + import.meta.dirname + '/fixtures/06-webresource/resources/'; import * as fsBase from 'fs'; import { createReadStream, createWriteStream } from 'fs'; @@ -11,14 +13,14 @@ import * as util from 'util'; import { randomUUID } from 'crypto'; import { tmpdir } from 'os'; import * as path from 'path'; -import { testInit, testDeInit, testLocalServer } from './lib/test-init'; +import { testInit, testDeInit, testLocalServer } from './lib/test-init.js'; import { ListObjectsV2Command, S3Client, DeleteObjectCommand, } from '@aws-sdk/client-s3'; import { intVar, requiredVar } from '@balena/env-parsing'; -import { assertExists } from './lib/common'; +import { assertExists } from './lib/common.js'; const pipeline = util.promisify(pipelineRaw); const fs = fsBase.promises; diff --git a/test/07-permissions.test.ts b/test/07-permissions.test.ts index 76dadfc48..72ef4f3e3 100644 --- a/test/07-permissions.test.ts +++ b/test/07-permissions.test.ts @@ -1,9 +1,9 @@ import supertest from 'supertest'; import { expect } from 'chai'; -const configPath = __dirname + '/fixtures/07-permissions/config.js'; -import { testInit, testDeInit, testLocalServer } from './lib/test-init'; -import { sbvrUtils, permissions } from '../src/server-glue/module'; -import type UserModel from '../src/sbvr-api/user'; +const configPath = import.meta.dirname + '/fixtures/07-permissions/config.js'; +import { testInit, testDeInit, testLocalServer } from './lib/test-init.js'; +import { sbvrUtils, permissions } from '../src/server-glue/module.js'; +import type UserModel from '../src/sbvr-api/user.js'; describe('07 permissions tests', function () { let pineServer: Awaited>; diff --git a/test/08-tasks.test.ts b/test/08-tasks.test.ts index e457645d6..0b1be247a 100644 --- a/test/08-tasks.test.ts +++ b/test/08-tasks.test.ts @@ -3,14 +3,14 @@ import { strict } from 'node:assert'; import { randomUUID } from 'node:crypto'; import { setTimeout } from 'node:timers/promises'; import { PineTest } from 'pinejs-client-supertest'; -import { testInit, testDeInit, testLocalServer } from './lib/test-init'; -import { tasks as tasksEnv } from '../src/config-loader/env'; -import type Model from '../src/tasks/tasks'; +import { testInit, testDeInit, testLocalServer } from './lib/test-init.js'; +import { tasks as tasksEnv } from '../src/config-loader/env.js'; +import type Model from '../src/tasks/tasks.js'; import * as cronParser from 'cron-parser'; -import { PINE_TEST_SIGNALS } from './lib/common'; +import { PINE_TEST_SIGNALS } from './lib/common.js'; const actorId = 1; -const fixturesBasePath = __dirname + '/fixtures/08-tasks/'; +const fixturesBasePath = import.meta.dirname + '/fixtures/08-tasks/'; // Wait for a condition to be true, or throw an error if it doesn't happen in time. export async function waitFor(checkFn: () => Promise): Promise { diff --git a/test/fixtures/00-basic/config.ts b/test/fixtures/00-basic/config.ts index 882e3d1d4..97765e14d 100644 --- a/test/fixtures/00-basic/config.ts +++ b/test/fixtures/00-basic/config.ts @@ -1,8 +1,8 @@ -import type { ConfigLoader } from '../../../src/server-glue/module'; +import type { ConfigLoader } from '../../../src/server-glue/module.js'; const apiRoot = 'example'; const modelName = 'example'; -const modelFile = __dirname + '/example.sbvr'; +const modelFile = import.meta.dirname + '/example.sbvr'; export default { models: [ diff --git a/test/fixtures/01-constrain/config.ts b/test/fixtures/01-constrain/config.ts index aeb936c3c..1ffbe8fbb 100644 --- a/test/fixtures/01-constrain/config.ts +++ b/test/fixtures/01-constrain/config.ts @@ -1,8 +1,8 @@ -import type { ConfigLoader } from '../../../src/server-glue/module'; +import type { ConfigLoader } from '../../../src/server-glue/module.js'; const apiRoot = 'university'; const modelName = 'university'; -const modelFile = __dirname + '/university.sbvr'; +const modelFile = import.meta.dirname + '/university.sbvr'; export default { models: [ diff --git a/test/fixtures/02-sync-migrator/00-execute-model.ts b/test/fixtures/02-sync-migrator/00-execute-model.ts index 383831c36..72b511ea2 100644 --- a/test/fixtures/02-sync-migrator/00-execute-model.ts +++ b/test/fixtures/02-sync-migrator/00-execute-model.ts @@ -1,9 +1,9 @@ -import type { ConfigLoader } from '../../../src/server-glue/module'; +import type { ConfigLoader } from '../../../src/server-glue/module.js'; const apiRoot = 'example'; const modelName = 'example'; -const modelFile = __dirname + '/example.sbvr'; -const initSqlPath = __dirname + '/init-data.sql'; +const modelFile = import.meta.dirname + '/example.sbvr'; +const initSqlPath = import.meta.dirname + '/init-data.sql'; export default { models: [ diff --git a/test/fixtures/02-sync-migrator/01-migrations.ts b/test/fixtures/02-sync-migrator/01-migrations.ts index 0b337c8ca..b02695ad6 100644 --- a/test/fixtures/02-sync-migrator/01-migrations.ts +++ b/test/fixtures/02-sync-migrator/01-migrations.ts @@ -1,9 +1,9 @@ -import type { ConfigLoader } from '../../../src/server-glue/module'; +import type { ConfigLoader } from '../../../src/server-glue/module.js'; const apiRoot = 'example'; const modelName = 'example'; -const modelFile = __dirname + '/example.sbvr'; -const migrationsPath = __dirname + '/01-migrations'; +const modelFile = import.meta.dirname + '/example.sbvr'; +const migrationsPath = import.meta.dirname + '/01-migrations'; export default { models: [ diff --git a/test/fixtures/02-sync-migrator/01-migrations/0002-test-migrations.sync.ts b/test/fixtures/02-sync-migrator/01-migrations/0002-test-migrations.sync.ts index 8a3a5b592..a72668f53 100644 --- a/test/fixtures/02-sync-migrator/01-migrations/0002-test-migrations.sync.ts +++ b/test/fixtures/02-sync-migrator/01-migrations/0002-test-migrations.sync.ts @@ -1,4 +1,4 @@ -import type { Migrator } from '../../../../src/server-glue/module'; +import type { Migrator } from '../../../../src/server-glue/module.js'; const migration: Migrator.MigrationFn = async (tx) => { const staticSql = `\ diff --git a/test/fixtures/02-sync-migrator/02-migrations-error.ts b/test/fixtures/02-sync-migrator/02-migrations-error.ts index 87cbc96cf..32fbcae73 100644 --- a/test/fixtures/02-sync-migrator/02-migrations-error.ts +++ b/test/fixtures/02-sync-migrator/02-migrations-error.ts @@ -1,9 +1,9 @@ -import type { ConfigLoader } from '../../../src/server-glue/module'; +import type { ConfigLoader } from '../../../src/server-glue/module.js'; const apiRoot = 'example'; const modelName = 'example'; -const modelFile = __dirname + '/example.sbvr'; -const migrationsPath = __dirname + '/02-migrations-error'; +const modelFile = import.meta.dirname + '/example.sbvr'; +const migrationsPath = import.meta.dirname + '/02-migrations-error'; export default { models: [ diff --git a/test/fixtures/02-sync-migrator/02-migrations-error/0002-test-migrations.sync.ts b/test/fixtures/02-sync-migrator/02-migrations-error/0002-test-migrations.sync.ts index 8a3a5b592..a72668f53 100644 --- a/test/fixtures/02-sync-migrator/02-migrations-error/0002-test-migrations.sync.ts +++ b/test/fixtures/02-sync-migrator/02-migrations-error/0002-test-migrations.sync.ts @@ -1,4 +1,4 @@ -import type { Migrator } from '../../../../src/server-glue/module'; +import type { Migrator } from '../../../../src/server-glue/module.js'; const migration: Migrator.MigrationFn = async (tx) => { const staticSql = `\ diff --git a/test/fixtures/02-sync-migrator/03-exclusive-category.ts b/test/fixtures/02-sync-migrator/03-exclusive-category.ts index caab3fe7b..2f2e2f8b2 100644 --- a/test/fixtures/02-sync-migrator/03-exclusive-category.ts +++ b/test/fixtures/02-sync-migrator/03-exclusive-category.ts @@ -1,9 +1,9 @@ -import type { ConfigLoader } from '../../../src/server-glue/module'; +import type { ConfigLoader } from '../../../src/server-glue/module.js'; const apiRoot = 'example'; const modelName = 'example'; -const modelFile = __dirname + '/example.sbvr'; -const migrationsPath = __dirname + '/01-migrations'; +const modelFile = import.meta.dirname + '/example.sbvr'; +const migrationsPath = import.meta.dirname + '/01-migrations'; export default { models: [ diff --git a/test/fixtures/02-sync-migrator/04-new-model-with-init.ts b/test/fixtures/02-sync-migrator/04-new-model-with-init.ts index d2bad8518..0f5d57f32 100644 --- a/test/fixtures/02-sync-migrator/04-new-model-with-init.ts +++ b/test/fixtures/02-sync-migrator/04-new-model-with-init.ts @@ -1,8 +1,8 @@ -import type { ConfigLoader } from '../../../src/server-glue/module'; +import type { ConfigLoader } from '../../../src/server-glue/module.js'; const apiRoot = 'example'; const modelName = 'example'; -const modelFile = __dirname + '/example.sbvr'; +const modelFile = import.meta.dirname + '/example.sbvr'; export default { models: [ @@ -13,12 +13,12 @@ export default { migrations: { '0001': ` INSERT INTO "device" ("id", "name", "note", "type") - VALUES (2, 'no run', 'shouldNotRun', 'empty') + VALUES (2, 'no run', 'shouldNotRun', 'empty') `, }, initSql: ` INSERT INTO "device" ("id", "name", "note", "type") - VALUES (1, 'initName', 'shouldBeInit', 'init') + VALUES (1, 'initName', 'shouldBeInit', 'init') `, }, ], diff --git a/test/fixtures/03-async-migrator/00-execute-model.ts b/test/fixtures/03-async-migrator/00-execute-model.ts index 383831c36..72b511ea2 100644 --- a/test/fixtures/03-async-migrator/00-execute-model.ts +++ b/test/fixtures/03-async-migrator/00-execute-model.ts @@ -1,9 +1,9 @@ -import type { ConfigLoader } from '../../../src/server-glue/module'; +import type { ConfigLoader } from '../../../src/server-glue/module.js'; const apiRoot = 'example'; const modelName = 'example'; -const modelFile = __dirname + '/example.sbvr'; -const initSqlPath = __dirname + '/init-data.sql'; +const modelFile = import.meta.dirname + '/example.sbvr'; +const initSqlPath = import.meta.dirname + '/init-data.sql'; export default { models: [ diff --git a/test/fixtures/03-async-migrator/01-migrations.ts b/test/fixtures/03-async-migrator/01-migrations.ts index 1c0f3794c..fe0421a0c 100644 --- a/test/fixtures/03-async-migrator/01-migrations.ts +++ b/test/fixtures/03-async-migrator/01-migrations.ts @@ -1,9 +1,9 @@ -import type { ConfigLoader } from '../../../src/server-glue/module'; +import type { ConfigLoader } from '../../../src/server-glue/module.js'; const apiRoot = 'example'; const modelName = 'example'; -const modelFile = __dirname + '/example.sbvr'; -const migrationsPath = __dirname + '/01-migrations/migrations'; +const modelFile = import.meta.dirname + '/example.sbvr'; +const migrationsPath = import.meta.dirname + '/01-migrations/migrations'; export default { models: [ diff --git a/test/fixtures/03-async-migrator/01-migrations/migrations/0002-test-migrations.async.ts b/test/fixtures/03-async-migrator/01-migrations/migrations/0002-test-migrations.async.ts index 1f0b2e990..0bdb17c24 100644 --- a/test/fixtures/03-async-migrator/01-migrations/migrations/0002-test-migrations.async.ts +++ b/test/fixtures/03-async-migrator/01-migrations/migrations/0002-test-migrations.async.ts @@ -1,4 +1,4 @@ -import type { AsyncMigration } from '../../../../../src/migrator/utils'; +import type { AsyncMigration } from '../../../../../src/migrator/utils.js'; const migration: AsyncMigration = { asyncFn: async (tx, options) => { diff --git a/test/fixtures/03-async-migrator/01-migrations/migrations/0003-finalized-test-migration.async.ts b/test/fixtures/03-async-migrator/01-migrations/migrations/0003-finalized-test-migration.async.ts index 1c21ab8f4..5bb953c8b 100644 --- a/test/fixtures/03-async-migrator/01-migrations/migrations/0003-finalized-test-migration.async.ts +++ b/test/fixtures/03-async-migrator/01-migrations/migrations/0003-finalized-test-migration.async.ts @@ -1,4 +1,4 @@ -import type { AsyncMigration } from '../../../../../src/migrator/utils'; +import type { AsyncMigration } from '../../../../../src/migrator/utils.js'; const migration: AsyncMigration = { asyncFn: async (tx) => { diff --git a/test/fixtures/03-async-migrator/02-parallel-migrations.ts b/test/fixtures/03-async-migrator/02-parallel-migrations.ts index 546b4013c..9b4fede0a 100644 --- a/test/fixtures/03-async-migrator/02-parallel-migrations.ts +++ b/test/fixtures/03-async-migrator/02-parallel-migrations.ts @@ -1,9 +1,10 @@ -import type { ConfigLoader } from '../../../src/server-glue/module'; +import type { ConfigLoader } from '../../../src/server-glue/module.js'; const apiRoot = 'example'; const modelName = 'example'; -const modelFile = __dirname + '/example.sbvr'; -const migrationsPath = __dirname + '/02-parallel-migrations/migrations'; +const modelFile = import.meta.dirname + '/example.sbvr'; +const migrationsPath = + import.meta.dirname + '/02-parallel-migrations/migrations'; export default { models: [ diff --git a/test/fixtures/03-async-migrator/02-parallel-migrations/migrations/0001-migrate-testa.async.ts b/test/fixtures/03-async-migrator/02-parallel-migrations/migrations/0001-migrate-testa.async.ts index 791f7231d..fb13b9c0a 100644 --- a/test/fixtures/03-async-migrator/02-parallel-migrations/migrations/0001-migrate-testa.async.ts +++ b/test/fixtures/03-async-migrator/02-parallel-migrations/migrations/0001-migrate-testa.async.ts @@ -1,4 +1,4 @@ -import type { AsyncMigration } from '../../../../../src/migrator/utils'; +import type { AsyncMigration } from '../../../../../src/migrator/utils.js'; const migration: AsyncMigration = { asyncFn: async (tx, options) => { diff --git a/test/fixtures/03-async-migrator/02-parallel-migrations/migrations/0002-migrate-testb.async.ts b/test/fixtures/03-async-migrator/02-parallel-migrations/migrations/0002-migrate-testb.async.ts index a535539f6..b3f93b9be 100644 --- a/test/fixtures/03-async-migrator/02-parallel-migrations/migrations/0002-migrate-testb.async.ts +++ b/test/fixtures/03-async-migrator/02-parallel-migrations/migrations/0002-migrate-testb.async.ts @@ -1,4 +1,4 @@ -import type { AsyncMigration } from '../../../../../src/migrator/utils'; +import type { AsyncMigration } from '../../../../../src/migrator/utils.js'; const migration: AsyncMigration = { asyncFn: async (tx, options) => { diff --git a/test/fixtures/03-async-migrator/03-finalize-async.ts b/test/fixtures/03-async-migrator/03-finalize-async.ts index 9d0d7106a..67f2e7ff7 100644 --- a/test/fixtures/03-async-migrator/03-finalize-async.ts +++ b/test/fixtures/03-async-migrator/03-finalize-async.ts @@ -1,9 +1,9 @@ -import type { ConfigLoader } from '../../../src/server-glue/module'; +import type { ConfigLoader } from '../../../src/server-glue/module.js'; const apiRoot = 'example'; const modelName = 'example'; -const modelFile = __dirname + '/example.sbvr'; -const migrationsPath = __dirname + '/03-finalize-async/migrations'; +const modelFile = import.meta.dirname + '/example.sbvr'; +const migrationsPath = import.meta.dirname + '/03-finalize-async/migrations'; export default { models: [ diff --git a/test/fixtures/03-async-migrator/03-finalize-async/migrations/m0001-data-copy.async.ts b/test/fixtures/03-async-migrator/03-finalize-async/migrations/m0001-data-copy.async.ts index 0908a5ab7..81e338207 100644 --- a/test/fixtures/03-async-migrator/03-finalize-async/migrations/m0001-data-copy.async.ts +++ b/test/fixtures/03-async-migrator/03-finalize-async/migrations/m0001-data-copy.async.ts @@ -1,4 +1,4 @@ -import type { AsyncMigration } from '../../../../../src/migrator/utils'; +import type { AsyncMigration } from '../../../../../src/migrator/utils.js'; const migration: AsyncMigration = { asyncFn: async (tx, options) => { diff --git a/test/fixtures/03-async-migrator/03-finalize-async/migrations/m0002-data-copy.async.ts b/test/fixtures/03-async-migrator/03-finalize-async/migrations/m0002-data-copy.async.ts index 504747aa4..09f850bb9 100644 --- a/test/fixtures/03-async-migrator/03-finalize-async/migrations/m0002-data-copy.async.ts +++ b/test/fixtures/03-async-migrator/03-finalize-async/migrations/m0002-data-copy.async.ts @@ -1,4 +1,4 @@ -import type { AsyncMigration } from '../../../../../src/migrator/utils'; +import type { AsyncMigration } from '../../../../../src/migrator/utils.js'; const migration: AsyncMigration = { asyncSql: `\ diff --git a/test/fixtures/03-async-migrator/04-migration-errors.ts b/test/fixtures/03-async-migrator/04-migration-errors.ts index a6e28e9eb..57a7a2f52 100644 --- a/test/fixtures/03-async-migrator/04-migration-errors.ts +++ b/test/fixtures/03-async-migrator/04-migration-errors.ts @@ -1,9 +1,9 @@ -import type { ConfigLoader } from '../../../src/server-glue/module'; +import type { ConfigLoader } from '../../../src/server-glue/module.js'; const apiRoot = 'example'; const modelName = 'example'; -const modelFile = __dirname + '/example.sbvr'; -const migrationsPath = __dirname + '/04-migration-errors/migrations'; +const modelFile = import.meta.dirname + '/example.sbvr'; +const migrationsPath = import.meta.dirname + '/04-migration-errors/migrations'; export default { models: [ diff --git a/test/fixtures/03-async-migrator/04-migration-errors/migrations/0001-successful-migration.async.ts b/test/fixtures/03-async-migrator/04-migration-errors/migrations/0001-successful-migration.async.ts index 791f7231d..fb13b9c0a 100644 --- a/test/fixtures/03-async-migrator/04-migration-errors/migrations/0001-successful-migration.async.ts +++ b/test/fixtures/03-async-migrator/04-migration-errors/migrations/0001-successful-migration.async.ts @@ -1,4 +1,4 @@ -import type { AsyncMigration } from '../../../../../src/migrator/utils'; +import type { AsyncMigration } from '../../../../../src/migrator/utils.js'; const migration: AsyncMigration = { asyncFn: async (tx, options) => { diff --git a/test/fixtures/03-async-migrator/04-migration-errors/migrations/0002-table-not-exists.async.ts b/test/fixtures/03-async-migrator/04-migration-errors/migrations/0002-table-not-exists.async.ts index 599733e60..ef7661c16 100644 --- a/test/fixtures/03-async-migrator/04-migration-errors/migrations/0002-table-not-exists.async.ts +++ b/test/fixtures/03-async-migrator/04-migration-errors/migrations/0002-table-not-exists.async.ts @@ -1,4 +1,4 @@ -import type { AsyncMigration } from '../../../../../src/migrator/utils'; +import type { AsyncMigration } from '../../../../../src/migrator/utils.js'; const migration: AsyncMigration = { asyncFn: async (tx, options) => { diff --git a/test/fixtures/03-async-migrator/04-migration-errors/migrations/0003-error-unique-key.async.ts b/test/fixtures/03-async-migrator/04-migration-errors/migrations/0003-error-unique-key.async.ts index fa26473ba..6c2f6d781 100644 --- a/test/fixtures/03-async-migrator/04-migration-errors/migrations/0003-error-unique-key.async.ts +++ b/test/fixtures/03-async-migrator/04-migration-errors/migrations/0003-error-unique-key.async.ts @@ -1,4 +1,4 @@ -import type { AsyncMigration } from '../../../../../src/migrator/utils'; +import type { AsyncMigration } from '../../../../../src/migrator/utils.js'; const migration: AsyncMigration = { asyncFn: async (tx) => { diff --git a/test/fixtures/03-async-migrator/05-massive-data.ts b/test/fixtures/03-async-migrator/05-massive-data.ts index 75640e43b..cafdf4718 100644 --- a/test/fixtures/03-async-migrator/05-massive-data.ts +++ b/test/fixtures/03-async-migrator/05-massive-data.ts @@ -1,9 +1,9 @@ -import type { ConfigLoader } from '../../../src/server-glue/module'; +import type { ConfigLoader } from '../../../src/server-glue/module.js'; const apiRoot = 'example'; const modelName = 'example'; -const modelFile = __dirname + '/example.sbvr'; -const migrationsPath = __dirname + '/05-massive-data/migrations'; +const modelFile = import.meta.dirname + '/example.sbvr'; +const migrationsPath = import.meta.dirname + '/05-massive-data/migrations'; export default { models: [ diff --git a/test/fixtures/03-async-migrator/05-massive-data/00-execute-model.ts b/test/fixtures/03-async-migrator/05-massive-data/00-execute-model.ts index d1492e18c..e1ac5d623 100644 --- a/test/fixtures/03-async-migrator/05-massive-data/00-execute-model.ts +++ b/test/fixtures/03-async-migrator/05-massive-data/00-execute-model.ts @@ -1,10 +1,10 @@ import { resolve } from 'path'; -import type { ConfigLoader } from '../../../../src/server-glue/module'; +import type { ConfigLoader } from '../../../../src/server-glue/module.js'; const apiRoot = 'example'; const modelName = 'example'; -const modelFile = resolve(__dirname, '../example.sbvr'); -const initSqlPath = __dirname + '/init-data.sql'; +const modelFile = resolve(import.meta.dirname, '../example.sbvr'); +const initSqlPath = import.meta.dirname + '/init-data.sql'; export default { models: [ diff --git a/test/fixtures/03-async-migrator/05-massive-data/migrations/0001-massive-migration.async.ts b/test/fixtures/03-async-migrator/05-massive-data/migrations/0001-massive-migration.async.ts index e4dd0797b..0dc569758 100644 --- a/test/fixtures/03-async-migrator/05-massive-data/migrations/0001-massive-migration.async.ts +++ b/test/fixtures/03-async-migrator/05-massive-data/migrations/0001-massive-migration.async.ts @@ -1,4 +1,4 @@ -import type { AsyncMigration } from '../../../../../src/migrator/utils'; +import type { AsyncMigration } from '../../../../../src/migrator/utils.js'; const migration: AsyncMigration = { asyncFn: async (tx, options) => { diff --git a/test/fixtures/03-async-migrator/06-setup-errors.ts b/test/fixtures/03-async-migrator/06-setup-errors.ts index a898b3769..d89f5886e 100644 --- a/test/fixtures/03-async-migrator/06-setup-errors.ts +++ b/test/fixtures/03-async-migrator/06-setup-errors.ts @@ -1,9 +1,9 @@ -import type { ConfigLoader } from '../../../src/server-glue/module'; +import type { ConfigLoader } from '../../../src/server-glue/module.js'; const apiRoot = 'example'; const modelName = 'example'; -const modelFile = __dirname + '/example.sbvr'; -const migrationsPath = __dirname + '/06-setup-errors'; +const modelFile = import.meta.dirname + '/example.sbvr'; +const migrationsPath = import.meta.dirname + '/06-setup-errors'; export default { models: [ diff --git a/test/fixtures/03-async-migrator/06-setup-errors/0001-error-async-sync-pair.async.ts b/test/fixtures/03-async-migrator/06-setup-errors/0001-error-async-sync-pair.async.ts index eb9661a8c..51e504088 100644 --- a/test/fixtures/03-async-migrator/06-setup-errors/0001-error-async-sync-pair.async.ts +++ b/test/fixtures/03-async-migrator/06-setup-errors/0001-error-async-sync-pair.async.ts @@ -1,4 +1,4 @@ -import type { AsyncMigration } from '../../../../src/migrator/utils'; +import type { AsyncMigration } from '../../../../src/migrator/utils.js'; const migration: AsyncMigration = { asyncFn: async (tx) => { diff --git a/test/fixtures/03-async-migrator/07-setup-error-mixed-migrations.ts b/test/fixtures/03-async-migrator/07-setup-error-mixed-migrations.ts index d8de91ff8..0308ce73d 100644 --- a/test/fixtures/03-async-migrator/07-setup-error-mixed-migrations.ts +++ b/test/fixtures/03-async-migrator/07-setup-error-mixed-migrations.ts @@ -1,6 +1,6 @@ const apiRoot = 'example'; const modelName = 'example'; -const modelFile = __dirname + '/example.sbvr'; +const modelFile = import.meta.dirname + '/example.sbvr'; export default { models: [ diff --git a/test/fixtures/03-async-migrator/08-01-async-lock-taker.ts b/test/fixtures/03-async-migrator/08-01-async-lock-taker.ts index d59533d1d..13b13ddc1 100644 --- a/test/fixtures/03-async-migrator/08-01-async-lock-taker.ts +++ b/test/fixtures/03-async-migrator/08-01-async-lock-taker.ts @@ -1,8 +1,8 @@ -import type { ConfigLoader } from '../../../src/server-glue/module'; +import type { ConfigLoader } from '../../../src/server-glue/module.js'; const apiRoot = 'example'; const modelName = 'example'; -const modelFile = __dirname + '/example.sbvr'; +const modelFile = import.meta.dirname + '/example.sbvr'; const asyncSpammer = { asyncFn: async (tx: any) => { diff --git a/test/fixtures/03-async-migrator/08-02-sync-lock-starvation.ts b/test/fixtures/03-async-migrator/08-02-sync-lock-starvation.ts index 1c50d2d82..6d214973b 100644 --- a/test/fixtures/03-async-migrator/08-02-sync-lock-starvation.ts +++ b/test/fixtures/03-async-migrator/08-02-sync-lock-starvation.ts @@ -1,8 +1,8 @@ -import type { ConfigLoader } from '../../../src/server-glue/module'; +import type { ConfigLoader } from '../../../src/server-glue/module.js'; const apiRoot = 'example'; const modelName = 'example'; -const modelFile = __dirname + '/example.sbvr'; +const modelFile = import.meta.dirname + '/example.sbvr'; export default { models: [ @@ -23,7 +23,7 @@ export default { CONCAT('a','b',trim(to_char(i,'0000000'))) as "name", NULL as "note", CONCAT('b','b',trim(to_char(i,'0000000'))) as "type" - FROM generate_series(21, 30) s(i); + FROM generate_series(21, 30) s(i); `); }, }, diff --git a/test/fixtures/04-translations/config.ts b/test/fixtures/04-translations/config.ts index 7dbd0f245..c445b0349 100644 --- a/test/fixtures/04-translations/config.ts +++ b/test/fixtures/04-translations/config.ts @@ -1,18 +1,21 @@ import type { AbstractSqlQuery } from '@balena/abstract-sql-compiler'; -import { getAbstractSqlModelFromFile } from '../../../src/bin/utils'; -import type { ConfigLoader } from '../../../src/server-glue/module'; +import { getAbstractSqlModelFromFile } from '../../../src/bin/utils.js'; +import type { ConfigLoader } from '../../../src/server-glue/module.js'; const apiRoot = 'university'; const modelName = 'university'; -const modelFile = __dirname + '/university.sbvr'; +const modelFile = import.meta.dirname + '/university.sbvr'; -import { v1AbstractSqlModel, v1Translations } from './translations/v1'; -import { v2AbstractSqlModel, v2Translations } from './translations/v2'; -import { v3AbstractSqlModel, v3Translations } from './translations/v3'; -import { v4AbstractSqlModel } from './translations/v4'; -import { v5AbstractSqlModel } from './translations/v5'; +import { v1AbstractSqlModel, v1Translations } from './translations/v1/index.js'; +import { v2AbstractSqlModel, v2Translations } from './translations/v2/index.js'; +import { v3AbstractSqlModel, v3Translations } from './translations/v3/index.js'; +import { v4AbstractSqlModel } from './translations/v4/index.js'; +import { v5AbstractSqlModel } from './translations/v5/index.js'; -export const abstractSql = getAbstractSqlModelFromFile(modelFile, undefined); +export const abstractSql = await getAbstractSqlModelFromFile( + modelFile, + undefined, +); abstractSql.tables['student'].fields.push({ fieldName: 'computed field', diff --git a/test/fixtures/04-translations/translations/hooks.ts b/test/fixtures/04-translations/translations/hooks.ts index 5cdfb6446..3e0b64be4 100644 --- a/test/fixtures/04-translations/translations/hooks.ts +++ b/test/fixtures/04-translations/translations/hooks.ts @@ -1,3 +1,3 @@ -import './v1/hooks'; -import './v2/hooks'; -import './v3/hooks'; +import './v1/hooks.js'; +import './v2/hooks.js'; +import './v3/hooks.js'; diff --git a/test/fixtures/04-translations/translations/v1/hooks.ts b/test/fixtures/04-translations/translations/v1/hooks.ts index 768063886..f8cc1650f 100644 --- a/test/fixtures/04-translations/translations/v1/hooks.ts +++ b/test/fixtures/04-translations/translations/v1/hooks.ts @@ -1,4 +1,4 @@ -import { sbvrUtils } from '../../../../../src/server-glue/module'; +import { sbvrUtils } from '../../../../../src/server-glue/module.js'; const addHook = ( methods: Array[0]>, diff --git a/test/fixtures/04-translations/translations/v1/index.ts b/test/fixtures/04-translations/translations/v1/index.ts index 7a545a90e..28d9d2597 100644 --- a/test/fixtures/04-translations/translations/v1/index.ts +++ b/test/fixtures/04-translations/translations/v1/index.ts @@ -1,11 +1,11 @@ -import type { ConfigLoader } from '../../../../../src/server-glue/module'; -import { getAbstractSqlModelFromFile } from '../../../../../src/bin/utils'; +import type { ConfigLoader } from '../../../../../src/server-glue/module.js'; +import { getAbstractSqlModelFromFile } from '../../../../../src/bin/utils.js'; import type { AbstractSqlQuery } from '@balena/abstract-sql-compiler'; export const toVersion = 'v2'; -export const v1AbstractSqlModel = getAbstractSqlModelFromFile( - __dirname + '/university.sbvr', +export const v1AbstractSqlModel = await getAbstractSqlModelFromFile( + import.meta.dirname + '/university.sbvr', undefined, ); diff --git a/test/fixtures/04-translations/translations/v2/hooks.ts b/test/fixtures/04-translations/translations/v2/hooks.ts index b4392e1b6..ff294afb7 100644 --- a/test/fixtures/04-translations/translations/v2/hooks.ts +++ b/test/fixtures/04-translations/translations/v2/hooks.ts @@ -1,5 +1,5 @@ -import { NotFoundError } from '../../../../../src/sbvr-api/errors'; -import { sbvrUtils } from '../../../../../src/server-glue/module'; +import { NotFoundError } from '../../../../../src/sbvr-api/errors.js'; +import { sbvrUtils } from '../../../../../src/server-glue/module.js'; const addHook = ( methods: Array[0]>, diff --git a/test/fixtures/04-translations/translations/v2/index.ts b/test/fixtures/04-translations/translations/v2/index.ts index 50518a79d..4fe5793b7 100644 --- a/test/fixtures/04-translations/translations/v2/index.ts +++ b/test/fixtures/04-translations/translations/v2/index.ts @@ -1,12 +1,12 @@ -import type { ConfigLoader } from '../../../../../src/server-glue/module'; -import { getAbstractSqlModelFromFile } from '../../../../../src/bin/utils'; +import type { ConfigLoader } from '../../../../../src/server-glue/module.js'; +import { getAbstractSqlModelFromFile } from '../../../../../src/bin/utils.js'; import type { AbstractSqlQuery, SelectQueryNode, } from '@balena/abstract-sql-compiler'; -export const v2AbstractSqlModel = getAbstractSqlModelFromFile( - __dirname + '/university.sbvr', +export const v2AbstractSqlModel = await getAbstractSqlModelFromFile( + import.meta.dirname + '/university.sbvr', undefined, ); diff --git a/test/fixtures/04-translations/translations/v3/hooks.ts b/test/fixtures/04-translations/translations/v3/hooks.ts index d5146bdee..e67434954 100644 --- a/test/fixtures/04-translations/translations/v3/hooks.ts +++ b/test/fixtures/04-translations/translations/v3/hooks.ts @@ -1,4 +1,4 @@ -import { sbvrUtils } from '../../../../../src/server-glue/module'; +import { sbvrUtils } from '../../../../../src/server-glue/module.js'; const addHook = ( methods: Array[0]>, diff --git a/test/fixtures/04-translations/translations/v3/index.ts b/test/fixtures/04-translations/translations/v3/index.ts index c7a173e00..3111c7b13 100644 --- a/test/fixtures/04-translations/translations/v3/index.ts +++ b/test/fixtures/04-translations/translations/v3/index.ts @@ -1,9 +1,9 @@ -import type { ConfigLoader } from '../../../../../src/server-glue/module'; -import { getAbstractSqlModelFromFile } from '../../../../../src/bin/utils'; +import type { ConfigLoader } from '../../../../../src/server-glue/module.js'; +import { getAbstractSqlModelFromFile } from '../../../../../src/bin/utils.js'; import type { AbstractSqlQuery } from '@balena/abstract-sql-compiler'; -export const v3AbstractSqlModel = getAbstractSqlModelFromFile( - __dirname + '/university.sbvr', +export const v3AbstractSqlModel = await getAbstractSqlModelFromFile( + import.meta.dirname + '/university.sbvr', undefined, ); diff --git a/test/fixtures/04-translations/translations/v4/index.ts b/test/fixtures/04-translations/translations/v4/index.ts index c666245bc..9121bd9f5 100644 --- a/test/fixtures/04-translations/translations/v4/index.ts +++ b/test/fixtures/04-translations/translations/v4/index.ts @@ -1,8 +1,8 @@ -import { getAbstractSqlModelFromFile } from '../../../../../src/bin/utils'; +import { getAbstractSqlModelFromFile } from '../../../../../src/bin/utils.js'; import type { AbstractSqlQuery } from '@balena/abstract-sql-compiler'; -export const v4AbstractSqlModel = getAbstractSqlModelFromFile( - __dirname + '/university.sbvr', +export const v4AbstractSqlModel = await getAbstractSqlModelFromFile( + import.meta.dirname + '/university.sbvr', undefined, ); diff --git a/test/fixtures/04-translations/translations/v5/index.ts b/test/fixtures/04-translations/translations/v5/index.ts index 36afe05a8..3f4ae6565 100644 --- a/test/fixtures/04-translations/translations/v5/index.ts +++ b/test/fixtures/04-translations/translations/v5/index.ts @@ -1,8 +1,8 @@ -import { getAbstractSqlModelFromFile } from '../../../../../src/bin/utils'; +import { getAbstractSqlModelFromFile } from '../../../../../src/bin/utils.js'; import type { AbstractSqlQuery } from '@balena/abstract-sql-compiler'; -export const v5AbstractSqlModel = getAbstractSqlModelFromFile( - __dirname + '/university.sbvr', +export const v5AbstractSqlModel = await getAbstractSqlModelFromFile( + import.meta.dirname + '/university.sbvr', undefined, ); diff --git a/test/fixtures/05-request-cancellation/config.ts b/test/fixtures/05-request-cancellation/config.ts index 882e3d1d4..97765e14d 100644 --- a/test/fixtures/05-request-cancellation/config.ts +++ b/test/fixtures/05-request-cancellation/config.ts @@ -1,8 +1,8 @@ -import type { ConfigLoader } from '../../../src/server-glue/module'; +import type { ConfigLoader } from '../../../src/server-glue/module.js'; const apiRoot = 'example'; const modelName = 'example'; -const modelFile = __dirname + '/example.sbvr'; +const modelFile = import.meta.dirname + '/example.sbvr'; export default { models: [ diff --git a/test/fixtures/05-request-cancellation/hooks.ts b/test/fixtures/05-request-cancellation/hooks.ts index 3c8a33728..704047030 100644 --- a/test/fixtures/05-request-cancellation/hooks.ts +++ b/test/fixtures/05-request-cancellation/hooks.ts @@ -1,6 +1,6 @@ import { setTimeout } from 'timers/promises'; -import { sbvrUtils } from '../../../src/server-glue/module'; -import { track } from './util'; +import { sbvrUtils } from '../../../src/server-glue/module.js'; +import { track } from './util.js'; sbvrUtils.addPureHook('POST', 'example', 'slow_resource', { async POSTRUN({ request, api }) { diff --git a/test/fixtures/05-request-cancellation/routes.ts b/test/fixtures/05-request-cancellation/routes.ts index 4933fac5d..ad8a3a3ab 100644 --- a/test/fixtures/05-request-cancellation/routes.ts +++ b/test/fixtures/05-request-cancellation/routes.ts @@ -1,10 +1,10 @@ import type express from 'express'; import onFinished from 'on-finished'; -import * as pine from '../../../src/server-glue/module'; -import { handleHttpErrors } from '../../../src/sbvr-api/sbvr-utils'; +import * as pine from '../../../src/server-glue/module.js'; +import { handleHttpErrors } from '../../../src/sbvr-api/sbvr-utils.js'; import { setTimeout } from 'timers/promises'; -import { track } from './util'; -import { BadRequestError } from '../../../src/sbvr-api/errors'; +import { track } from './util.js'; +import { BadRequestError } from '../../../src/sbvr-api/errors.js'; export const initRoutes = (app: express.Express) => { app.post('/slow-custom-endpoint', async (req, res) => { diff --git a/test/fixtures/05-request-cancellation/util.ts b/test/fixtures/05-request-cancellation/util.ts index c2b981fd5..54d4fcda6 100644 --- a/test/fixtures/05-request-cancellation/util.ts +++ b/test/fixtures/05-request-cancellation/util.ts @@ -1,4 +1,4 @@ -import { sbvrUtils } from '../../../src/server-glue/module'; +import { sbvrUtils } from '../../../src/server-glue/module.js'; // Since pine runs in a different process than the tests, we can't use spies, // so we use a resource as a workaround for persistence outside of TXs. diff --git a/test/fixtures/06-webresource/config.ts b/test/fixtures/06-webresource/config.ts index 39d1101dc..8c40bb4b6 100644 --- a/test/fixtures/06-webresource/config.ts +++ b/test/fixtures/06-webresource/config.ts @@ -1,12 +1,12 @@ -import type { ConfigLoader } from '../../../src/server-glue/module'; -import type { WebResourceHandler } from '../../../src/webresource-handler'; -import { S3Handler } from '../../../src/webresource-handler/handlers/S3Handler'; -import { v1AbstractSqlModel, v1Translations } from './translations/v1'; +import type { ConfigLoader } from '../../../src/server-glue/module.js'; +import type { WebResourceHandler } from '../../../src/webresource-handler/index.js'; +import { S3Handler } from '../../../src/webresource-handler/handlers/S3Handler.js'; +import { v1AbstractSqlModel, v1Translations } from './translations/v1/index.js'; import { requiredVar, intVar } from '@balena/env-parsing'; const apiRoot = 'example'; const modelName = 'example'; -const modelFile = __dirname + '/example.sbvr'; +const modelFile = import.meta.dirname + '/example.sbvr'; const s3Handler: WebResourceHandler = new S3Handler({ bucket: requiredVar('S3_STORAGE_ADAPTER_BUCKET'), diff --git a/test/fixtures/06-webresource/translations/hooks.ts b/test/fixtures/06-webresource/translations/hooks.ts index 59bac1f9a..636c3972a 100644 --- a/test/fixtures/06-webresource/translations/hooks.ts +++ b/test/fixtures/06-webresource/translations/hooks.ts @@ -1 +1 @@ -import './v1/hooks'; +import './v1/hooks.js'; diff --git a/test/fixtures/06-webresource/translations/v1/hooks.ts b/test/fixtures/06-webresource/translations/v1/hooks.ts index 6fef3ee9f..865a9b5af 100644 --- a/test/fixtures/06-webresource/translations/v1/hooks.ts +++ b/test/fixtures/06-webresource/translations/v1/hooks.ts @@ -1,4 +1,4 @@ -import { sbvrUtils } from '../../../../../src/server-glue/module'; +import { sbvrUtils } from '../../../../../src/server-glue/module.js'; const addHook = ( methods: Array[0]>, diff --git a/test/fixtures/06-webresource/translations/v1/index.ts b/test/fixtures/06-webresource/translations/v1/index.ts index 5b9c9814e..dc4435e82 100644 --- a/test/fixtures/06-webresource/translations/v1/index.ts +++ b/test/fixtures/06-webresource/translations/v1/index.ts @@ -1,10 +1,10 @@ -import type { ConfigLoader } from '../../../../../src/server-glue/module'; -import { getAbstractSqlModelFromFile } from '../../../../../src/bin/utils'; +import type { ConfigLoader } from '../../../../../src/server-glue/module.js'; +import { getAbstractSqlModelFromFile } from '../../../../../src/bin/utils.js'; export const toVersion = 'example'; -export const v1AbstractSqlModel = getAbstractSqlModelFromFile( - __dirname + '/example.sbvr', +export const v1AbstractSqlModel = await getAbstractSqlModelFromFile( + import.meta.dirname + '/example.sbvr', undefined, ); diff --git a/test/fixtures/07-permissions/config.ts b/test/fixtures/07-permissions/config.ts index 2ae6e9592..fa982c30f 100644 --- a/test/fixtures/07-permissions/config.ts +++ b/test/fixtures/07-permissions/config.ts @@ -1,8 +1,8 @@ -import type { ConfigLoader } from '../../../src/server-glue/module'; +import type { ConfigLoader } from '../../../src/server-glue/module.js'; const apiRoot = 'university'; const modelName = 'university'; -const modelFile = __dirname + '/university.sbvr'; +const modelFile = import.meta.dirname + '/university.sbvr'; export default { models: [ diff --git a/test/fixtures/08-tasks/config.ts b/test/fixtures/08-tasks/config.ts index 5c66ccd31..fc484c051 100644 --- a/test/fixtures/08-tasks/config.ts +++ b/test/fixtures/08-tasks/config.ts @@ -1,20 +1,20 @@ -import type { ConfigLoader } from '../../../src/server-glue/module'; +import type { ConfigLoader } from '../../../src/server-glue/module.js'; export default { models: [ { modelName: 'Auth', - modelFile: __dirname + '/../../../src/sbvr-api/user.sbvr', + modelFile: import.meta.dirname + '/../../../src/sbvr-api/user.sbvr', apiRoot: 'Auth', }, { modelName: 'tasks', - modelFile: __dirname + '/../../../src/tasks/tasks.sbvr', + modelFile: import.meta.dirname + '/../../../src/tasks/tasks.sbvr', apiRoot: 'tasks', }, { modelName: 'example', - modelFile: __dirname + '/example.sbvr', + modelFile: import.meta.dirname + '/example.sbvr', apiRoot: 'example', }, ], diff --git a/test/fixtures/08-tasks/task-handlers.ts b/test/fixtures/08-tasks/task-handlers.ts index ecb9c7749..562d2c2c8 100644 --- a/test/fixtures/08-tasks/task-handlers.ts +++ b/test/fixtures/08-tasks/task-handlers.ts @@ -1,5 +1,5 @@ import type { FromSchema } from 'json-schema-to-ts'; -import { sbvrUtils, tasks } from '../../../src/server-glue/module'; +import { sbvrUtils, tasks } from '../../../src/server-glue/module.js'; // Define JSON schema for accepted parameters const createDeviceParamsSchema = { diff --git a/test/lib/pine-in-process.ts b/test/lib/pine-in-process.ts index 81e487698..14765169d 100644 --- a/test/lib/pine-in-process.ts +++ b/test/lib/pine-in-process.ts @@ -1,9 +1,9 @@ import { exit } from 'process'; import cluster from 'node:cluster'; -import type { PineTestOptions } from './pine-init'; -import { init } from './pine-init'; -import { tasks } from '../../src/server-glue/module'; -import { PINE_TEST_SIGNALS } from './common'; +import type { PineTestOptions } from './pine-init.js'; +import { init } from './pine-init.js'; +import { tasks } from '../../src/server-glue/module.js'; +import { PINE_TEST_SIGNALS } from './common.js'; import { type Serializable } from 'child_process'; const createWorker = ( @@ -67,7 +67,7 @@ async function runApp(processArgs: PineTestOptions) { const { default: initConfig } = await import(processArgs.configPath); console.info(`listenPort: ${processArgs.listenPort}`); const app = await init( - initConfig.default, + initConfig, processArgs.listenPort, processArgs.withLoginRoute, ); @@ -79,16 +79,12 @@ async function runApp(processArgs: PineTestOptions) { // load task handlers if (processArgs.taskHandlersPath) { - const { - default: { initTaskHandlers }, - } = await import(processArgs.taskHandlersPath); + const { initTaskHandlers } = await import(processArgs.taskHandlersPath); initTaskHandlers(); } if (processArgs.routesPath) { - const { - default: { initRoutes }, - } = await import(processArgs.routesPath); + const { initRoutes } = await import(processArgs.routesPath); initRoutes(app); } diff --git a/test/lib/pine-init.ts b/test/lib/pine-init.ts index d6846bb4e..4e8660009 100644 --- a/test/lib/pine-init.ts +++ b/test/lib/pine-init.ts @@ -1,6 +1,6 @@ import express from 'express'; import { exit } from 'process'; -import * as pine from '../../src/server-glue/module'; +import * as pine from '../../src/server-glue/module.js'; export type PineTestOptions = { configPath: string; diff --git a/test/lib/test-init.ts b/test/lib/test-init.ts index 84e62ad78..8559dafef 100644 --- a/test/lib/test-init.ts +++ b/test/lib/test-init.ts @@ -1,9 +1,9 @@ import type { ChildProcess } from 'child_process'; import { fork } from 'child_process'; import { boolVar } from '@balena/env-parsing'; -import * as pine from '../../src/server-glue/module'; -import type { PineTestOptions } from './pine-init'; -import type { OptionalField } from '../../src/sbvr-api/common-types'; +import * as pine from '../../src/server-glue/module.js'; +import type { PineTestOptions } from './pine-init.js'; +import type { OptionalField } from '../../src/sbvr-api/common-types.js'; export const listenPortDefault = 1337; export const testLocalServer = `http://localhost:${listenPortDefault}`; @@ -25,7 +25,7 @@ export async function testInit( await cleanDb(); } const testServer = fork( - __dirname + '/pine-in-process.ts', + import.meta.dirname + '/pine-in-process.ts', [JSON.stringify(processArgs)], { detached: false, diff --git a/tsconfig.dev.json b/tsconfig.dev.json index f0cbfb7fd..baea09633 100644 --- a/tsconfig.dev.json +++ b/tsconfig.dev.json @@ -1,13 +1,15 @@ { "extends": "./tsconfig.json", "compilerOptions": { - "rootDir": "." + "rootDir": ".", + "allowImportingTsExtensions": true }, "include": [ "build/**/*", + "bin/**/*", "src/**/*", "test/**/*", "typings/**/*.d.ts", - "Gruntfile.ts" + "Gruntfile.cts" ] } diff --git a/tsconfig.json b/tsconfig.json index 03e9038c5..c12880529 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "module": "Node16", + "module": "NodeNext", "strict": true, "strictFunctionTypes": false, "noImplicitThis": false, diff --git a/typings/lf-to-abstract-sql.d.ts b/typings/lf-to-abstract-sql.d.ts index a1a728577..aa8ce3a53 100644 --- a/typings/lf-to-abstract-sql.d.ts +++ b/typings/lf-to-abstract-sql.d.ts @@ -5,7 +5,7 @@ declare module '@balena/lf-to-abstract-sql' { export const LF2AbstractSQL: { createInstance: () => { match: (lfModel: LFModel, rule: 'Process') => AbstractSqlModel; - addTypes: (types: typeof sbvrTypes) => void; + addTypes: (types: typeof sbvrTypes.default) => void; reset: () => void; }; }; @@ -14,6 +14,6 @@ declare module '@balena/lf-to-abstract-sql' { _extend(obj: object): typeof LF2AbstractSQLPrep; }; export const createTranslator: ( - types: typeof sbvrTypes, + types: typeof sbvrTypes.default, ) => (lfModel: LFModel, rule: 'Process') => AbstractSqlModel; } diff --git a/typings/memoizee.d.ts b/typings/memoizee.d.ts index f374180bf..4f2ed0394 100644 --- a/typings/memoizee.d.ts +++ b/typings/memoizee.d.ts @@ -1,4 +1,4 @@ -declare module 'memoizee/weak' { +declare module 'memoizee/weak.js' { import type * as Memoize from 'memoizee'; type FirstArg = T extends (arg1: infer U) => any ? U : any;