diff --git a/CHANGELOG.md b/CHANGELOG.md index a2a850d0..2af51b11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Dev * update @cucumber/html-formatter ([#213](https://github.com/vitalets/playwright-bdd/issues/213)) +* chore: use import subpath from package.json for internal imports ## 7.2.2 * fix: provide empty world for Playwright-style steps ([#208](https://github.com/vitalets/playwright-bdd/issues/208)) diff --git a/eslint.config.mjs b/eslint.config.mjs index b936ad63..92d6ad2c 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -51,6 +51,19 @@ export default [ 'no-empty-pattern': 0, }, }, + { + files: ['src/**/*.ts'], + rules: { + 'no-restricted-imports': [ + 'error', + { + // restrict high parent imports in favor of import subpaths (not path alias!) + // https://www.typescriptlang.org/docs/handbook/modules/reference.html#packagejson-imports-and-self-name-imports + patterns: ['../../../*'], + }, + ], + }, + }, { files: ['test/**/*.{ts,js,mjs}'], plugins: { diff --git a/knip.config.mts b/knip.config.mts index 0dfae9ab..c5d1b55d 100644 --- a/knip.config.mts +++ b/knip.config.mts @@ -7,16 +7,15 @@ const config: KnipConfig = { 'src/index.ts', 'src/decorators.ts', 'src/reporter/cucumber/index.ts', + 'scripts/**', + 'examples/**', 'test/**', ], - project: ['src/**/*.ts'], - ignore: ['**/*.d.ts'], + ignore: ['**/*.d.ts', '**/.features-gen/**'], ignoreBinaries: ['docsify'], ignoreDependencies: [ '@cucumber/compatibility-kit', '@cucumber/pretty-formatter', - '@types/react-dom', - 'react-dom', 'lint-staged', 'np', 'npm-run-all', diff --git a/package-lock.json b/package-lock.json index b2aac78c..9dc5e0ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,7 +40,7 @@ "eslint-plugin-playwright": "1.6.2", "expect-type": "0.19.0", "globals": "15.8.0", - "knip": "5.26.0", + "knip": "5.27.4", "lint-staged": "15.2.7", "lodash.get": "4.4.2", "marked": "13.0.2", @@ -4310,6 +4310,19 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, + "node_modules/enhanced-resolve": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -6603,9 +6616,9 @@ } }, "node_modules/knip": { - "version": "5.26.0", - "resolved": "https://registry.npmjs.org/knip/-/knip-5.26.0.tgz", - "integrity": "sha512-vOp+Wk86aqlPwElrUpxXyg6Q8w+j0j6wuzyu5p6k/mBWUI8iP91PCAz1Jzz9PGq5JYdptV7rFBYB9vHr7AFgqg==", + "version": "5.27.4", + "resolved": "https://registry.npmjs.org/knip/-/knip-5.27.4.tgz", + "integrity": "sha512-7t1yqIKxaVGYD1cLI4raVLWi9cNqv+JNbngc8mgvTVJbomnxOg1pjxgCGEztB7eVgD+6VEwf7Jg5WHXzk+Kbpw==", "dev": true, "funding": [ { @@ -6625,6 +6638,7 @@ "@nodelib/fs.walk": "1.2.8", "@snyk/github-codeowners": "1.1.0", "easy-table": "1.2.0", + "enhanced-resolve": "^5.17.1", "fast-glob": "^3.3.2", "jiti": "^1.21.6", "js-yaml": "^4.1.0", @@ -6632,7 +6646,6 @@ "picocolors": "^1.0.0", "picomatch": "^4.0.1", "pretty-ms": "^9.0.0", - "resolve": "^1.22.8", "smol-toml": "^1.1.4", "strip-json-comments": "5.0.1", "summary": "2.1.0", @@ -10724,6 +10737,15 @@ "node": ">=0.10" } }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/terminal-link": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-3.0.0.tgz", diff --git a/package.json b/package.json index cbb240bf..8f4d0666 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,12 @@ "./reporter/cucumber": "./dist/reporter/cucumber/index.js", "./package.json": "./package.json" }, + "imports": { + "#*": { + "pw-bdd-dev": "./dist/src/*", + "default": "./dist/*" + } + }, "engines": { "node": ">=18" }, @@ -25,7 +31,7 @@ "prepare": "git config core.hooksPath .hooks", "lint": "eslint .", "tsc": "tsc", - "knip": "knip -c knip.config.mts", + "knip": "knip -c knip.config.mts --tsConfig tsconfig.build.json", "prettier": "prettier --check --ignore-unknown .", "prettier:w": "prettier --write --ignore-unknown .", "test": "node test/setup.mjs && node --test test/**/test.mjs", @@ -73,7 +79,7 @@ "eslint-plugin-playwright": "1.6.2", "expect-type": "0.19.0", "globals": "15.8.0", - "knip": "5.26.0", + "knip": "5.27.4", "lint-staged": "15.2.7", "lodash.get": "4.4.2", "marked": "13.0.2", diff --git a/src/cli/commands/env.ts b/src/cli/commands/env.ts index 7f356da8..6eaccdea 100644 --- a/src/cli/commands/env.ts +++ b/src/cli/commands/env.ts @@ -2,7 +2,7 @@ import { Command } from 'commander'; import { ConfigOption } from '../options'; import { Logger } from '../../utils/logger'; import { getPackageVersion } from '../../utils'; -import { resolveConfigFile } from '../../playwright/loadConfig'; +import { resolveConfigFile } from '#playwright/loadConfig.js'; import { relativeToCwd } from '../../utils/paths'; const logger = new Logger({ verbose: true }); diff --git a/src/reporter/cucumber/base.ts b/src/reporter/cucumber/base.ts index 736c20c8..e0d38bdb 100644 --- a/src/reporter/cucumber/base.ts +++ b/src/reporter/cucumber/base.ts @@ -8,7 +8,7 @@ import fs from 'node:fs'; import { Writable } from 'node:stream'; import { finished } from 'node:stream/promises'; import { EventEmitter } from 'node:events'; -import EventDataCollector from '../../cucumber/formatter/EventDataCollector'; +import EventDataCollector from '#cucumber/formatter/EventDataCollector.js'; export type InternalOptions = { cwd: string; diff --git a/src/reporter/cucumber/messagesBuilder/AttachmentMapper.ts b/src/reporter/cucumber/messagesBuilder/AttachmentMapper.ts index d0c69eb4..0a7fdd95 100644 --- a/src/reporter/cucumber/messagesBuilder/AttachmentMapper.ts +++ b/src/reporter/cucumber/messagesBuilder/AttachmentMapper.ts @@ -55,10 +55,10 @@ * 2.4 remove found attachment from attachments array */ import * as pw from '@playwright/test/reporter'; -import { AutofillMap } from '../../../utils/AutofillMap'; +import { AutofillMap } from '#utils/AutofillMap.js'; import { collectStepsWithCategory, getHooksRootPwStep } from './pwStepUtils'; -import { PwAttachment } from '../../../playwright/types'; -import { stripAnsiEscapes } from '../../../utils/stripAnsiEscapes'; +import { PwAttachment } from '#playwright/types.js'; +import { stripAnsiEscapes } from '#utils/stripAnsiEscapes.js'; export class AttachmentMapper { private stepAttachments = new AutofillMap(); diff --git a/src/reporter/cucumber/messagesBuilder/GherkinDocument.ts b/src/reporter/cucumber/messagesBuilder/GherkinDocument.ts index 21d2fb88..1795ce4c 100644 --- a/src/reporter/cucumber/messagesBuilder/GherkinDocument.ts +++ b/src/reporter/cucumber/messagesBuilder/GherkinDocument.ts @@ -3,9 +3,9 @@ * Attaches extra fields (meta). */ import * as messages from '@cucumber/messages'; -import { GherkinDocumentWithPickles } from '../../../features/load'; +import { GherkinDocumentWithPickles } from '#features/load.js'; import { ConcreteEnvelope } from './types'; -import { omit } from '../../../utils'; +import { omit } from '#utils/index.js'; import { ProjectInfo, getFeatureUriWithProject } from './Projects'; type GherkinDocumentMeta = { diff --git a/src/reporter/cucumber/messagesBuilder/GherkinDocumentClone.ts b/src/reporter/cucumber/messagesBuilder/GherkinDocumentClone.ts index 99d24d9b..b7a46319 100644 --- a/src/reporter/cucumber/messagesBuilder/GherkinDocumentClone.ts +++ b/src/reporter/cucumber/messagesBuilder/GherkinDocumentClone.ts @@ -3,8 +3,8 @@ * pickle IDs and pickle steps IDs. */ import { randomUUID } from 'node:crypto'; -import { GherkinDocumentWithPickles, PickleWithLocation } from '../../../features/load'; -import { AutofillMap } from '../../../utils/AutofillMap'; +import { GherkinDocumentWithPickles, PickleWithLocation } from '#features/load.js'; +import { AutofillMap } from '#utils/AutofillMap.js'; export class GherkinDocumentClone { private oldNewIds = new AutofillMap(); diff --git a/src/reporter/cucumber/messagesBuilder/GherkinDocuments.ts b/src/reporter/cucumber/messagesBuilder/GherkinDocuments.ts index 67d67afd..bf6060bd 100644 --- a/src/reporter/cucumber/messagesBuilder/GherkinDocuments.ts +++ b/src/reporter/cucumber/messagesBuilder/GherkinDocuments.ts @@ -3,16 +3,16 @@ */ import path from 'node:path'; import * as messages from '@cucumber/messages'; -import { AutofillMap } from '../../../utils/AutofillMap'; +import { AutofillMap } from '#utils/AutofillMap.js'; import { TestCaseRun } from './TestCaseRun'; -import { FeaturesLoader, GherkinDocumentWithPickles } from '../../../features/load'; -import { getPlaywrightConfigDir } from '../../../config/configDir'; +import { FeaturesLoader, GherkinDocumentWithPickles } from '#features/load.js'; +import { getPlaywrightConfigDir } from '#config/configDir.js'; import { ConcreteEnvelope } from './types'; import { GherkinDocumentClone } from './GherkinDocumentClone'; import { GherkinDocumentMessage } from './GherkinDocument'; import { ProjectInfo, getFeatureUriWithProject } from './Projects'; -import { getEnvConfigs } from '../../../config/env'; -import { LANG_EN } from '../../../config/lang'; +import { getEnvConfigs } from '#config/env.js'; +import { LANG_EN } from '#config/lang.js'; export class GherkinDocuments { private featuresLoader = new FeaturesLoader(); diff --git a/src/reporter/cucumber/messagesBuilder/Hook.ts b/src/reporter/cucumber/messagesBuilder/Hook.ts index 6ae14b6b..c7d70d83 100644 --- a/src/reporter/cucumber/messagesBuilder/Hook.ts +++ b/src/reporter/cucumber/messagesBuilder/Hook.ts @@ -5,7 +5,7 @@ import { randomUUID } from 'node:crypto'; import * as pw from '@playwright/test/reporter'; import * as messages from '@cucumber/messages'; -import { getPlaywrightConfigDir } from '../../../config/configDir'; +import { getPlaywrightConfigDir } from '#config/configDir.js'; import path from 'node:path'; export type HookType = 'before' | 'after'; diff --git a/src/reporter/cucumber/messagesBuilder/Meta.ts b/src/reporter/cucumber/messagesBuilder/Meta.ts index 7d56e2ce..4f44e219 100644 --- a/src/reporter/cucumber/messagesBuilder/Meta.ts +++ b/src/reporter/cucumber/messagesBuilder/Meta.ts @@ -4,7 +4,7 @@ */ import os from 'node:os'; import * as messages from '@cucumber/messages'; -import { getPackageVersion } from '../../../utils'; +import { getPackageVersion } from '#utils/index.js'; export class Meta { buildMessage() { diff --git a/src/reporter/cucumber/messagesBuilder/Pickles.ts b/src/reporter/cucumber/messagesBuilder/Pickles.ts index 14234e3d..cfdea85c 100644 --- a/src/reporter/cucumber/messagesBuilder/Pickles.ts +++ b/src/reporter/cucumber/messagesBuilder/Pickles.ts @@ -2,8 +2,8 @@ * Builds Pickle messages. */ import * as messages from '@cucumber/messages'; -import { omit } from '../../../utils'; -import { AutofillMap } from '../../../utils/AutofillMap'; +import { omit } from '#utils/index.js'; +import { AutofillMap } from '#utils/AutofillMap.js'; import { TestCase } from './TestCase'; import { ConcreteEnvelope } from './types'; import { getFeatureUriWithProject } from './Projects'; diff --git a/src/reporter/cucumber/messagesBuilder/Projects.ts b/src/reporter/cucumber/messagesBuilder/Projects.ts index 4e6aa041..46569c76 100644 --- a/src/reporter/cucumber/messagesBuilder/Projects.ts +++ b/src/reporter/cucumber/messagesBuilder/Projects.ts @@ -4,7 +4,7 @@ * See: https://github.com/microsoft/playwright/issues/29841 */ import * as pw from '@playwright/test/reporter'; -import { AutofillMap } from '../../../utils/AutofillMap'; +import { AutofillMap } from '#utils/AutofillMap.js'; export type ProjectInfo = { projectName?: string; diff --git a/src/reporter/cucumber/messagesBuilder/TestCase.ts b/src/reporter/cucumber/messagesBuilder/TestCase.ts index 77a521c3..b75cccc0 100644 --- a/src/reporter/cucumber/messagesBuilder/TestCase.ts +++ b/src/reporter/cucumber/messagesBuilder/TestCase.ts @@ -12,10 +12,10 @@ import * as messages from '@cucumber/messages'; import { TestCaseRun } from './TestCaseRun'; import { Hook, HookType } from './Hook'; -import { GherkinDocumentWithPickles, PickleWithLocation } from '../../../features/load'; -import { stringifyLocation } from '../../../utils'; +import { GherkinDocumentWithPickles, PickleWithLocation } from '#features/load.js'; +import { stringifyLocation } from '#utils/index.js'; import { ProjectInfo } from './Projects'; -import { BddData } from '../../../run/bddAnnotation/types'; +import { BddData } from '#run/bddAnnotation/types.js'; type HookWithStep = { hook: Hook; diff --git a/src/reporter/cucumber/messagesBuilder/TestCaseRun.ts b/src/reporter/cucumber/messagesBuilder/TestCaseRun.ts index a4c6635c..1bbad6d6 100644 --- a/src/reporter/cucumber/messagesBuilder/TestCaseRun.ts +++ b/src/reporter/cucumber/messagesBuilder/TestCaseRun.ts @@ -3,18 +3,18 @@ */ import * as pw from '@playwright/test/reporter'; import * as messages from '@cucumber/messages'; -import { stringifyLocation } from '../../../utils'; +import { stringifyLocation } from '#utils/index.js'; import { Hook, HookType } from './Hook'; import { TestCase } from './TestCase'; -import { AutofillMap } from '../../../utils/AutofillMap'; +import { AutofillMap } from '#utils/AutofillMap.js'; import { TestStepRun, TestStepRunEnvelope } from './TestStepRun'; import { toCucumberTimestamp } from './timing'; import { collectStepsWithCategory, isUnknownDuration } from './pwStepUtils'; import { AttachmentMapper } from './AttachmentMapper'; import { TestCaseRunHooks } from './TestCaseRunHooks'; import { ProjectInfo, getProjectInfo } from './Projects'; -import { BddData, BddDataStep } from '../../../run/bddAnnotation/types'; -import { getBddDataFromTest } from '../../../run/bddAnnotation'; +import { BddData, BddDataStep } from '#run/bddAnnotation/types.js'; +import { getBddDataFromTest } from '#run/bddAnnotation/index.js'; export type TestCaseRunEnvelope = TestStepRunEnvelope & Pick< diff --git a/src/reporter/cucumber/messagesBuilder/TestStepAttachments.ts b/src/reporter/cucumber/messagesBuilder/TestStepAttachments.ts index 5262684d..fd912a4f 100644 --- a/src/reporter/cucumber/messagesBuilder/TestStepAttachments.ts +++ b/src/reporter/cucumber/messagesBuilder/TestStepAttachments.ts @@ -5,7 +5,7 @@ import fs from 'node:fs'; import * as pw from '@playwright/test/reporter'; import * as messages from '@cucumber/messages'; import { TestCaseRun } from './TestCaseRun'; -import { PwAttachment } from '../../../playwright/types'; +import { PwAttachment } from '#playwright/types.js'; import path from 'node:path'; export class TestStepAttachments { diff --git a/src/reporter/cucumber/messagesBuilder/TestStepRun.ts b/src/reporter/cucumber/messagesBuilder/TestStepRun.ts index e04f9412..c2729920 100644 --- a/src/reporter/cucumber/messagesBuilder/TestStepRun.ts +++ b/src/reporter/cucumber/messagesBuilder/TestStepRun.ts @@ -9,7 +9,7 @@ */ import * as pw from '@playwright/test/reporter'; import * as messages from '@cucumber/messages'; -import { stripAnsiEscapes } from '../../../utils/stripAnsiEscapes'; +import { stripAnsiEscapes } from '#utils/stripAnsiEscapes.js'; import { TestCaseRun } from './TestCaseRun'; import { toCucumberTimestamp } from './timing'; import { TestStepAttachments } from './TestStepAttachments'; diff --git a/src/reporter/cucumber/messagesBuilder/index.ts b/src/reporter/cucumber/messagesBuilder/index.ts index af095c37..55429044 100644 --- a/src/reporter/cucumber/messagesBuilder/index.ts +++ b/src/reporter/cucumber/messagesBuilder/index.ts @@ -8,13 +8,13 @@ import { TestCase } from './TestCase'; import { Meta } from './Meta'; import { TimeMeasured, calcMinMaxByArray, toCucumberTimestamp } from './timing'; import EventEmitter from 'node:events'; -import EventDataCollector from '../../../cucumber/formatter/EventDataCollector'; +import EventDataCollector from '#cucumber/formatter/EventDataCollector.js'; import { Hook } from './Hook'; -import { AutofillMap } from '../../../utils/AutofillMap'; +import { AutofillMap } from '#utils/AutofillMap.js'; import { GherkinDocuments } from './GherkinDocuments'; import { Pickles } from './Pickles'; import { ConcreteEnvelope } from './types'; -import { hasBddConfig } from '../../../config/env'; +import { hasBddConfig } from '#config/env.js'; export class MessagesBuilder { private report = { diff --git a/tsconfig.build.json b/tsconfig.build.json index fe374c5a..a1b148df 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -3,6 +3,7 @@ "compilerOptions": { "rootDir": "src", "outDir": "dist", + "customConditions": [], "noEmit": false, "declaration": true, "declarationMap": true, diff --git a/tsconfig.json b/tsconfig.json index 7d03b0d2..d0193372 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,10 +7,15 @@ "useUnknownInCatchVariables": false, "forceConsistentCasingInFileNames": true, "skipLibCheck": true, + "resolvePackageJsonImports": true, + "rootDir": ".", + "outDir": "dist", + "customConditions": ["pw-bdd-dev"], "noEmit": true, "resolveJsonModule": true, "esModuleInterop": true, - "jsx": "react" + "jsx": "react-jsx" }, - "include": ["**/*.ts", "**/*.tsx", "knip.config.mts"] + "include": ["**/*.ts", "**/*.tsx", "**/*.mts"], + "exclude": ["test/types-non-strict"] }