fastypest 3.0.38 → 3.0.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/specs/2026-07-31-event-driven-release-pipeline.md +141 -0
- package/.agents/specs/2026-07-31-release-auto-merge.md +66 -0
- package/dist/core/fastypest.js +1 -3
- package/dist/core/fastypest.js.map +1 -1
- package/dist/core/sql-script/sql-script.js +1 -3
- package/dist/core/sql-script/sql-script.js.map +1 -1
- package/dist/logging/logger.js +1 -3
- package/dist/logging/logger.js.map +1 -1
- package/package.json +9 -9
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Event-driven release pipeline
|
|
2
|
+
|
|
3
|
+
## Request
|
|
4
|
+
|
|
5
|
+
Split Fastypest release automation into independent event-driven workflows:
|
|
6
|
+
|
|
7
|
+
1. After each update to the default branch, count commits since the latest published release and create a version pull request once the configured threshold is reached.
|
|
8
|
+
2. After a default-branch update changes `package.json` version, create the corresponding immutable tag and GitHub Release with generated notes.
|
|
9
|
+
3. After a GitHub Release is published, publish the matching package version to npm through the existing trusted-publisher workflow.
|
|
10
|
+
4. Automatically validate, approve, and queue trusted release pull requests for squash auto-merge.
|
|
11
|
+
5. Preserve the exact `.github/workflows/auto-release.workflow.yml` filename required by npm OIDC.
|
|
12
|
+
|
|
13
|
+
Only `fastypest` is in scope. `typeorm-test-db` and DevBar are excluded.
|
|
14
|
+
|
|
15
|
+
## Evidence
|
|
16
|
+
|
|
17
|
+
- GitHub suppresses most follow-up workflow runs for events emitted with the repository `GITHUB_TOKEN`.
|
|
18
|
+
- Pull requests created with `GITHUB_TOKEN` require explicit workflow approval before their pull-request workflows run.
|
|
19
|
+
- A personal access token or GitHub App token can create the release branch and pull request while allowing normal pull-request checks to run.
|
|
20
|
+
- The `release.published` event supports both manually and automatically published GitHub Releases.
|
|
21
|
+
- npm trusted publishing binds the package to an exact workflow filename and requires OIDC.
|
|
22
|
+
- The previous implementation combined npm publication, tag creation, and GitHub Release creation after a pull-request state transition.
|
|
23
|
+
- Review found and the implementation corrected exact-release-commit targeting, shell template expansion, persisted checkout credentials, label validation under `pipefail`, and missing approval-workflow ownership documentation.
|
|
24
|
+
|
|
25
|
+
## Scope
|
|
26
|
+
|
|
27
|
+
- Refactor `prepare-release.workflow.yml` to run on default-branch pushes and manual dispatch.
|
|
28
|
+
- Add `create-github-release.workflow.yml`.
|
|
29
|
+
- Change `auto-release.workflow.yml` to publish npm only from `release.published`.
|
|
30
|
+
- Harden the existing trusted release approval job.
|
|
31
|
+
- Add scoped GitHub automation guidance.
|
|
32
|
+
- Preserve manual release recovery, manual release-to-npm delivery, dry-run release calculation, release strategies, breaking-change notes, build checks, and package installation smoke tests.
|
|
33
|
+
|
|
34
|
+
## Decision
|
|
35
|
+
|
|
36
|
+
Use event boundaries as the orchestration contract:
|
|
37
|
+
|
|
38
|
+
```text
|
|
39
|
+
push default branch
|
|
40
|
+
├─ prepare release PR when threshold is reached
|
|
41
|
+
└─ create GitHub Release when package.json version changes
|
|
42
|
+
|
|
43
|
+
release pull request
|
|
44
|
+
└─ validate exact contract → bot approval → PAT-backed auto-merge
|
|
45
|
+
|
|
46
|
+
release.published
|
|
47
|
+
└─ validate tag and package → build/package smoke → npm OIDC publish
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`PAT_FINE` is used only in the protected `admin` environment where an operation must emit a follow-up event: release branch push, release pull-request creation, auto-merge enablement, immutable tag creation, and GitHub Release publication. GitHub Actions bot approval continues to use `github.token`. npm publication uses OIDC only.
|
|
51
|
+
|
|
52
|
+
## Acceptance
|
|
53
|
+
|
|
54
|
+
- A default-branch push below the threshold does not create a release pull request.
|
|
55
|
+
- A default-branch push at or above the threshold creates at most one owner-authored `release/v<version>` pull request.
|
|
56
|
+
- Release preparation is attached to the exact default-branch event SHA and does not drift to a newer branch head.
|
|
57
|
+
- The generated pull request changes exactly `package.json` and `CHANGELOG.md`.
|
|
58
|
+
- The trusted workflow validates the current head, title, exact branch, author, repository, base, label, package name, monotonic version, changelog entry, destination tag/release state, and changed files before approving.
|
|
59
|
+
- The approval is submitted through the reviews API against the validated commit SHA with body `Approved by the trusted release workflow contract.`
|
|
60
|
+
- Auto-merge is enabled only for the validated current head and repository rules remain the merge authority.
|
|
61
|
+
- A release pull-request merge does not immediately create another version pull request while the new package version lacks its GitHub Release.
|
|
62
|
+
- The release baseline tag must target a commit whose `package.json` contains the current version and whose release metadata matches stable or prerelease state.
|
|
63
|
+
- A changed package version creates an immutable tag and GitHub Release targeting the exact first-parent commit that introduced that version, including multi-commit push cases.
|
|
64
|
+
- Existing releases are accepted as idempotent only when tag target, draft state, and prerelease state match the resolved contract.
|
|
65
|
+
- Existing wrong-target tags or releases fail without force-updating or deleting them.
|
|
66
|
+
- Generated GitHub Releases use `PAT_FINE`, so `release.published` can trigger the npm workflow.
|
|
67
|
+
- Manually published owner releases trigger the same npm workflow.
|
|
68
|
+
- npm publication validates package name, semantic version, tag, prerelease state, default-branch ancestry, build, package archive, and existing npm state.
|
|
69
|
+
- Stable versions publish to `latest`; prereleases publish to `next`.
|
|
70
|
+
- Reruns are idempotent.
|
|
71
|
+
- No workflow polls check runs, directly merges a pull request, force-pushes a tag, or deletes release evidence on failure.
|
|
72
|
+
- The npm trusted-publisher workflow filename remains unchanged.
|
|
73
|
+
|
|
74
|
+
## Risks
|
|
75
|
+
|
|
76
|
+
- A broad or leaked PAT could create repository objects outside the intended release flow.
|
|
77
|
+
- A privileged `pull_request_target` workflow could execute untrusted pull-request code.
|
|
78
|
+
- Concurrent default-branch pushes could create duplicate release pull requests.
|
|
79
|
+
- Release creation can partially complete after tag creation.
|
|
80
|
+
- Manual releases could target an untrusted commit or mismatched package version.
|
|
81
|
+
- A prerelease could accidentally replace npm `latest`.
|
|
82
|
+
- A multi-commit default-branch push could place commits after the version change and accidentally expand the release target.
|
|
83
|
+
|
|
84
|
+
## Controls
|
|
85
|
+
|
|
86
|
+
- Restrict `PAT_FINE` to this repository and the minimum Contents/Pull requests permissions.
|
|
87
|
+
- Keep PAT-backed jobs behind the `admin` environment and verify the authenticated actor is the repository owner.
|
|
88
|
+
- Never checkout or execute pull-request code in the privileged approval job.
|
|
89
|
+
- Serialize release preparation and GitHub Release creation with repository-scoped concurrency.
|
|
90
|
+
- Attach release preparation to the event SHA before creating the release commit and branch.
|
|
91
|
+
- Treat an open trusted release pull request as a preparation barrier.
|
|
92
|
+
- Treat a package version without a GitHub Release as a preparation barrier.
|
|
93
|
+
- Bind approval and auto-merge to the live head SHA.
|
|
94
|
+
- Validate exact changed files, monotonic versioning, changelog content, and package metadata through the GitHub API.
|
|
95
|
+
- Resolve the exact first-parent commit that introduced the package version.
|
|
96
|
+
- Reject tag/release collisions and verify tag targets and release metadata after creation.
|
|
97
|
+
- Require release tags to be reachable from the default branch before npm publication.
|
|
98
|
+
- Pass event and action values into shell blocks through explicit environment variables.
|
|
99
|
+
- Use npm OIDC without a token fallback.
|
|
100
|
+
|
|
101
|
+
## Tests
|
|
102
|
+
|
|
103
|
+
- Parsed every changed workflow as YAML.
|
|
104
|
+
- Checked every changed shell block with `bash -n` after neutralizing GitHub expressions.
|
|
105
|
+
- Checked every changed `actions/github-script` program by parsing it inside an async function wrapper.
|
|
106
|
+
- Asserted every third-party action reference is pinned to a full commit SHA.
|
|
107
|
+
- Asserted the preparation workflow contains no check polling, direct merge, npm publish, GitHub Release creation, force push, or destructive cleanup.
|
|
108
|
+
- Asserted the release creator uses a package-version-change gate, exact tag target validation, generated notes, and `PAT_FINE`.
|
|
109
|
+
- Asserted the npm publisher is triggered only by `release.published`, retains its filename, has `id-token: write`, and contains no npm token fallback.
|
|
110
|
+
- Asserted the trusted approval validates branch, title, monotonic package metadata, changelog, changed files, destination collisions, and current head before bot approval and PAT-backed auto-merge.
|
|
111
|
+
- Exercised the exact release-SHA resolver with synthetic histories covering a multi-commit push, manual recovery, and a later `package.json` edit that retained the same version.
|
|
112
|
+
- Exercised the strict semantic-version parser and comparator for patch, minor, major, prerelease, stable-versus-prerelease, numeric-versus-string identifiers, and invalid leading-zero identifiers.
|
|
113
|
+
- Ran the repository pull-request build, format, package-install smoke, and database matrix on implementation heads.
|
|
114
|
+
- Resolved all initial review findings and confirmed no unresolved review threads before final delivery validation.
|
|
115
|
+
|
|
116
|
+
## Checks
|
|
117
|
+
|
|
118
|
+
- YAML syntax: passed.
|
|
119
|
+
- Shell syntax: passed.
|
|
120
|
+
- GitHub-script syntax: passed.
|
|
121
|
+
- Static workflow contract assertions: passed.
|
|
122
|
+
- Exact release-SHA synthetic cases: passed.
|
|
123
|
+
- Semantic-version parser/comparator cases: passed.
|
|
124
|
+
- Pull-request build, format, package smoke, and database matrix: passed on hardened implementation heads; the final documentation head remains subject to the normal pull-request CI gate.
|
|
125
|
+
- Initial review findings: resolved.
|
|
126
|
+
- Final diff inspection: no secret values, mutable release tags, privileged execution of pull-request code, duplicate release ownership, or destructive failure cleanup found.
|
|
127
|
+
|
|
128
|
+
## Rollback
|
|
129
|
+
|
|
130
|
+
Revert the implementation pull request. Existing tags, releases, packages, and generated release branches are not deleted. The previous merged-pull-request publication workflow is restored by the revert.
|
|
131
|
+
|
|
132
|
+
## Delivery
|
|
133
|
+
|
|
134
|
+
- Branch: `agent/refactor-event-driven-release`
|
|
135
|
+
- Pull request: `https://github.com/juanjoGonDev/fastypest/pull/1681`
|
|
136
|
+
- Merge: requires explicit owner approval
|
|
137
|
+
- Release/publication: not permitted from this implementation branch
|
|
138
|
+
|
|
139
|
+
## Status
|
|
140
|
+
|
|
141
|
+
Implementation, review hardening, and static validation are complete. Delivery remains gated by pull-request CI and explicit owner merge approval; no merge, GitHub Release, tag, or npm publication has been performed.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Release pull request auto-merge architecture
|
|
2
|
+
|
|
3
|
+
## Request
|
|
4
|
+
Replace the auto-release workflow's direct check polling and merge logic with repository-native auto-merge. Publish only after the release pull request has been merged by the configured branch requirements.
|
|
5
|
+
|
|
6
|
+
## Evidence
|
|
7
|
+
- Run `30620987564` created release PR `#1679`, then treated every check run as mandatory and aborted when an additional check failed.
|
|
8
|
+
- The package build, package installation smoke test, and project CI passed.
|
|
9
|
+
- The failure cleanup deleted the release branch and tag before the external check could be diagnosed.
|
|
10
|
+
- Code scanning can add or rename checks without changing the repository's required-check contract.
|
|
11
|
+
|
|
12
|
+
## Scope
|
|
13
|
+
- Prepare release metadata in a same-repository `release/<run-number>` pull request.
|
|
14
|
+
- Approve the exact release head and enable squash auto-merge.
|
|
15
|
+
- Publish npm, create the immutable tag, and create the GitHub Release only after the pull request merges.
|
|
16
|
+
- Preserve scheduled releases, manual strategies, dry runs, breaking-change metadata, package build, and package installation smoke tests.
|
|
17
|
+
|
|
18
|
+
## Decision
|
|
19
|
+
GitHub branch requirements are the source of truth for release eligibility. A dedicated preparation workflow does not enumerate check runs, wait for checks, merge directly, publish, or delete release evidence. The trusted pull-request workflow enables auto-merge for the exact head SHA. The existing `auto-release.workflow.yml` remains the owner of npm publication so its trusted-publisher identity is preserved; its merged-release job validates the pull-request contract before checking out the merge commit and publishing.
|
|
20
|
+
|
|
21
|
+
## Risks
|
|
22
|
+
- A malformed release pull request could trigger privileged publication.
|
|
23
|
+
- npm publication can succeed before tag or GitHub Release creation.
|
|
24
|
+
- A rerun can encounter an existing branch, tag, package version, or release.
|
|
25
|
+
- Missing workflow approval settings or `PAT_FINE` prevents release auto-merge.
|
|
26
|
+
|
|
27
|
+
## Controls
|
|
28
|
+
- Require a merged, same-repository, owner-authored, `auto-release` pull request targeting the default branch from `release/`.
|
|
29
|
+
- Require exactly `package.json` and `CHANGELOG.md` changes.
|
|
30
|
+
- Match the pull-request title to the package version.
|
|
31
|
+
- Bind approval and auto-merge to the current head SHA.
|
|
32
|
+
- Make npm, tag, and GitHub Release delivery idempotent and reject tag collisions.
|
|
33
|
+
- Keep privileged publication behind the `admin` environment.
|
|
34
|
+
|
|
35
|
+
## Acceptance
|
|
36
|
+
- A prepared release pull request exits without polling checks or merging directly.
|
|
37
|
+
- Auto-merge waits for the repository's configured requirements.
|
|
38
|
+
- Failed or pending checks leave the pull request and branch available for diagnosis.
|
|
39
|
+
- Publication cannot run before a trusted release pull request is merged.
|
|
40
|
+
- A successful merged release publishes the exact package version, tags the merge commit, creates a GitHub Release, and verifies all three outputs.
|
|
41
|
+
- Dry-run and breaking-change behavior remains available.
|
|
42
|
+
|
|
43
|
+
## Tests
|
|
44
|
+
- Parse all changed workflow YAML files.
|
|
45
|
+
- Assert the preparation workflow contains no check-run polling, direct merge API call, npm publication, release creation, forced tag update, or failure cleanup.
|
|
46
|
+
- Assert release approval enables auto-merge with an exact head match.
|
|
47
|
+
- Assert merged publication validates actor, repository, base, head prefix, label, changed files, title, package version, tag target, npm state, and GitHub Release state.
|
|
48
|
+
- Run the repository pull-request workflow on the resulting branch.
|
|
49
|
+
|
|
50
|
+
## Checks
|
|
51
|
+
- YAML syntax validation.
|
|
52
|
+
- Workflow contract inspection.
|
|
53
|
+
- Pull-request CI and CodeQL.
|
|
54
|
+
- Review final diff for secrets, mutable privileged behavior, and destructive cleanup.
|
|
55
|
+
|
|
56
|
+
## Rollback
|
|
57
|
+
Revert the pull request. Existing failed release PRs remain closed and no package or tag is recreated automatically. A later scheduled or manual release can create a fresh release pull request.
|
|
58
|
+
|
|
59
|
+
## Delivery
|
|
60
|
+
- Branch: `agent/fix-release-auto-merge`
|
|
61
|
+
- Pull request: #1680
|
|
62
|
+
- Merge: requires explicit owner approval
|
|
63
|
+
- Publication: not triggered by this implementation pull request
|
|
64
|
+
|
|
65
|
+
## Status
|
|
66
|
+
Implementation, review hardening, and static validation are complete. Delivery remains gated by pull-request CI and explicit owner merge approval; no merge or publication has been performed.
|
package/dist/core/fastypest.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/fastypest.ts"],"sourcesContent":["import { Connection, DataSource, EntityManager, Table } from \"typeorm\";\nimport type { LoggingOptions, ScopedLogger } from \"../logging\";\nimport {\n configureLogging,\n createScopedLogger,\n LOGGING_DETAIL_LEVELS,\n LOGGING_LEVEL_LABELS,\n LOGGING_LEVEL_SEQUENCE,\n LoggingDetailLevel,\n LogLevel,\n} from \"../logging\";\nimport {\n INDEX_OFFSET_CONFIG,\n MIN_SEQUENCE_VALUE_BY_TYPE,\n PARALLEL_QUERY_SUPPORT,\n} from \"./config\";\nimport { detectQueryEvents } from \"./query-mediator\";\nimport { SQLScript } from \"./sql-script\";\nimport {\n ChangeDetectionStrategy,\n type ColumnStat,\n type ColumnsWithAutoIncrement,\n type DBType,\n type DependencyTreeQueryOut,\n type FastypestOptions,\n type IncrementDetail,\n type Manager,\n type TableDependencyQueryOut,\n type TableDependencyQueryOutWithUpperCase,\n} from \"./types\";\n\nconst PROGRESS_OFFSET = 1;\n\ntype QueryExecutor = {\n query: (...args: unknown[]) => Promise<unknown>;\n};\n\ntype QueryRunnerFactory = {\n createQueryRunner: (...args: unknown[]) => QueryExecutor;\n};\n\nexport class Fastypest extends SQLScript {\n private manager: EntityManager;\n private tables: Set<string> = new Set();\n private tablesWithAutoIncrement: Map<string, IncrementDetail[]> = new Map();\n private tableDependents: Map<string, Set<string>> = new Map();\n private restoreInOder: boolean = false;\n private readonly options: Required<Omit<FastypestOptions, \"logging\">>;\n private readonly changedTables: Set<string> = new Set();\n private readonly logger: ScopedLogger;\n private readonly dbConnection: DataSource | Connection;\n private readonly patchedQueryExecutors: WeakSet<object> = new WeakSet();\n private queryTrackingPaused: boolean = false;\n private hasUnsafeMutations: boolean = false;\n private queryMediatorRegistered: boolean = false;\n\n constructor(connection: DataSource | Connection, options?: FastypestOptions) {\n super(connection.options.type);\n const loggingConfiguration = this.resolveLoggingConfiguration(\n options?.logging,\n );\n const resolvedLogging = configureLogging(loggingConfiguration);\n this.logger = createScopedLogger(\"Fastypest\");\n this.manager = connection.manager;\n this.dbConnection = connection;\n this.options = {\n changeDetectionStrategy:\n options?.changeDetectionStrategy ?? ChangeDetectionStrategy.Query,\n };\n const detailLevels =\n resolvedLogging.detail !== undefined\n ? LOGGING_DETAIL_LEVELS[resolvedLogging.detail]\n : undefined;\n const customLevels =\n resolvedLogging.levels && resolvedLogging.levels.length > 0\n ? resolvedLogging.levels\n : undefined;\n const activeLevels =\n detailLevels && customLevels\n ? customLevels.filter((level) => detailLevels.includes(level))\n : (detailLevels ?? customLevels ?? LOGGING_LEVEL_SEQUENCE);\n const activeLevelLabels = activeLevels.map(\n (level) => LOGGING_LEVEL_LABELS[level],\n );\n const detailText =\n resolvedLogging.detail !== undefined\n ? `Style ${\n resolvedLogging.detail === LoggingDetailLevel.Simple\n ? \"Simple\"\n : \"Detailed\"\n }`\n : undefined;\n const customLevelText = customLevels\n ? `Selected levels ${customLevels\n .map((level) => LOGGING_LEVEL_LABELS[level])\n .join(\", \")}`\n : undefined;\n const activeLevelText =\n detailLevels && customLevels && activeLevels.length === 0\n ? \"Active levels none\"\n : `Active levels ${activeLevelLabels.join(\", \")}`;\n const loggingDetails = [\n detailText,\n customLevelText,\n activeLevelText,\n `Database ${this.getType()}`,\n `Change detection ${this.options.changeDetectionStrategy}`,\n ].filter((entry): entry is string => Boolean(entry));\n if (resolvedLogging.enabled) {\n this.logger.log(\"🟢 Logging enabled\", ...loggingDetails);\n } else {\n this.logger.warn(\"⚪️ Logging disabled\", ...loggingDetails);\n }\n if (this.shouldTrackChanges()) {\n this.logger.info(\"🛰️ Change detection strategy enabled\");\n this.registerQueryMediator();\n }\n }\n\n public async init(): Promise<void> {\n const timer = this.logger.timer(\"Initialization\");\n this.logger.verbose(\n \"🚀 Initialization started\",\n `Database ${this.getType()}`,\n );\n await this.withQueryTrackingPaused(async () => {\n await this.manager.transaction(async (em: EntityManager) => {\n await this.detectTables(em);\n await this.detectTableDependencies(em);\n await this.calculateDependencyTables(em);\n const tables = [...this.tables];\n if (this.canRunQueriesInParallel()) {\n await Promise.all([\n this.createTempTable(em, tables),\n this.detectTablesWithAutoIncrement(em, tables),\n ]);\n } else {\n await this.createTempTable(em, tables);\n await this.detectTablesWithAutoIncrement(em, tables);\n }\n });\n });\n timer.end(\n \"✅ Initialization completed\",\n LogLevel.Info,\n `Tables ${this.tables.size}`,\n `Tables with auto increment ${this.tablesWithAutoIncrement.size}`,\n );\n }\n\n private async createTempTable(\n em: EntityManager,\n tables: string[],\n ): Promise<void> {\n const totalTables = tables.length;\n if (this.canRunQueriesInParallel()) {\n await Promise.all(\n tables.map(async (tableName, index) => {\n await this.execQuery(em, \"dropTempTable\", { tableName });\n await this.execQuery(em, \"createTempTable\", { tableName });\n this.logger.debug(\n \"🧪 Temporary table prepared\",\n `Table ${tableName}`,\n `Progress ${index + PROGRESS_OFFSET}/${totalTables}`,\n );\n }),\n );\n return;\n }\n\n for (const [index, tableName] of tables.entries()) {\n await this.execQuery(em, \"dropTempTable\", { tableName });\n await this.execQuery(em, \"createTempTable\", { tableName });\n this.logger.debug(\n \"🧪 Temporary table prepared\",\n `Table ${tableName}`,\n `Progress ${index + PROGRESS_OFFSET}/${totalTables}`,\n );\n }\n }\n\n private async detectTablesWithAutoIncrement(\n em: EntityManager,\n tables: string[],\n ): Promise<void> {\n const totalTables = tables.length;\n for (const [index, tableName] of tables.entries()) {\n await this.processTable(\n em,\n tableName,\n index + PROGRESS_OFFSET,\n totalTables,\n );\n }\n this.logger.debug(\n \"📊 Auto increment analysis completed\",\n `Tables with auto increment ${this.tablesWithAutoIncrement.size}`,\n );\n }\n\n private async processTable(\n em: EntityManager,\n tableName: string,\n position: number,\n total: number,\n ): Promise<void> {\n const columns = await this.getColumnsWithAutoIncrement(em, tableName);\n if (!columns) return;\n\n for (const column of columns) {\n await this.processColumn(em, tableName, column, position, total);\n }\n }\n\n private async getColumnsWithAutoIncrement(\n em: EntityManager,\n tableName: string,\n ): Promise<ColumnsWithAutoIncrement[] | null> {\n const columns = await this.execQuery<ColumnsWithAutoIncrement>(\n em,\n \"getColumnsWithAutoIncrement\",\n { tableName },\n );\n return Array.isArray(columns) ? columns : null;\n }\n\n private async processColumn(\n em: EntityManager,\n tableName: string,\n column: ColumnsWithAutoIncrement,\n position: number,\n total: number,\n ): Promise<void> {\n const stat = await this.getMaxColumnIndex(\n em,\n tableName,\n column.column_name,\n );\n const sequenceName = this.getSequenceName(column.column_default);\n if (!sequenceName) return;\n\n const maxIndex = Number(stat?.maxindex) || 0;\n const offset = INDEX_OFFSET_CONFIG[this.getType()] ?? 0;\n const minimumSequenceValue = MIN_SEQUENCE_VALUE_BY_TYPE[this.getType()] ?? 0;\n const index = Math.max(maxIndex + offset, minimumSequenceValue);\n this.updateTablesWithAutoIncrement(tableName, {\n column: column.column_name,\n sequenceName,\n index: String(index),\n });\n this.logger.debug(\n \"🔁 Auto increment column processed\",\n `Table ${tableName}`,\n `Column ${column.column_name}`,\n `Sequence ${sequenceName}`,\n `Progress ${position}/${total}`,\n );\n }\n\n private async getMaxColumnIndex(\n em: EntityManager,\n tableName: string,\n columnName: string,\n ): Promise<ColumnStat | null> {\n const [stat] = await this.execQuery<ColumnStat>(em, \"getMaxColumnIndex\", {\n tableName,\n column_name: columnName,\n });\n return stat || null;\n }\n\n private getSequenceName(columnDefault: string): string | null {\n return columnDefault.match(/'([^']+)'/)?.[1] || null;\n }\n\n private updateTablesWithAutoIncrement(\n tableName: string,\n data: { column: string; sequenceName: string; index: string },\n ): void {\n if (!this.tablesWithAutoIncrement.has(tableName)) {\n this.tablesWithAutoIncrement.set(tableName, []);\n }\n\n this.tablesWithAutoIncrement.get(tableName)?.push(data);\n }\n\n public async restoreData(): Promise<void> {\n const tablesToRestore = this.getTablesForRestore();\n if (\n this.shouldTrackChanges() &&\n this.changedTables.size === 0 &&\n !this.hasUnsafeMutations\n ) {\n this.logger.debug(\n \"🕊️ No tracked table changes detected\",\n `Tables ${tablesToRestore.length}`,\n );\n }\n const timer = this.logger.timer(\"Restore process\");\n const changeSummary = this.shouldTrackChanges()\n ? `Tracked changes ${this.changedTables.size}`\n : undefined;\n const unsafeSummary = this.shouldTrackChanges()\n ? `Unsafe queries ${this.hasUnsafeMutations ? \"yes\" : \"no\"}`\n : undefined;\n this.logger.verbose(\n \"🛠️ Restore process started\",\n `Tables selected ${tablesToRestore.length}`,\n changeSummary,\n unsafeSummary,\n );\n await this.withQueryTrackingPaused(async () => {\n await this.manager.transaction(async (em: EntityManager) => {\n const { foreignKey, restoreOrder } = await this.restoreManager(em);\n await foreignKey.disable();\n await restoreOrder();\n await foreignKey.enable();\n });\n });\n timer.end(\n \"🎉 Restore process completed\",\n LogLevel.Info,\n `Tables restored ${tablesToRestore.length}`,\n );\n }\n\n protected async restoreManager(em: EntityManager): Promise<Manager> {\n if (this.tables.size === 0) {\n await this.detectTables(em);\n }\n\n const manager: Manager = {\n foreignKey: {\n disable: async () => Promise.resolve(),\n enable: async () => Promise.resolve(),\n },\n restoreOrder: async () => Promise.resolve(),\n };\n\n const typesWithForeignKey: DBType[] = [\"postgres\", \"mariadb\", \"mysql\"];\n if (typesWithForeignKey.includes(this.getType())) {\n manager.foreignKey.disable = async (): Promise<void> => {\n this.logger.debug(\n \"🚧 Foreign keys disabled\",\n `Database ${this.getType()}`,\n );\n await this.execQuery(em, \"foreignKey.disable\");\n };\n manager.foreignKey.enable = async (): Promise<void> => {\n await this.execQuery(em, \"foreignKey.enable\");\n this.logger.debug(\n \"🆗 Foreign keys enabled\",\n `Database ${this.getType()}`,\n );\n };\n }\n\n manager.restoreOrder = (): Promise<void> => this.restoreOrder(em);\n\n return manager;\n }\n\n private async calculateDependencyTables(em: EntityManager): Promise<void> {\n const timer = this.logger.timer(\"Dependency planning\");\n this.logger.debug(\"🧭 Calculating dependency order for restore\");\n const dependencyTree = await this.execQuery<DependencyTreeQueryOut>(\n em,\n \"dependencyTree\",\n );\n\n if (!dependencyTree.length) {\n this.restoreInOder = false;\n timer.end(\n \"🧭 Dependency order calculated\",\n LogLevel.Debug,\n \"Mode parallel\",\n `Tables ${this.tables.size}`,\n );\n return;\n }\n\n const sortedTables = new Set(dependencyTree.map((row) => row.table_name));\n this.tables.clear();\n this.tables = sortedTables;\n this.restoreInOder = true;\n timer.end(\n \"🧭 Dependency order calculated\",\n LogLevel.Debug,\n \"Mode ordered\",\n `Tables ${this.tables.size}`,\n );\n }\n\n private async detectTables(em: EntityManager): Promise<void> {\n const timer = this.logger.timer(\"Table discovery\");\n this.logger.debug(\"🗂️ Discovering tables from database\");\n const tables = await this.execQuery<Table>(em, \"getTables\");\n if (!tables) {\n timer.end(\n \"🗂️ Table discovery completed\",\n LogLevel.Debug,\n `Tables ${this.tables.size}`,\n );\n return;\n }\n\n tables.forEach((row) => {\n this.tables.add(row.name);\n });\n timer.end(\n \"🗂️ Table discovery completed\",\n LogLevel.Debug,\n `Tables ${this.tables.size}`,\n );\n }\n\n private async detectTableDependencies(em: EntityManager): Promise<void> {\n const timer = this.logger.timer(\"Dependency mapping\");\n const dependencies = await this.execQuery<\n TableDependencyQueryOut & TableDependencyQueryOutWithUpperCase\n >(\n em,\n \"tableDependencies\",\n );\n this.tableDependents.clear();\n for (const dependency of dependencies) {\n const dependentTableName = this.getDependencyTableName(\n dependency,\n \"table_name\",\n \"TABLE_NAME\",\n );\n const referencedTableName = this.getDependencyTableName(\n dependency,\n \"referenced_table_name\",\n \"REFERENCED_TABLE_NAME\",\n );\n if (!dependentTableName || !referencedTableName) {\n this.logger.warn(\n \"⚠️ Invalid dependency row ignored\",\n `Database ${this.getType()}`,\n );\n continue;\n }\n const dependentTable = this.resolveTrackedTableName(dependentTableName);\n const referencedTable = this.resolveTrackedTableName(referencedTableName);\n if (!this.tables.has(dependentTable) || !this.tables.has(referencedTable)) {\n continue;\n }\n if (!this.tableDependents.has(referencedTable)) {\n this.tableDependents.set(referencedTable, new Set());\n }\n this.tableDependents.get(referencedTable)?.add(dependentTable);\n }\n timer.end(\n \"🧭 Dependency mapping completed\",\n LogLevel.Debug,\n `Tables with dependents ${this.tableDependents.size}`,\n );\n }\n\n private async restoreOrder(em: EntityManager): Promise<void> {\n const tables = this.getTablesForRestore();\n const orderedTables = this.sortTablesForRestore(tables);\n const totalTables = orderedTables.length;\n const useBatchTruncate = this.shouldUseBatchTruncate(orderedTables);\n const runOrderedRestore =\n this.restoreInOder || !this.canRunQueriesInParallel();\n if (useBatchTruncate) {\n await this.truncateTablesInBatch(em, orderedTables);\n }\n if (runOrderedRestore) {\n this.logger.verbose(\"🧱 Restore mode ordered\", `Tables ${totalTables}`);\n for (const [index, tableName] of orderedTables.entries()) {\n await this.recreateData(\n em,\n tableName,\n index + PROGRESS_OFFSET,\n totalTables,\n useBatchTruncate,\n );\n }\n } else {\n this.logger.verbose(\"🧱 Restore mode parallel\", `Tables ${totalTables}`);\n await Promise.all(\n orderedTables.map((tableName, index) =>\n this.recreateData(\n em,\n tableName,\n index + PROGRESS_OFFSET,\n totalTables,\n useBatchTruncate,\n ),\n ),\n );\n }\n if (this.shouldTrackChanges()) {\n this.changedTables.clear();\n this.hasUnsafeMutations = false;\n }\n }\n\n private async recreateData(\n em: EntityManager,\n tableName: string,\n position: number,\n total: number,\n skipTruncate: boolean = false,\n ): Promise<void> {\n const timer = this.logger.timer(`Restore ${tableName}`);\n this.logger.debug(\n \"📥 Restoring table\",\n `Table ${tableName}`,\n `Progress ${position}/${total}`,\n );\n if (!skipTruncate) {\n await this.execQuery(em, \"truncateTable\", { tableName });\n timer.mark(\n \"🧹 Table truncated\",\n LogLevel.Debug,\n `Table ${tableName}`,\n `Progress ${position}/${total}`,\n );\n } else {\n timer.mark(\n \"🧹 Table truncation reused\",\n LogLevel.Debug,\n `Table ${tableName}`,\n `Progress ${position}/${total}`,\n );\n }\n await this.execQuery(em, \"restoreData\", { tableName });\n timer.mark(\n \"📦 Table data restored\",\n LogLevel.Debug,\n `Table ${tableName}`,\n `Progress ${position}/${total}`,\n );\n await this.resetAutoIncrementColumns(em, tableName);\n timer.end(\n \"✅ Table restored\",\n LogLevel.Info,\n `Table ${tableName}`,\n `Progress ${position}/${total}`,\n );\n }\n\n private async resetAutoIncrementColumns(\n em: EntityManager,\n tableName: string,\n ): Promise<void> {\n const tables = this.tablesWithAutoIncrement.get(tableName);\n if (!tables) return;\n\n for (const { column, sequenceName, index } of tables) {\n await this.execQuery(em, \"resetAutoIncrementColumn\", {\n tableName,\n column,\n sequenceName,\n index,\n });\n this.logger.debug(\n \"♻️ Auto increment column reset\",\n `Table ${tableName}`,\n `Column ${column}`,\n `Sequence ${sequenceName}`,\n `Next value ${index}`,\n );\n }\n }\n\n private registerQueryMediator(): void {\n if (this.queryMediatorRegistered) {\n return;\n }\n this.patchQueryExecutor(this.dbConnection as unknown as QueryExecutor);\n this.patchQueryRunnerFactory();\n this.queryMediatorRegistered = true;\n this.logger.info(\n \"📡 Query mediator registered\",\n `Database ${this.getType()}`,\n );\n }\n\n private patchQueryRunnerFactory(): void {\n const connection = this\n .dbConnection as unknown as Partial<QueryRunnerFactory>;\n if (!connection.createQueryRunner) {\n return;\n }\n const originalCreateQueryRunner = connection.createQueryRunner.bind(\n this.dbConnection,\n );\n connection.createQueryRunner = (...args: unknown[]): QueryExecutor => {\n const queryRunner = originalCreateQueryRunner(...args);\n this.patchQueryExecutor(queryRunner);\n return queryRunner;\n };\n }\n\n private patchQueryExecutor(executor: QueryExecutor): void {\n const reference = executor as unknown as object;\n if (this.patchedQueryExecutors.has(reference)) {\n return;\n }\n const originalQuery = executor.query.bind(executor);\n executor.query = async (...args: unknown[]): Promise<unknown> => {\n const query = args[0];\n if (typeof query === \"string\") {\n this.handleExecutedQuery(query);\n }\n return await originalQuery(...args);\n };\n this.patchedQueryExecutors.add(reference);\n }\n\n private handleExecutedQuery(query: string): void {\n if (!this.shouldTrackChanges() || this.queryTrackingPaused) {\n return;\n }\n const events = detectQueryEvents(this.getType(), query);\n events.forEach((event) => {\n if (event.type === \"tableTouched\") {\n this.trackChangedTable(event.tableName);\n return;\n }\n if (event.type === \"unsupportedMutation\" && !this.hasUnsafeMutations) {\n this.hasUnsafeMutations = true;\n this.logger.warn(\n \"⚠️ Unsafe query detected, full restore enabled\",\n `Database ${this.getType()}`,\n );\n }\n });\n }\n\n private trackChangedTable(tableName: string): void {\n const normalizedTableName = this.resolveTrackedTableName(tableName);\n const wasTracked = this.changedTables.has(normalizedTableName);\n this.changedTables.add(normalizedTableName);\n if (!wasTracked) {\n this.logger.debug(\n \"🔎 Table change detected\",\n `Table ${normalizedTableName}`,\n `Tracked tables ${this.changedTables.size}`,\n );\n }\n }\n\n private shouldTrackChanges(): boolean {\n return (\n this.options.changeDetectionStrategy === ChangeDetectionStrategy.Query\n );\n }\n\n private canRunQueriesInParallel(): boolean {\n return PARALLEL_QUERY_SUPPORT[this.getType()] ?? true;\n }\n\n private getTablesForRestore(): string[] {\n const tables = [...this.tables];\n if (!this.shouldTrackChanges()) {\n return tables;\n }\n if (this.hasUnsafeMutations) {\n this.logger.warn(\n \"🛡️ Restoring all tables because unsafe queries were detected\",\n `Tables ${tables.length}`,\n );\n return tables;\n }\n if (this.changedTables.size === 0) {\n return tables;\n }\n const changedAndDependents = this.expandTablesForRestore(\n new Set(this.changedTables),\n );\n const filtered = tables.filter((table) => changedAndDependents.has(table));\n if (filtered.length === 0) {\n return tables;\n }\n this.logger.debug(\n \"🗜️ Filtering tables by tracked changes\",\n `Matched tables ${filtered.length}`,\n `Tracked tables ${this.changedTables.size}`,\n `Total tables ${tables.length}`,\n );\n return filtered;\n }\n\n private getDependencyTableName(\n dependency: TableDependencyQueryOut & TableDependencyQueryOutWithUpperCase,\n lowerCaseKey: keyof TableDependencyQueryOut,\n upperCaseKey: keyof TableDependencyQueryOutWithUpperCase,\n ): string | null {\n const rawValue = dependency[lowerCaseKey] ?? dependency[upperCaseKey];\n if (typeof rawValue !== \"string\") {\n return null;\n }\n const tableName = rawValue.trim();\n if (tableName.length === 0) {\n return null;\n }\n return tableName;\n }\n\n private resolveTrackedTableName(tableName: string | null | undefined): string {\n if (!tableName) {\n return \"\";\n }\n if (this.tables.has(tableName)) {\n return tableName;\n }\n const normalizedTableName = tableName.toLowerCase();\n for (const knownTableName of this.tables) {\n if (knownTableName.toLowerCase() === normalizedTableName) {\n return knownTableName;\n }\n }\n return tableName;\n }\n\n private expandTablesForRestore(changedTables: Set<string>): Set<string> {\n const tablesToRestore = new Set(changedTables);\n const queue = [...changedTables];\n while (queue.length > 0) {\n const current = queue.shift();\n if (!current) {\n continue;\n }\n const dependentTables = this.tableDependents.get(current);\n if (!dependentTables) {\n continue;\n }\n for (const dependentTable of dependentTables) {\n if (tablesToRestore.has(dependentTable)) {\n continue;\n }\n tablesToRestore.add(dependentTable);\n queue.push(dependentTable);\n }\n }\n return tablesToRestore;\n }\n\n private sortTablesForRestore(tables: string[]): string[] {\n if (tables.length < 2) {\n return tables;\n }\n const tableSet = new Set(tables);\n const inDegree = new Map<string, number>();\n const adjacency = new Map<string, string[]>();\n for (const table of tables) {\n inDegree.set(table, 0);\n adjacency.set(table, []);\n }\n for (const [referencedTable, dependentTables] of this.tableDependents) {\n if (!tableSet.has(referencedTable)) {\n continue;\n }\n for (const dependentTable of dependentTables) {\n if (!tableSet.has(dependentTable)) {\n continue;\n }\n adjacency.get(referencedTable)?.push(dependentTable);\n inDegree.set(dependentTable, (inDegree.get(dependentTable) ?? 0) + 1);\n }\n }\n for (const dependentTables of adjacency.values()) {\n dependentTables.sort((left, right) => left.localeCompare(right));\n }\n const queue = tables\n .filter((table) => (inDegree.get(table) ?? 0) === 0)\n .sort((left, right) => left.localeCompare(right));\n const sorted: string[] = [];\n while (queue.length > 0) {\n const tableName = queue.shift();\n if (!tableName) {\n break;\n }\n sorted.push(tableName);\n const dependentTables = adjacency.get(tableName) ?? [];\n for (const dependentTable of dependentTables) {\n const nextDegree = (inDegree.get(dependentTable) ?? 0) - 1;\n inDegree.set(dependentTable, nextDegree);\n if (nextDegree === 0) {\n queue.push(dependentTable);\n queue.sort((left, right) => left.localeCompare(right));\n }\n }\n }\n if (sorted.length !== tables.length) {\n return tables;\n }\n return sorted;\n }\n\n private shouldUseBatchTruncate(tables: string[]): boolean {\n const type = this.getType();\n return (\n (type === \"cockroachdb\" || type === \"postgres\") && tables.length > 1\n );\n }\n\n private async truncateTablesInBatch(\n em: EntityManager,\n tables: string[],\n ): Promise<void> {\n const quotedTables = tables\n .map((tableName) => `\"${tableName}\"`)\n .join(\", \");\n await em.query(`TRUNCATE TABLE ${quotedTables} CASCADE;`);\n this.logger.debug(\n \"🧹 Batch table truncation completed\",\n `Tables ${tables.length}`,\n `Database ${this.getType()}`,\n );\n }\n\n private async withQueryTrackingPaused<T>(\n callback: () => Promise<T>,\n ): Promise<T> {\n const previousTrackingState = this.queryTrackingPaused;\n this.queryTrackingPaused = true;\n try {\n return await callback();\n } finally {\n this.queryTrackingPaused = previousTrackingState;\n }\n }\n\n private resolveLoggingConfiguration(\n logging?: boolean | LoggingOptions,\n ): LoggingOptions | undefined {\n if (typeof logging === \"boolean\") {\n return { enabled: logging };\n }\n if (!logging) {\n return undefined;\n }\n if (logging.enabled === undefined) {\n return { ...logging, enabled: true };\n }\n return logging;\n }\n}\n"],"names":["Fastypest","PROGRESS_OFFSET","SQLScript","init","timer","logger","verbose","getType","withQueryTrackingPaused","manager","transaction","em","detectTables","detectTableDependencies","calculateDependencyTables","tables","canRunQueriesInParallel","Promise","all","createTempTable","detectTablesWithAutoIncrement","end","LogLevel","Info","size","tablesWithAutoIncrement","totalTables","length","map","tableName","index","execQuery","debug","entries","processTable","position","total","columns","getColumnsWithAutoIncrement","column","processColumn","Array","isArray","stat","getMaxColumnIndex","column_name","sequenceName","getSequenceName","column_default","maxIndex","Number","maxindex","offset","INDEX_OFFSET_CONFIG","minimumSequenceValue","MIN_SEQUENCE_VALUE_BY_TYPE","Math","max","updateTablesWithAutoIncrement","String","columnName","columnDefault","match","data","has","set","get","push","restoreData","tablesToRestore","getTablesForRestore","shouldTrackChanges","changedTables","hasUnsafeMutations","changeSummary","undefined","unsafeSummary","foreignKey","restoreOrder","restoreManager","disable","enable","resolve","typesWithForeignKey","includes","dependencyTree","restoreInOder","Debug","sortedTables","Set","row","table_name","clear","forEach","add","name","dependencies","tableDependents","dependency","dependentTableName","getDependencyTableName","referencedTableName","warn","dependentTable","resolveTrackedTableName","referencedTable","orderedTables","sortTablesForRestore","useBatchTruncate","shouldUseBatchTruncate","runOrderedRestore","truncateTablesInBatch","recreateData","skipTruncate","mark","resetAutoIncrementColumns","registerQueryMediator","queryMediatorRegistered","patchQueryExecutor","dbConnection","patchQueryRunnerFactory","info","connection","createQueryRunner","originalCreateQueryRunner","bind","args","queryRunner","executor","reference","patchedQueryExecutors","originalQuery","query","handleExecutedQuery","queryTrackingPaused","events","detectQueryEvents","event","type","trackChangedTable","normalizedTableName","wasTracked","options","changeDetectionStrategy","ChangeDetectionStrategy","Query","PARALLEL_QUERY_SUPPORT","changedAndDependents","expandTablesForRestore","filtered","filter","table","lowerCaseKey","upperCaseKey","rawValue","trim","toLowerCase","knownTableName","queue","current","shift","dependentTables","tableSet","inDegree","Map","adjacency","values","sort","left","right","localeCompare","sorted","nextDegree","quotedTables","join","callback","previousTrackingState","resolveLoggingConfiguration","logging","enabled","WeakSet","loggingConfiguration","resolvedLogging","configureLogging","createScopedLogger","detailLevels","detail","LOGGING_DETAIL_LEVELS","customLevels","levels","activeLevels","level","LOGGING_LEVEL_SEQUENCE","activeLevelLabels","LOGGING_LEVEL_LABELS","detailText","LoggingDetailLevel","Simple","customLevelText","activeLevelText","loggingDetails","entry","Boolean","log"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/core/fastypest.ts"],"sourcesContent":["import { Connection, DataSource, EntityManager, Table } from \"typeorm\";\nimport type { LoggingOptions, ScopedLogger } from \"../logging\";\nimport {\n configureLogging,\n createScopedLogger,\n LOGGING_DETAIL_LEVELS,\n LOGGING_LEVEL_LABELS,\n LOGGING_LEVEL_SEQUENCE,\n LoggingDetailLevel,\n LogLevel,\n} from \"../logging\";\nimport {\n INDEX_OFFSET_CONFIG,\n MIN_SEQUENCE_VALUE_BY_TYPE,\n PARALLEL_QUERY_SUPPORT,\n} from \"./config\";\nimport { detectQueryEvents } from \"./query-mediator\";\nimport { SQLScript } from \"./sql-script\";\nimport {\n ChangeDetectionStrategy,\n type ColumnStat,\n type ColumnsWithAutoIncrement,\n type DBType,\n type DependencyTreeQueryOut,\n type FastypestOptions,\n type IncrementDetail,\n type Manager,\n type TableDependencyQueryOut,\n type TableDependencyQueryOutWithUpperCase,\n} from \"./types\";\n\nconst PROGRESS_OFFSET = 1;\n\ntype QueryExecutor = {\n query: (...args: unknown[]) => Promise<unknown>;\n};\n\ntype QueryRunnerFactory = {\n createQueryRunner: (...args: unknown[]) => QueryExecutor;\n};\n\nexport class Fastypest extends SQLScript {\n private manager: EntityManager;\n private tables: Set<string> = new Set();\n private tablesWithAutoIncrement: Map<string, IncrementDetail[]> = new Map();\n private tableDependents: Map<string, Set<string>> = new Map();\n private restoreInOder: boolean = false;\n private readonly options: Required<Omit<FastypestOptions, \"logging\">>;\n private readonly changedTables: Set<string> = new Set();\n private readonly logger: ScopedLogger;\n private readonly dbConnection: DataSource | Connection;\n private readonly patchedQueryExecutors: WeakSet<object> = new WeakSet();\n private queryTrackingPaused: boolean = false;\n private hasUnsafeMutations: boolean = false;\n private queryMediatorRegistered: boolean = false;\n\n constructor(connection: DataSource | Connection, options?: FastypestOptions) {\n super(connection.options.type);\n const loggingConfiguration = this.resolveLoggingConfiguration(\n options?.logging,\n );\n const resolvedLogging = configureLogging(loggingConfiguration);\n this.logger = createScopedLogger(\"Fastypest\");\n this.manager = connection.manager;\n this.dbConnection = connection;\n this.options = {\n changeDetectionStrategy:\n options?.changeDetectionStrategy ?? ChangeDetectionStrategy.Query,\n };\n const detailLevels =\n resolvedLogging.detail !== undefined\n ? LOGGING_DETAIL_LEVELS[resolvedLogging.detail]\n : undefined;\n const customLevels =\n resolvedLogging.levels && resolvedLogging.levels.length > 0\n ? resolvedLogging.levels\n : undefined;\n const activeLevels =\n detailLevels && customLevels\n ? customLevels.filter((level) => detailLevels.includes(level))\n : (detailLevels ?? customLevels ?? LOGGING_LEVEL_SEQUENCE);\n const activeLevelLabels = activeLevels.map(\n (level) => LOGGING_LEVEL_LABELS[level],\n );\n const detailText =\n resolvedLogging.detail !== undefined\n ? `Style ${\n resolvedLogging.detail === LoggingDetailLevel.Simple\n ? \"Simple\"\n : \"Detailed\"\n }`\n : undefined;\n const customLevelText = customLevels\n ? `Selected levels ${customLevels\n .map((level) => LOGGING_LEVEL_LABELS[level])\n .join(\", \")}`\n : undefined;\n const activeLevelText =\n detailLevels && customLevels && activeLevels.length === 0\n ? \"Active levels none\"\n : `Active levels ${activeLevelLabels.join(\", \")}`;\n const loggingDetails = [\n detailText,\n customLevelText,\n activeLevelText,\n `Database ${this.getType()}`,\n `Change detection ${this.options.changeDetectionStrategy}`,\n ].filter((entry): entry is string => Boolean(entry));\n if (resolvedLogging.enabled) {\n this.logger.log(\"🟢 Logging enabled\", ...loggingDetails);\n } else {\n this.logger.warn(\"⚪️ Logging disabled\", ...loggingDetails);\n }\n if (this.shouldTrackChanges()) {\n this.logger.info(\"🛰️ Change detection strategy enabled\");\n this.registerQueryMediator();\n }\n }\n\n public async init(): Promise<void> {\n const timer = this.logger.timer(\"Initialization\");\n this.logger.verbose(\n \"🚀 Initialization started\",\n `Database ${this.getType()}`,\n );\n await this.withQueryTrackingPaused(async () => {\n await this.manager.transaction(async (em: EntityManager) => {\n await this.detectTables(em);\n await this.detectTableDependencies(em);\n await this.calculateDependencyTables(em);\n const tables = [...this.tables];\n if (this.canRunQueriesInParallel()) {\n await Promise.all([\n this.createTempTable(em, tables),\n this.detectTablesWithAutoIncrement(em, tables),\n ]);\n } else {\n await this.createTempTable(em, tables);\n await this.detectTablesWithAutoIncrement(em, tables);\n }\n });\n });\n timer.end(\n \"✅ Initialization completed\",\n LogLevel.Info,\n `Tables ${this.tables.size}`,\n `Tables with auto increment ${this.tablesWithAutoIncrement.size}`,\n );\n }\n\n private async createTempTable(\n em: EntityManager,\n tables: string[],\n ): Promise<void> {\n const totalTables = tables.length;\n if (this.canRunQueriesInParallel()) {\n await Promise.all(\n tables.map(async (tableName, index) => {\n await this.execQuery(em, \"dropTempTable\", { tableName });\n await this.execQuery(em, \"createTempTable\", { tableName });\n this.logger.debug(\n \"🧪 Temporary table prepared\",\n `Table ${tableName}`,\n `Progress ${index + PROGRESS_OFFSET}/${totalTables}`,\n );\n }),\n );\n return;\n }\n\n for (const [index, tableName] of tables.entries()) {\n await this.execQuery(em, \"dropTempTable\", { tableName });\n await this.execQuery(em, \"createTempTable\", { tableName });\n this.logger.debug(\n \"🧪 Temporary table prepared\",\n `Table ${tableName}`,\n `Progress ${index + PROGRESS_OFFSET}/${totalTables}`,\n );\n }\n }\n\n private async detectTablesWithAutoIncrement(\n em: EntityManager,\n tables: string[],\n ): Promise<void> {\n const totalTables = tables.length;\n for (const [index, tableName] of tables.entries()) {\n await this.processTable(\n em,\n tableName,\n index + PROGRESS_OFFSET,\n totalTables,\n );\n }\n this.logger.debug(\n \"📊 Auto increment analysis completed\",\n `Tables with auto increment ${this.tablesWithAutoIncrement.size}`,\n );\n }\n\n private async processTable(\n em: EntityManager,\n tableName: string,\n position: number,\n total: number,\n ): Promise<void> {\n const columns = await this.getColumnsWithAutoIncrement(em, tableName);\n if (!columns) return;\n\n for (const column of columns) {\n await this.processColumn(em, tableName, column, position, total);\n }\n }\n\n private async getColumnsWithAutoIncrement(\n em: EntityManager,\n tableName: string,\n ): Promise<ColumnsWithAutoIncrement[] | null> {\n const columns = await this.execQuery<ColumnsWithAutoIncrement>(\n em,\n \"getColumnsWithAutoIncrement\",\n { tableName },\n );\n return Array.isArray(columns) ? columns : null;\n }\n\n private async processColumn(\n em: EntityManager,\n tableName: string,\n column: ColumnsWithAutoIncrement,\n position: number,\n total: number,\n ): Promise<void> {\n const stat = await this.getMaxColumnIndex(\n em,\n tableName,\n column.column_name,\n );\n const sequenceName = this.getSequenceName(column.column_default);\n if (!sequenceName) return;\n\n const maxIndex = Number(stat?.maxindex) || 0;\n const offset = INDEX_OFFSET_CONFIG[this.getType()] ?? 0;\n const minimumSequenceValue = MIN_SEQUENCE_VALUE_BY_TYPE[this.getType()] ?? 0;\n const index = Math.max(maxIndex + offset, minimumSequenceValue);\n this.updateTablesWithAutoIncrement(tableName, {\n column: column.column_name,\n sequenceName,\n index: String(index),\n });\n this.logger.debug(\n \"🔁 Auto increment column processed\",\n `Table ${tableName}`,\n `Column ${column.column_name}`,\n `Sequence ${sequenceName}`,\n `Progress ${position}/${total}`,\n );\n }\n\n private async getMaxColumnIndex(\n em: EntityManager,\n tableName: string,\n columnName: string,\n ): Promise<ColumnStat | null> {\n const [stat] = await this.execQuery<ColumnStat>(em, \"getMaxColumnIndex\", {\n tableName,\n column_name: columnName,\n });\n return stat || null;\n }\n\n private getSequenceName(columnDefault: string): string | null {\n return columnDefault.match(/'([^']+)'/)?.[1] || null;\n }\n\n private updateTablesWithAutoIncrement(\n tableName: string,\n data: { column: string; sequenceName: string; index: string },\n ): void {\n if (!this.tablesWithAutoIncrement.has(tableName)) {\n this.tablesWithAutoIncrement.set(tableName, []);\n }\n\n this.tablesWithAutoIncrement.get(tableName)?.push(data);\n }\n\n public async restoreData(): Promise<void> {\n const tablesToRestore = this.getTablesForRestore();\n if (\n this.shouldTrackChanges() &&\n this.changedTables.size === 0 &&\n !this.hasUnsafeMutations\n ) {\n this.logger.debug(\n \"🕊️ No tracked table changes detected\",\n `Tables ${tablesToRestore.length}`,\n );\n }\n const timer = this.logger.timer(\"Restore process\");\n const changeSummary = this.shouldTrackChanges()\n ? `Tracked changes ${this.changedTables.size}`\n : undefined;\n const unsafeSummary = this.shouldTrackChanges()\n ? `Unsafe queries ${this.hasUnsafeMutations ? \"yes\" : \"no\"}`\n : undefined;\n this.logger.verbose(\n \"🛠️ Restore process started\",\n `Tables selected ${tablesToRestore.length}`,\n changeSummary,\n unsafeSummary,\n );\n await this.withQueryTrackingPaused(async () => {\n await this.manager.transaction(async (em: EntityManager) => {\n const { foreignKey, restoreOrder } = await this.restoreManager(em);\n await foreignKey.disable();\n await restoreOrder();\n await foreignKey.enable();\n });\n });\n timer.end(\n \"🎉 Restore process completed\",\n LogLevel.Info,\n `Tables restored ${tablesToRestore.length}`,\n );\n }\n\n protected async restoreManager(em: EntityManager): Promise<Manager> {\n if (this.tables.size === 0) {\n await this.detectTables(em);\n }\n\n const manager: Manager = {\n foreignKey: {\n disable: async () => Promise.resolve(),\n enable: async () => Promise.resolve(),\n },\n restoreOrder: async () => Promise.resolve(),\n };\n\n const typesWithForeignKey: DBType[] = [\"postgres\", \"mariadb\", \"mysql\"];\n if (typesWithForeignKey.includes(this.getType())) {\n manager.foreignKey.disable = async (): Promise<void> => {\n this.logger.debug(\n \"🚧 Foreign keys disabled\",\n `Database ${this.getType()}`,\n );\n await this.execQuery(em, \"foreignKey.disable\");\n };\n manager.foreignKey.enable = async (): Promise<void> => {\n await this.execQuery(em, \"foreignKey.enable\");\n this.logger.debug(\n \"🆗 Foreign keys enabled\",\n `Database ${this.getType()}`,\n );\n };\n }\n\n manager.restoreOrder = (): Promise<void> => this.restoreOrder(em);\n\n return manager;\n }\n\n private async calculateDependencyTables(em: EntityManager): Promise<void> {\n const timer = this.logger.timer(\"Dependency planning\");\n this.logger.debug(\"🧭 Calculating dependency order for restore\");\n const dependencyTree = await this.execQuery<DependencyTreeQueryOut>(\n em,\n \"dependencyTree\",\n );\n\n if (!dependencyTree.length) {\n this.restoreInOder = false;\n timer.end(\n \"🧭 Dependency order calculated\",\n LogLevel.Debug,\n \"Mode parallel\",\n `Tables ${this.tables.size}`,\n );\n return;\n }\n\n const sortedTables = new Set(dependencyTree.map((row) => row.table_name));\n this.tables.clear();\n this.tables = sortedTables;\n this.restoreInOder = true;\n timer.end(\n \"🧭 Dependency order calculated\",\n LogLevel.Debug,\n \"Mode ordered\",\n `Tables ${this.tables.size}`,\n );\n }\n\n private async detectTables(em: EntityManager): Promise<void> {\n const timer = this.logger.timer(\"Table discovery\");\n this.logger.debug(\"🗂️ Discovering tables from database\");\n const tables = await this.execQuery<Table>(em, \"getTables\");\n if (!tables) {\n timer.end(\n \"🗂️ Table discovery completed\",\n LogLevel.Debug,\n `Tables ${this.tables.size}`,\n );\n return;\n }\n\n tables.forEach((row) => {\n this.tables.add(row.name);\n });\n timer.end(\n \"🗂️ Table discovery completed\",\n LogLevel.Debug,\n `Tables ${this.tables.size}`,\n );\n }\n\n private async detectTableDependencies(em: EntityManager): Promise<void> {\n const timer = this.logger.timer(\"Dependency mapping\");\n const dependencies = await this.execQuery<\n TableDependencyQueryOut & TableDependencyQueryOutWithUpperCase\n >(\n em,\n \"tableDependencies\",\n );\n this.tableDependents.clear();\n for (const dependency of dependencies) {\n const dependentTableName = this.getDependencyTableName(\n dependency,\n \"table_name\",\n \"TABLE_NAME\",\n );\n const referencedTableName = this.getDependencyTableName(\n dependency,\n \"referenced_table_name\",\n \"REFERENCED_TABLE_NAME\",\n );\n if (!dependentTableName || !referencedTableName) {\n this.logger.warn(\n \"⚠️ Invalid dependency row ignored\",\n `Database ${this.getType()}`,\n );\n continue;\n }\n const dependentTable = this.resolveTrackedTableName(dependentTableName);\n const referencedTable = this.resolveTrackedTableName(referencedTableName);\n if (!this.tables.has(dependentTable) || !this.tables.has(referencedTable)) {\n continue;\n }\n if (!this.tableDependents.has(referencedTable)) {\n this.tableDependents.set(referencedTable, new Set());\n }\n this.tableDependents.get(referencedTable)?.add(dependentTable);\n }\n timer.end(\n \"🧭 Dependency mapping completed\",\n LogLevel.Debug,\n `Tables with dependents ${this.tableDependents.size}`,\n );\n }\n\n private async restoreOrder(em: EntityManager): Promise<void> {\n const tables = this.getTablesForRestore();\n const orderedTables = this.sortTablesForRestore(tables);\n const totalTables = orderedTables.length;\n const useBatchTruncate = this.shouldUseBatchTruncate(orderedTables);\n const runOrderedRestore =\n this.restoreInOder || !this.canRunQueriesInParallel();\n if (useBatchTruncate) {\n await this.truncateTablesInBatch(em, orderedTables);\n }\n if (runOrderedRestore) {\n this.logger.verbose(\"🧱 Restore mode ordered\", `Tables ${totalTables}`);\n for (const [index, tableName] of orderedTables.entries()) {\n await this.recreateData(\n em,\n tableName,\n index + PROGRESS_OFFSET,\n totalTables,\n useBatchTruncate,\n );\n }\n } else {\n this.logger.verbose(\"🧱 Restore mode parallel\", `Tables ${totalTables}`);\n await Promise.all(\n orderedTables.map((tableName, index) =>\n this.recreateData(\n em,\n tableName,\n index + PROGRESS_OFFSET,\n totalTables,\n useBatchTruncate,\n ),\n ),\n );\n }\n if (this.shouldTrackChanges()) {\n this.changedTables.clear();\n this.hasUnsafeMutations = false;\n }\n }\n\n private async recreateData(\n em: EntityManager,\n tableName: string,\n position: number,\n total: number,\n skipTruncate: boolean = false,\n ): Promise<void> {\n const timer = this.logger.timer(`Restore ${tableName}`);\n this.logger.debug(\n \"📥 Restoring table\",\n `Table ${tableName}`,\n `Progress ${position}/${total}`,\n );\n if (!skipTruncate) {\n await this.execQuery(em, \"truncateTable\", { tableName });\n timer.mark(\n \"🧹 Table truncated\",\n LogLevel.Debug,\n `Table ${tableName}`,\n `Progress ${position}/${total}`,\n );\n } else {\n timer.mark(\n \"🧹 Table truncation reused\",\n LogLevel.Debug,\n `Table ${tableName}`,\n `Progress ${position}/${total}`,\n );\n }\n await this.execQuery(em, \"restoreData\", { tableName });\n timer.mark(\n \"📦 Table data restored\",\n LogLevel.Debug,\n `Table ${tableName}`,\n `Progress ${position}/${total}`,\n );\n await this.resetAutoIncrementColumns(em, tableName);\n timer.end(\n \"✅ Table restored\",\n LogLevel.Info,\n `Table ${tableName}`,\n `Progress ${position}/${total}`,\n );\n }\n\n private async resetAutoIncrementColumns(\n em: EntityManager,\n tableName: string,\n ): Promise<void> {\n const tables = this.tablesWithAutoIncrement.get(tableName);\n if (!tables) return;\n\n for (const { column, sequenceName, index } of tables) {\n await this.execQuery(em, \"resetAutoIncrementColumn\", {\n tableName,\n column,\n sequenceName,\n index,\n });\n this.logger.debug(\n \"♻️ Auto increment column reset\",\n `Table ${tableName}`,\n `Column ${column}`,\n `Sequence ${sequenceName}`,\n `Next value ${index}`,\n );\n }\n }\n\n private registerQueryMediator(): void {\n if (this.queryMediatorRegistered) {\n return;\n }\n this.patchQueryExecutor(this.dbConnection as unknown as QueryExecutor);\n this.patchQueryRunnerFactory();\n this.queryMediatorRegistered = true;\n this.logger.info(\n \"📡 Query mediator registered\",\n `Database ${this.getType()}`,\n );\n }\n\n private patchQueryRunnerFactory(): void {\n const connection = this\n .dbConnection as unknown as Partial<QueryRunnerFactory>;\n if (!connection.createQueryRunner) {\n return;\n }\n const originalCreateQueryRunner = connection.createQueryRunner.bind(\n this.dbConnection,\n );\n connection.createQueryRunner = (...args: unknown[]): QueryExecutor => {\n const queryRunner = originalCreateQueryRunner(...args);\n this.patchQueryExecutor(queryRunner);\n return queryRunner;\n };\n }\n\n private patchQueryExecutor(executor: QueryExecutor): void {\n const reference = executor as unknown as object;\n if (this.patchedQueryExecutors.has(reference)) {\n return;\n }\n const originalQuery = executor.query.bind(executor);\n executor.query = async (...args: unknown[]): Promise<unknown> => {\n const query = args[0];\n if (typeof query === \"string\") {\n this.handleExecutedQuery(query);\n }\n return await originalQuery(...args);\n };\n this.patchedQueryExecutors.add(reference);\n }\n\n private handleExecutedQuery(query: string): void {\n if (!this.shouldTrackChanges() || this.queryTrackingPaused) {\n return;\n }\n const events = detectQueryEvents(this.getType(), query);\n events.forEach((event) => {\n if (event.type === \"tableTouched\") {\n this.trackChangedTable(event.tableName);\n return;\n }\n if (event.type === \"unsupportedMutation\" && !this.hasUnsafeMutations) {\n this.hasUnsafeMutations = true;\n this.logger.warn(\n \"⚠️ Unsafe query detected, full restore enabled\",\n `Database ${this.getType()}`,\n );\n }\n });\n }\n\n private trackChangedTable(tableName: string): void {\n const normalizedTableName = this.resolveTrackedTableName(tableName);\n const wasTracked = this.changedTables.has(normalizedTableName);\n this.changedTables.add(normalizedTableName);\n if (!wasTracked) {\n this.logger.debug(\n \"🔎 Table change detected\",\n `Table ${normalizedTableName}`,\n `Tracked tables ${this.changedTables.size}`,\n );\n }\n }\n\n private shouldTrackChanges(): boolean {\n return (\n this.options.changeDetectionStrategy === ChangeDetectionStrategy.Query\n );\n }\n\n private canRunQueriesInParallel(): boolean {\n return PARALLEL_QUERY_SUPPORT[this.getType()] ?? true;\n }\n\n private getTablesForRestore(): string[] {\n const tables = [...this.tables];\n if (!this.shouldTrackChanges()) {\n return tables;\n }\n if (this.hasUnsafeMutations) {\n this.logger.warn(\n \"🛡️ Restoring all tables because unsafe queries were detected\",\n `Tables ${tables.length}`,\n );\n return tables;\n }\n if (this.changedTables.size === 0) {\n return tables;\n }\n const changedAndDependents = this.expandTablesForRestore(\n new Set(this.changedTables),\n );\n const filtered = tables.filter((table) => changedAndDependents.has(table));\n if (filtered.length === 0) {\n return tables;\n }\n this.logger.debug(\n \"🗜️ Filtering tables by tracked changes\",\n `Matched tables ${filtered.length}`,\n `Tracked tables ${this.changedTables.size}`,\n `Total tables ${tables.length}`,\n );\n return filtered;\n }\n\n private getDependencyTableName(\n dependency: TableDependencyQueryOut & TableDependencyQueryOutWithUpperCase,\n lowerCaseKey: keyof TableDependencyQueryOut,\n upperCaseKey: keyof TableDependencyQueryOutWithUpperCase,\n ): string | null {\n const rawValue = dependency[lowerCaseKey] ?? dependency[upperCaseKey];\n if (typeof rawValue !== \"string\") {\n return null;\n }\n const tableName = rawValue.trim();\n if (tableName.length === 0) {\n return null;\n }\n return tableName;\n }\n\n private resolveTrackedTableName(tableName: string | null | undefined): string {\n if (!tableName) {\n return \"\";\n }\n if (this.tables.has(tableName)) {\n return tableName;\n }\n const normalizedTableName = tableName.toLowerCase();\n for (const knownTableName of this.tables) {\n if (knownTableName.toLowerCase() === normalizedTableName) {\n return knownTableName;\n }\n }\n return tableName;\n }\n\n private expandTablesForRestore(changedTables: Set<string>): Set<string> {\n const tablesToRestore = new Set(changedTables);\n const queue = [...changedTables];\n while (queue.length > 0) {\n const current = queue.shift();\n if (!current) {\n continue;\n }\n const dependentTables = this.tableDependents.get(current);\n if (!dependentTables) {\n continue;\n }\n for (const dependentTable of dependentTables) {\n if (tablesToRestore.has(dependentTable)) {\n continue;\n }\n tablesToRestore.add(dependentTable);\n queue.push(dependentTable);\n }\n }\n return tablesToRestore;\n }\n\n private sortTablesForRestore(tables: string[]): string[] {\n if (tables.length < 2) {\n return tables;\n }\n const tableSet = new Set(tables);\n const inDegree = new Map<string, number>();\n const adjacency = new Map<string, string[]>();\n for (const table of tables) {\n inDegree.set(table, 0);\n adjacency.set(table, []);\n }\n for (const [referencedTable, dependentTables] of this.tableDependents) {\n if (!tableSet.has(referencedTable)) {\n continue;\n }\n for (const dependentTable of dependentTables) {\n if (!tableSet.has(dependentTable)) {\n continue;\n }\n adjacency.get(referencedTable)?.push(dependentTable);\n inDegree.set(dependentTable, (inDegree.get(dependentTable) ?? 0) + 1);\n }\n }\n for (const dependentTables of adjacency.values()) {\n dependentTables.sort((left, right) => left.localeCompare(right));\n }\n const queue = tables\n .filter((table) => (inDegree.get(table) ?? 0) === 0)\n .sort((left, right) => left.localeCompare(right));\n const sorted: string[] = [];\n while (queue.length > 0) {\n const tableName = queue.shift();\n if (!tableName) {\n break;\n }\n sorted.push(tableName);\n const dependentTables = adjacency.get(tableName) ?? [];\n for (const dependentTable of dependentTables) {\n const nextDegree = (inDegree.get(dependentTable) ?? 0) - 1;\n inDegree.set(dependentTable, nextDegree);\n if (nextDegree === 0) {\n queue.push(dependentTable);\n queue.sort((left, right) => left.localeCompare(right));\n }\n }\n }\n if (sorted.length !== tables.length) {\n return tables;\n }\n return sorted;\n }\n\n private shouldUseBatchTruncate(tables: string[]): boolean {\n const type = this.getType();\n return (\n (type === \"cockroachdb\" || type === \"postgres\") && tables.length > 1\n );\n }\n\n private async truncateTablesInBatch(\n em: EntityManager,\n tables: string[],\n ): Promise<void> {\n const quotedTables = tables\n .map((tableName) => `\"${tableName}\"`)\n .join(\", \");\n await em.query(`TRUNCATE TABLE ${quotedTables} CASCADE;`);\n this.logger.debug(\n \"🧹 Batch table truncation completed\",\n `Tables ${tables.length}`,\n `Database ${this.getType()}`,\n );\n }\n\n private async withQueryTrackingPaused<T>(\n callback: () => Promise<T>,\n ): Promise<T> {\n const previousTrackingState = this.queryTrackingPaused;\n this.queryTrackingPaused = true;\n try {\n return await callback();\n } finally {\n this.queryTrackingPaused = previousTrackingState;\n }\n }\n\n private resolveLoggingConfiguration(\n logging?: boolean | LoggingOptions,\n ): LoggingOptions | undefined {\n if (typeof logging === \"boolean\") {\n return { enabled: logging };\n }\n if (!logging) {\n return undefined;\n }\n if (logging.enabled === undefined) {\n return { ...logging, enabled: true };\n }\n return logging;\n }\n}\n"],"names":["Fastypest","PROGRESS_OFFSET","SQLScript","init","timer","logger","verbose","getType","withQueryTrackingPaused","manager","transaction","em","detectTables","detectTableDependencies","calculateDependencyTables","tables","canRunQueriesInParallel","Promise","all","createTempTable","detectTablesWithAutoIncrement","end","LogLevel","Info","size","tablesWithAutoIncrement","totalTables","length","map","tableName","index","execQuery","debug","entries","processTable","position","total","columns","getColumnsWithAutoIncrement","column","processColumn","Array","isArray","stat","getMaxColumnIndex","column_name","sequenceName","getSequenceName","column_default","maxIndex","Number","maxindex","offset","INDEX_OFFSET_CONFIG","minimumSequenceValue","MIN_SEQUENCE_VALUE_BY_TYPE","Math","max","updateTablesWithAutoIncrement","String","columnName","columnDefault","match","data","has","set","get","push","restoreData","tablesToRestore","getTablesForRestore","shouldTrackChanges","changedTables","hasUnsafeMutations","changeSummary","undefined","unsafeSummary","foreignKey","restoreOrder","restoreManager","disable","enable","resolve","typesWithForeignKey","includes","dependencyTree","restoreInOder","Debug","sortedTables","Set","row","table_name","clear","forEach","add","name","dependencies","tableDependents","dependency","dependentTableName","getDependencyTableName","referencedTableName","warn","dependentTable","resolveTrackedTableName","referencedTable","orderedTables","sortTablesForRestore","useBatchTruncate","shouldUseBatchTruncate","runOrderedRestore","truncateTablesInBatch","recreateData","skipTruncate","mark","resetAutoIncrementColumns","registerQueryMediator","queryMediatorRegistered","patchQueryExecutor","dbConnection","patchQueryRunnerFactory","info","connection","createQueryRunner","originalCreateQueryRunner","bind","args","queryRunner","executor","reference","patchedQueryExecutors","originalQuery","query","handleExecutedQuery","queryTrackingPaused","events","detectQueryEvents","event","type","trackChangedTable","normalizedTableName","wasTracked","options","changeDetectionStrategy","ChangeDetectionStrategy","Query","PARALLEL_QUERY_SUPPORT","changedAndDependents","expandTablesForRestore","filtered","filter","table","lowerCaseKey","upperCaseKey","rawValue","trim","toLowerCase","knownTableName","queue","current","shift","dependentTables","tableSet","inDegree","Map","adjacency","values","sort","left","right","localeCompare","sorted","nextDegree","quotedTables","join","callback","previousTrackingState","resolveLoggingConfiguration","logging","enabled","WeakSet","loggingConfiguration","resolvedLogging","configureLogging","createScopedLogger","detailLevels","detail","LOGGING_DETAIL_LEVELS","customLevels","levels","activeLevels","level","LOGGING_LEVEL_SEQUENCE","activeLevelLabels","LOGGING_LEVEL_LABELS","detailText","LoggingDetailLevel","Simple","customLevelText","activeLevelText","loggingDetails","entry","Boolean","log"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/sql-script/sql-script.ts"],"sourcesContent":["import { DataSourceOptions, EntityManager } from \"typeorm\";\nimport { createScopedLogger } from \"../../logging\";\nimport { AllowedDataBases, DB_QUERIES, Queries } from \"./queries\";\nimport { QueryPath } from \"./types\";\n\ntype DBTypes = DataSourceOptions[\"type\"];\n\nexport class SQLScript {\n private queries: Queries;\n private readonly scriptLogger = createScopedLogger(\"SQLScript\");\n\n protected constructor(private readonly type: DBTypes) {\n if (!(this.type in DB_QUERIES)) {\n throw new Error(\n `The database type provided is not supported. Please choose from the following: ${Object.keys(\n DB_QUERIES,\n )}`,\n );\n }\n\n this.queries = DB_QUERIES[this.type as AllowedDataBases];\n }\n\n protected getType(): DBTypes {\n return this.type;\n }\n\n protected execQuery<T = void>(\n em: EntityManager,\n queryPath: QueryPath<Queries>,\n values?: Record<string, string>,\n ): T extends void ? Promise<void> : Promise<T[]> {\n const queryObj = queryPath\n .split(\".\")\n .reduce((obj: any, key) => obj[key], this.queries);\n\n let query = queryObj;\n\n if (values) {\n for (const key in values) {\n query = query.replace(\n new RegExp(`{{\\\\s*${key}\\\\s*}}`, \"g\"),\n values[key],\n );\n }\n }\n\n const parameterEntries = values\n ? Object.entries(values).map(([key, value]) => `${key}=${value}`)\n : [];\n this.scriptLogger.debug(\n \"Executing SQL query\",\n `Path ${queryPath}`,\n parameterEntries.length > 0\n ? `Parameters ${parameterEntries.join(\", \")}`\n : undefined,\n );\n return em.query(query) as T extends void ? Promise<void> : Promise<T[]>;\n }\n}\n"],"names":["SQLScript","getType","type","execQuery","em","queryPath","values","queryObj","split","reduce","obj","key","queries","query","replace","RegExp","parameterEntries","Object","entries","map","value","scriptLogger","debug","length","join","undefined","createScopedLogger","DB_QUERIES","Error","keys"],"mappings":";;;;+BAOaA;;;eAAAA;;;yBANsB;yBACmB
|
|
1
|
+
{"version":3,"sources":["../../../src/core/sql-script/sql-script.ts"],"sourcesContent":["import { DataSourceOptions, EntityManager } from \"typeorm\";\nimport { createScopedLogger } from \"../../logging\";\nimport { AllowedDataBases, DB_QUERIES, Queries } from \"./queries\";\nimport { QueryPath } from \"./types\";\n\ntype DBTypes = DataSourceOptions[\"type\"];\n\nexport class SQLScript {\n private queries: Queries;\n private readonly scriptLogger = createScopedLogger(\"SQLScript\");\n\n protected constructor(private readonly type: DBTypes) {\n if (!(this.type in DB_QUERIES)) {\n throw new Error(\n `The database type provided is not supported. Please choose from the following: ${Object.keys(\n DB_QUERIES,\n )}`,\n );\n }\n\n this.queries = DB_QUERIES[this.type as AllowedDataBases];\n }\n\n protected getType(): DBTypes {\n return this.type;\n }\n\n protected execQuery<T = void>(\n em: EntityManager,\n queryPath: QueryPath<Queries>,\n values?: Record<string, string>,\n ): T extends void ? Promise<void> : Promise<T[]> {\n const queryObj = queryPath\n .split(\".\")\n .reduce((obj: any, key) => obj[key], this.queries);\n\n let query = queryObj;\n\n if (values) {\n for (const key in values) {\n query = query.replace(\n new RegExp(`{{\\\\s*${key}\\\\s*}}`, \"g\"),\n values[key],\n );\n }\n }\n\n const parameterEntries = values\n ? Object.entries(values).map(([key, value]) => `${key}=${value}`)\n : [];\n this.scriptLogger.debug(\n \"Executing SQL query\",\n `Path ${queryPath}`,\n parameterEntries.length > 0\n ? `Parameters ${parameterEntries.join(\", \")}`\n : undefined,\n );\n return em.query(query) as T extends void ? Promise<void> : Promise<T[]>;\n }\n}\n"],"names":["SQLScript","getType","type","execQuery","em","queryPath","values","queryObj","split","reduce","obj","key","queries","query","replace","RegExp","parameterEntries","Object","entries","map","value","scriptLogger","debug","length","join","undefined","createScopedLogger","DB_QUERIES","Error","keys"],"mappings":";;;;+BAOaA;;;eAAAA;;;yBANsB;yBACmB;;;;;;;;;;;;AAK/C,MAAMA;IAgBDC,UAAmB;QAC3B,OAAO,IAAI,CAACC,IAAI;IAClB;IAEUC,UACRC,EAAiB,EACjBC,SAA6B,EAC7BC,MAA+B,EACgB;QAC/C,MAAMC,WAAWF,UACdG,KAAK,CAAC,KACNC,MAAM,CAAC,CAACC,KAAUC,MAAQD,GAAG,CAACC,IAAI,EAAE,IAAI,CAACC,OAAO;QAEnD,IAAIC,QAAQN;QAEZ,IAAID,QAAQ;YACV,IAAK,MAAMK,OAAOL,OAAQ;gBACxBO,QAAQA,MAAMC,OAAO,CACnB,IAAIC,OAAO,CAAC,MAAM,EAAEJ,IAAI,MAAM,CAAC,EAAE,MACjCL,MAAM,CAACK,IAAI;YAEf;QACF;QAEA,MAAMK,mBAAmBV,SACrBW,OAAOC,OAAO,CAACZ,QAAQa,GAAG,CAAC,CAAC,CAACR,KAAKS,MAAM,GAAK,GAAGT,IAAI,CAAC,EAAES,OAAO,IAC9D,EAAE;QACN,IAAI,CAACC,YAAY,CAACC,KAAK,CACrB,uBACA,CAAC,KAAK,EAAEjB,WAAW,EACnBW,iBAAiBO,MAAM,GAAG,IACtB,CAAC,WAAW,EAAEP,iBAAiBQ,IAAI,CAAC,OAAO,GAC3CC;QAEN,OAAOrB,GAAGS,KAAK,CAACA;IAClB;IA/CA,YAAsB,AAAiBX,IAAa,CAAE;;QAHtD,uBAAQU,WAAR,KAAA;QACA,uBAAiBS,gBAAjB,KAAA;aAEuCnB,OAAAA;aAFtBmB,eAAeK,IAAAA,2BAAkB,EAAC;QAGjD,IAAI,CAAE,CAAA,IAAI,CAACxB,IAAI,IAAIyB,mBAAU,AAAD,GAAI;YAC9B,MAAM,IAAIC,MACR,CAAC,+EAA+E,EAAEX,OAAOY,IAAI,CAC3FF,mBAAU,GACT;QAEP;QAEA,IAAI,CAACf,OAAO,GAAGe,mBAAU,CAAC,IAAI,CAACzB,IAAI,CAAqB;IAC1D;AAsCF"}
|
package/dist/logging/logger.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/logging/logger.ts"],"sourcesContent":["import { performance } from \"node:perf_hooks\";\nimport { addColors, createLogger, format, transports } from \"winston\";\nimport {\n LOGGING_COLORS,\n LOGGING_DEFAULT_ENABLED,\n LOGGING_DETAIL_LEVELS,\n LOGGING_LEVEL_ICONS,\n LOGGING_LEVEL_LABELS,\n LOGGING_LEVEL_WEIGHTS,\n LOGGING_TIMESTAMP_FORMAT,\n LogLevel,\n LoggingDetailLevel,\n type LoggingOptions,\n type ResolvedLoggingOptions,\n} from \"./constants\";\n\nconst LOG_FIELD_LABEL = \"label\";\nconst LOG_FIELD_MESSAGE = \"message\";\nconst LOG_FIELD_LEVEL = \"level\";\nconst LOG_FIELD_TIMESTAMP = \"timestamp\";\nconst LOG_FIELD_DETAILS = \"details\";\nconst ANSI_ESCAPE_PATTERN = /\\u001b\\[[0-9;]*m/g;\nconst DETAIL_SEPARATOR = \" · \";\nconst DETAIL_PREFIX = \" — \";\nconst MILLISECONDS_IN_SECOND = 1000;\nconst SECONDS_IN_MINUTE = 60;\nconst MINUTES_IN_HOUR = 60;\nconst MILLISECONDS_IN_MINUTE = MILLISECONDS_IN_SECOND * SECONDS_IN_MINUTE;\nconst MILLISECONDS_IN_HOUR = MILLISECONDS_IN_MINUTE * MINUTES_IN_HOUR;\nconst DECIMAL_PRECISION_SHORT = 2;\nconst DECIMAL_PRECISION_LONG = 1;\nconst LOGGING_LEVELS_KEY: keyof LoggingOptions = \"levels\";\nconst LOGGING_DETAIL_KEY: keyof LoggingOptions = \"detail\";\n\nconst formatDetailValue = (detail: LogDetail): string | undefined => {\n if (detail === undefined) {\n return undefined;\n }\n if (detail === null) {\n return \"null\";\n }\n if (detail instanceof Date) {\n return detail.toISOString();\n }\n if (detail instanceof Error) {\n return detail.message;\n }\n if (typeof detail === \"boolean\") {\n return detail ? \"yes\" : \"no\";\n }\n return String(detail);\n};\n\nconst trimDecimals = (value: number): string => {\n if (Number.isInteger(value)) {\n return value.toString();\n }\n return value.toString();\n};\n\nconst formatSeconds = (seconds: number): string => {\n const precision =\n seconds < 10 ? DECIMAL_PRECISION_SHORT : DECIMAL_PRECISION_LONG;\n const rounded = Number(seconds.toFixed(precision));\n return `${trimDecimals(rounded)}s`;\n};\n\nconst formatDurationText = (durationMs: number): string => {\n if (durationMs <= 0) {\n return \"0ms\";\n }\n const segments: string[] = [];\n const hours = Math.floor(durationMs / MILLISECONDS_IN_HOUR);\n let remaining = durationMs - hours * MILLISECONDS_IN_HOUR;\n const minutes = Math.floor(remaining / MILLISECONDS_IN_MINUTE);\n remaining -= minutes * MILLISECONDS_IN_MINUTE;\n const seconds = remaining / MILLISECONDS_IN_SECOND;\n const wholeSeconds = Math.floor(seconds);\n const leftoverMs = Math.round(\n remaining - wholeSeconds * MILLISECONDS_IN_SECOND,\n );\n\n if (hours > 0) {\n segments.push(`${hours}h`);\n }\n if (minutes > 0) {\n segments.push(`${minutes}m`);\n }\n if (hours > 0 || minutes > 0) {\n if (wholeSeconds > 0) {\n segments.push(`${wholeSeconds}s`);\n }\n if (segments.length === 0 || leftoverMs > 0) {\n if (leftoverMs > 0) {\n segments.push(`${leftoverMs}ms`);\n }\n }\n } else if (seconds >= 1) {\n segments.push(formatSeconds(seconds));\n } else {\n segments.push(`${Math.round(durationMs)}ms`);\n }\n return segments.join(\" \");\n};\n\ntype LogDetail =\n | string\n | number\n | boolean\n | bigint\n | Date\n | Error\n | null\n | undefined;\n\ntype LogDetailsInput = LogDetail | LogDetail[];\n\ntype LoggerInfo = Record<string, unknown> & {\n level: string;\n message: string;\n [LOG_FIELD_DETAILS]?: string;\n};\n\ntype LoggerPayload = LoggerInfo & {\n [LOG_FIELD_LABEL]: string;\n};\n\ntype TimerEmitter = (\n level: LogLevel,\n message: string,\n details: LogDetail[],\n) => void;\n\nconst extractLevel = (info: LoggerInfo): LogLevel | undefined => {\n const levelText = (info[LOG_FIELD_LEVEL] as string | undefined) ?? info.level;\n if (!levelText) {\n return undefined;\n }\n const normalized = levelText.replace(ANSI_ESCAPE_PATTERN, \"\").toLowerCase();\n return normalized in LOGGING_LEVEL_WEIGHTS\n ? (normalized as LogLevel)\n : undefined;\n};\n\nconst formatDetails = (details: LogDetail[]): string | undefined => {\n const formatted = details\n .map((detail) => formatDetailValue(detail))\n .filter((value): value is string => Boolean(value && value.length > 0));\n if (formatted.length === 0) {\n return undefined;\n }\n return formatted.join(DETAIL_SEPARATOR);\n};\n\nconst formatLogMessage = (info: LoggerInfo): string => {\n const label = info[LOG_FIELD_LABEL] as string | undefined;\n const timestamp = info[LOG_FIELD_TIMESTAMP] as string | undefined;\n const level = extractLevel(info);\n const fallbackLevel = info.level\n .replace(ANSI_ESCAPE_PATTERN, \"\")\n .toUpperCase();\n const message = info[LOG_FIELD_MESSAGE]\n ? String(info[LOG_FIELD_MESSAGE])\n : info.message;\n const levelLabel = level ? LOGGING_LEVEL_LABELS[level] : fallbackLevel;\n const levelIcon = level ? `${LOGGING_LEVEL_ICONS[level]} ` : \"\";\n const detailText = info[LOG_FIELD_DETAILS]\n ? String(info[LOG_FIELD_DETAILS])\n : \"\";\n const formattedDetails = detailText ? `${DETAIL_PREFIX}${detailText}` : \"\";\n const timestampText = timestamp ? `${timestamp} ` : \"\";\n return `${timestampText}${levelIcon}[${label ?? \"\"}] ${levelLabel} ${message}${formattedDetails}`;\n};\n\naddColors(LOGGING_COLORS);\n\nconst baseLogger = createLogger({\n levels: LOGGING_LEVEL_WEIGHTS,\n level: LogLevel.Verbose,\n format: format.combine(\n format.timestamp({ format: LOGGING_TIMESTAMP_FORMAT }),\n format.colorize({ all: true }),\n format.printf((info: unknown) => formatLogMessage(info as LoggerInfo)),\n ),\n transports: [new transports.Console()],\n silent: false,\n});\n\nlet globalOptions: ResolvedLoggingOptions = {\n enabled: LOGGING_DEFAULT_ENABLED,\n levels: undefined,\n detail: undefined,\n};\n\nconst resolveEnabled = (\n enabled: boolean | undefined,\n hasOptions: boolean,\n): boolean => {\n if (enabled !== undefined) {\n return enabled;\n }\n if (hasOptions) {\n return true;\n }\n return LOGGING_DEFAULT_ENABLED;\n};\n\nconst normalizeLevels = (levels?: LogLevel[]): LogLevel[] | undefined => {\n if (!levels || levels.length === 0) {\n return undefined;\n }\n const unique = Array.from(new Set(levels));\n return unique.length > 0 ? unique : undefined;\n};\n\nconst hasLevelsOption = (options?: LoggingOptions): boolean => {\n if (!options) {\n return false;\n }\n return Object.prototype.hasOwnProperty.call(options, LOGGING_LEVELS_KEY);\n};\n\nconst resolveLoggingOptions = (\n options?: LoggingOptions,\n): ResolvedLoggingOptions => {\n const hasOptions = Boolean(options);\n const enabled = resolveEnabled(options?.enabled, hasOptions);\n if (!enabled) {\n return { enabled, levels: undefined, detail: undefined };\n }\n return {\n enabled,\n levels: normalizeLevels(options?.levels),\n detail: options?.detail,\n };\n};\n\nconst getDetailLevels = (\n detail: LoggingDetailLevel | undefined,\n): LogLevel[] | undefined => {\n if (!detail) {\n return undefined;\n }\n return LOGGING_DETAIL_LEVELS[detail];\n};\n\nconst shouldLog = (\n level: LogLevel,\n options: ResolvedLoggingOptions,\n): boolean => {\n if (!options.enabled) {\n return false;\n }\n const detailLevels = getDetailLevels(options.detail);\n const hasDetailFilter = detailLevels && detailLevels.length > 0;\n const hasLevelFilter = options.levels && options.levels.length > 0;\n if (!hasDetailFilter && !hasLevelFilter) {\n return true;\n }\n if (hasDetailFilter && !detailLevels!.includes(level)) {\n return false;\n }\n if (hasLevelFilter && !options.levels!.includes(level)) {\n return false;\n }\n return true;\n};\n\nconst mergeOptions = (local?: LoggingOptions): ResolvedLoggingOptions => {\n if (!local) {\n return globalOptions;\n }\n const resolvedLocal = resolveLoggingOptions(local);\n const hasLocalLevels = hasLevelsOption(local);\n const hasLocalDetail = Object.prototype.hasOwnProperty.call(\n local,\n LOGGING_DETAIL_KEY,\n );\n const ignoreGlobalLevels = hasLocalDetail && !hasLocalLevels;\n return {\n enabled: resolvedLocal.enabled,\n levels: hasLocalLevels\n ? resolvedLocal.levels\n : ignoreGlobalLevels\n ? undefined\n : globalOptions.levels,\n detail: hasLocalDetail ? resolvedLocal.detail : globalOptions.detail,\n };\n};\n\nconst normalizeDetails = (input: LogDetailsInput[]): LogDetail[] => {\n return input.flatMap((entry) => {\n if (Array.isArray(entry)) {\n return entry;\n }\n return [entry];\n });\n};\n\nconst logWithDetails = (\n level: LogLevel,\n scope: string,\n message: string,\n details: LogDetail[],\n options: ResolvedLoggingOptions,\n): void => {\n if (!shouldLog(level, options)) {\n return;\n }\n const formattedDetails = formatDetails(details);\n const logPayload: LoggerPayload = {\n level,\n message,\n [LOG_FIELD_LABEL]: scope,\n };\n if (formattedDetails) {\n logPayload[LOG_FIELD_DETAILS] = formattedDetails;\n }\n baseLogger.log(logPayload);\n};\n\nexport const configureLogging = (\n options?: LoggingOptions,\n): ResolvedLoggingOptions => {\n globalOptions = resolveLoggingOptions(options);\n return globalOptions;\n};\n\nclass LoggerTimer {\n private readonly start = performance.now();\n private lastMark = this.start;\n private finished = false;\n\n constructor(\n private readonly label: string,\n private readonly emit: TimerEmitter,\n ) {}\n\n public mark(\n message: string,\n level: LogLevel = LogLevel.Debug,\n ...details: LogDetailsInput[]\n ): void {\n if (this.finished) {\n return;\n }\n const now = performance.now();\n const totalElapsed = now - this.start;\n const segmentElapsed = now - this.lastMark;\n this.lastMark = now;\n const timerDetails: LogDetail[] = [\n `${this.label} total ${formatDurationText(totalElapsed)}`,\n ];\n if (segmentElapsed > 0 && segmentElapsed !== totalElapsed) {\n timerDetails.push(`segment ${formatDurationText(segmentElapsed)}`);\n }\n const normalized = normalizeDetails(details);\n this.emit(level, message, [...timerDetails, ...normalized]);\n }\n\n public end(\n message?: string,\n level: LogLevel = LogLevel.Info,\n ...details: LogDetailsInput[]\n ): void {\n if (this.finished) {\n return;\n }\n const totalElapsed = performance.now() - this.start;\n const normalized = normalizeDetails(details);\n const timerDetails: LogDetail[] = [\n `${this.label} total ${formatDurationText(totalElapsed)}`,\n ];\n this.emit(level, message ?? `${this.label} completed`, [\n ...timerDetails,\n ...normalized,\n ]);\n this.finished = true;\n }\n}\n\nexport class ScopedLogger {\n constructor(\n private readonly scope: string,\n private readonly localOptions?: LoggingOptions,\n ) {}\n\n public error(message: string, ...details: LogDetailsInput[]): void {\n this.write(LogLevel.Error, message, details);\n }\n\n public warn(message: string, ...details: LogDetailsInput[]): void {\n this.write(LogLevel.Warn, message, details);\n }\n\n public log(message: string, ...details: LogDetailsInput[]): void {\n this.write(LogLevel.Log, message, details);\n }\n\n public info(message: string, ...details: LogDetailsInput[]): void {\n this.write(LogLevel.Info, message, details);\n }\n\n public debug(message: string, ...details: LogDetailsInput[]): void {\n this.write(LogLevel.Debug, message, details);\n }\n\n public verbose(message: string, ...details: LogDetailsInput[]): void {\n this.write(LogLevel.Verbose, message, details);\n }\n\n public timer(label: string): LoggerTimer {\n return new LoggerTimer(label, (level, message, details) => {\n this.write(level, message, details);\n });\n }\n\n public formatDuration(durationMs: number): string {\n return formatDurationText(durationMs);\n }\n\n private write(\n level: LogLevel,\n message: string,\n details: LogDetailsInput[],\n ): void {\n const normalized = normalizeDetails(details);\n logWithDetails(\n level,\n this.scope,\n message,\n normalized,\n mergeOptions(this.localOptions),\n );\n }\n}\n\nexport const createScopedLogger = (\n scope: string,\n options?: LoggingOptions,\n): ScopedLogger => new ScopedLogger(scope, options);\n\nexport const getLoggingOptions = (): ResolvedLoggingOptions => ({\n ...globalOptions,\n levels: globalOptions.levels ? [...globalOptions.levels] : undefined,\n});\n"],"names":["ScopedLogger","configureLogging","createScopedLogger","getLoggingOptions","LOG_FIELD_LABEL","LOG_FIELD_MESSAGE","LOG_FIELD_LEVEL","LOG_FIELD_TIMESTAMP","LOG_FIELD_DETAILS","ANSI_ESCAPE_PATTERN","DETAIL_SEPARATOR","DETAIL_PREFIX","MILLISECONDS_IN_SECOND","SECONDS_IN_MINUTE","MINUTES_IN_HOUR","MILLISECONDS_IN_MINUTE","MILLISECONDS_IN_HOUR","DECIMAL_PRECISION_SHORT","DECIMAL_PRECISION_LONG","LOGGING_LEVELS_KEY","LOGGING_DETAIL_KEY","formatDetailValue","detail","undefined","Date","toISOString","Error","message","String","trimDecimals","value","Number","isInteger","toString","formatSeconds","seconds","precision","rounded","toFixed","formatDurationText","durationMs","segments","hours","Math","floor","remaining","minutes","wholeSeconds","leftoverMs","round","push","length","join","extractLevel","info","levelText","level","normalized","replace","toLowerCase","LOGGING_LEVEL_WEIGHTS","formatDetails","details","formatted","map","filter","Boolean","formatLogMessage","label","timestamp","fallbackLevel","toUpperCase","levelLabel","LOGGING_LEVEL_LABELS","levelIcon","LOGGING_LEVEL_ICONS","detailText","formattedDetails","timestampText","addColors","LOGGING_COLORS","baseLogger","createLogger","levels","LogLevel","Verbose","format","combine","LOGGING_TIMESTAMP_FORMAT","colorize","all","printf","transports","Console","silent","globalOptions","enabled","LOGGING_DEFAULT_ENABLED","resolveEnabled","hasOptions","normalizeLevels","unique","Array","from","Set","hasLevelsOption","options","Object","prototype","hasOwnProperty","call","resolveLoggingOptions","getDetailLevels","LOGGING_DETAIL_LEVELS","shouldLog","detailLevels","hasDetailFilter","hasLevelFilter","includes","mergeOptions","local","resolvedLocal","hasLocalLevels","hasLocalDetail","ignoreGlobalLevels","normalizeDetails","input","flatMap","entry","isArray","logWithDetails","scope","logPayload","log","LoggerTimer","mark","Debug","finished","now","performance","totalElapsed","start","segmentElapsed","lastMark","timerDetails","emit","end","Info","error","write","warn","Warn","Log","debug","verbose","timer","formatDuration","localOptions"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/logging/logger.ts"],"sourcesContent":["import { performance } from \"node:perf_hooks\";\nimport { addColors, createLogger, format, transports } from \"winston\";\nimport {\n LOGGING_COLORS,\n LOGGING_DEFAULT_ENABLED,\n LOGGING_DETAIL_LEVELS,\n LOGGING_LEVEL_ICONS,\n LOGGING_LEVEL_LABELS,\n LOGGING_LEVEL_WEIGHTS,\n LOGGING_TIMESTAMP_FORMAT,\n LogLevel,\n LoggingDetailLevel,\n type LoggingOptions,\n type ResolvedLoggingOptions,\n} from \"./constants\";\n\nconst LOG_FIELD_LABEL = \"label\";\nconst LOG_FIELD_MESSAGE = \"message\";\nconst LOG_FIELD_LEVEL = \"level\";\nconst LOG_FIELD_TIMESTAMP = \"timestamp\";\nconst LOG_FIELD_DETAILS = \"details\";\nconst ANSI_ESCAPE_PATTERN = /\\u001b\\[[0-9;]*m/g;\nconst DETAIL_SEPARATOR = \" · \";\nconst DETAIL_PREFIX = \" — \";\nconst MILLISECONDS_IN_SECOND = 1000;\nconst SECONDS_IN_MINUTE = 60;\nconst MINUTES_IN_HOUR = 60;\nconst MILLISECONDS_IN_MINUTE = MILLISECONDS_IN_SECOND * SECONDS_IN_MINUTE;\nconst MILLISECONDS_IN_HOUR = MILLISECONDS_IN_MINUTE * MINUTES_IN_HOUR;\nconst DECIMAL_PRECISION_SHORT = 2;\nconst DECIMAL_PRECISION_LONG = 1;\nconst LOGGING_LEVELS_KEY: keyof LoggingOptions = \"levels\";\nconst LOGGING_DETAIL_KEY: keyof LoggingOptions = \"detail\";\n\nconst formatDetailValue = (detail: LogDetail): string | undefined => {\n if (detail === undefined) {\n return undefined;\n }\n if (detail === null) {\n return \"null\";\n }\n if (detail instanceof Date) {\n return detail.toISOString();\n }\n if (detail instanceof Error) {\n return detail.message;\n }\n if (typeof detail === \"boolean\") {\n return detail ? \"yes\" : \"no\";\n }\n return String(detail);\n};\n\nconst trimDecimals = (value: number): string => {\n if (Number.isInteger(value)) {\n return value.toString();\n }\n return value.toString();\n};\n\nconst formatSeconds = (seconds: number): string => {\n const precision =\n seconds < 10 ? DECIMAL_PRECISION_SHORT : DECIMAL_PRECISION_LONG;\n const rounded = Number(seconds.toFixed(precision));\n return `${trimDecimals(rounded)}s`;\n};\n\nconst formatDurationText = (durationMs: number): string => {\n if (durationMs <= 0) {\n return \"0ms\";\n }\n const segments: string[] = [];\n const hours = Math.floor(durationMs / MILLISECONDS_IN_HOUR);\n let remaining = durationMs - hours * MILLISECONDS_IN_HOUR;\n const minutes = Math.floor(remaining / MILLISECONDS_IN_MINUTE);\n remaining -= minutes * MILLISECONDS_IN_MINUTE;\n const seconds = remaining / MILLISECONDS_IN_SECOND;\n const wholeSeconds = Math.floor(seconds);\n const leftoverMs = Math.round(\n remaining - wholeSeconds * MILLISECONDS_IN_SECOND,\n );\n\n if (hours > 0) {\n segments.push(`${hours}h`);\n }\n if (minutes > 0) {\n segments.push(`${minutes}m`);\n }\n if (hours > 0 || minutes > 0) {\n if (wholeSeconds > 0) {\n segments.push(`${wholeSeconds}s`);\n }\n if (segments.length === 0 || leftoverMs > 0) {\n if (leftoverMs > 0) {\n segments.push(`${leftoverMs}ms`);\n }\n }\n } else if (seconds >= 1) {\n segments.push(formatSeconds(seconds));\n } else {\n segments.push(`${Math.round(durationMs)}ms`);\n }\n return segments.join(\" \");\n};\n\ntype LogDetail =\n | string\n | number\n | boolean\n | bigint\n | Date\n | Error\n | null\n | undefined;\n\ntype LogDetailsInput = LogDetail | LogDetail[];\n\ntype LoggerInfo = Record<string, unknown> & {\n level: string;\n message: string;\n [LOG_FIELD_DETAILS]?: string;\n};\n\ntype LoggerPayload = LoggerInfo & {\n [LOG_FIELD_LABEL]: string;\n};\n\ntype TimerEmitter = (\n level: LogLevel,\n message: string,\n details: LogDetail[],\n) => void;\n\nconst extractLevel = (info: LoggerInfo): LogLevel | undefined => {\n const levelText = (info[LOG_FIELD_LEVEL] as string | undefined) ?? info.level;\n if (!levelText) {\n return undefined;\n }\n const normalized = levelText.replace(ANSI_ESCAPE_PATTERN, \"\").toLowerCase();\n return normalized in LOGGING_LEVEL_WEIGHTS\n ? (normalized as LogLevel)\n : undefined;\n};\n\nconst formatDetails = (details: LogDetail[]): string | undefined => {\n const formatted = details\n .map((detail) => formatDetailValue(detail))\n .filter((value): value is string => Boolean(value && value.length > 0));\n if (formatted.length === 0) {\n return undefined;\n }\n return formatted.join(DETAIL_SEPARATOR);\n};\n\nconst formatLogMessage = (info: LoggerInfo): string => {\n const label = info[LOG_FIELD_LABEL] as string | undefined;\n const timestamp = info[LOG_FIELD_TIMESTAMP] as string | undefined;\n const level = extractLevel(info);\n const fallbackLevel = info.level\n .replace(ANSI_ESCAPE_PATTERN, \"\")\n .toUpperCase();\n const message = info[LOG_FIELD_MESSAGE]\n ? String(info[LOG_FIELD_MESSAGE])\n : info.message;\n const levelLabel = level ? LOGGING_LEVEL_LABELS[level] : fallbackLevel;\n const levelIcon = level ? `${LOGGING_LEVEL_ICONS[level]} ` : \"\";\n const detailText = info[LOG_FIELD_DETAILS]\n ? String(info[LOG_FIELD_DETAILS])\n : \"\";\n const formattedDetails = detailText ? `${DETAIL_PREFIX}${detailText}` : \"\";\n const timestampText = timestamp ? `${timestamp} ` : \"\";\n return `${timestampText}${levelIcon}[${label ?? \"\"}] ${levelLabel} ${message}${formattedDetails}`;\n};\n\naddColors(LOGGING_COLORS);\n\nconst baseLogger = createLogger({\n levels: LOGGING_LEVEL_WEIGHTS,\n level: LogLevel.Verbose,\n format: format.combine(\n format.timestamp({ format: LOGGING_TIMESTAMP_FORMAT }),\n format.colorize({ all: true }),\n format.printf((info: unknown) => formatLogMessage(info as LoggerInfo)),\n ),\n transports: [new transports.Console()],\n silent: false,\n});\n\nlet globalOptions: ResolvedLoggingOptions = {\n enabled: LOGGING_DEFAULT_ENABLED,\n levels: undefined,\n detail: undefined,\n};\n\nconst resolveEnabled = (\n enabled: boolean | undefined,\n hasOptions: boolean,\n): boolean => {\n if (enabled !== undefined) {\n return enabled;\n }\n if (hasOptions) {\n return true;\n }\n return LOGGING_DEFAULT_ENABLED;\n};\n\nconst normalizeLevels = (levels?: LogLevel[]): LogLevel[] | undefined => {\n if (!levels || levels.length === 0) {\n return undefined;\n }\n const unique = Array.from(new Set(levels));\n return unique.length > 0 ? unique : undefined;\n};\n\nconst hasLevelsOption = (options?: LoggingOptions): boolean => {\n if (!options) {\n return false;\n }\n return Object.prototype.hasOwnProperty.call(options, LOGGING_LEVELS_KEY);\n};\n\nconst resolveLoggingOptions = (\n options?: LoggingOptions,\n): ResolvedLoggingOptions => {\n const hasOptions = Boolean(options);\n const enabled = resolveEnabled(options?.enabled, hasOptions);\n if (!enabled) {\n return { enabled, levels: undefined, detail: undefined };\n }\n return {\n enabled,\n levels: normalizeLevels(options?.levels),\n detail: options?.detail,\n };\n};\n\nconst getDetailLevels = (\n detail: LoggingDetailLevel | undefined,\n): LogLevel[] | undefined => {\n if (!detail) {\n return undefined;\n }\n return LOGGING_DETAIL_LEVELS[detail];\n};\n\nconst shouldLog = (\n level: LogLevel,\n options: ResolvedLoggingOptions,\n): boolean => {\n if (!options.enabled) {\n return false;\n }\n const detailLevels = getDetailLevels(options.detail);\n const hasDetailFilter = detailLevels && detailLevels.length > 0;\n const hasLevelFilter = options.levels && options.levels.length > 0;\n if (!hasDetailFilter && !hasLevelFilter) {\n return true;\n }\n if (hasDetailFilter && !detailLevels!.includes(level)) {\n return false;\n }\n if (hasLevelFilter && !options.levels!.includes(level)) {\n return false;\n }\n return true;\n};\n\nconst mergeOptions = (local?: LoggingOptions): ResolvedLoggingOptions => {\n if (!local) {\n return globalOptions;\n }\n const resolvedLocal = resolveLoggingOptions(local);\n const hasLocalLevels = hasLevelsOption(local);\n const hasLocalDetail = Object.prototype.hasOwnProperty.call(\n local,\n LOGGING_DETAIL_KEY,\n );\n const ignoreGlobalLevels = hasLocalDetail && !hasLocalLevels;\n return {\n enabled: resolvedLocal.enabled,\n levels: hasLocalLevels\n ? resolvedLocal.levels\n : ignoreGlobalLevels\n ? undefined\n : globalOptions.levels,\n detail: hasLocalDetail ? resolvedLocal.detail : globalOptions.detail,\n };\n};\n\nconst normalizeDetails = (input: LogDetailsInput[]): LogDetail[] => {\n return input.flatMap((entry) => {\n if (Array.isArray(entry)) {\n return entry;\n }\n return [entry];\n });\n};\n\nconst logWithDetails = (\n level: LogLevel,\n scope: string,\n message: string,\n details: LogDetail[],\n options: ResolvedLoggingOptions,\n): void => {\n if (!shouldLog(level, options)) {\n return;\n }\n const formattedDetails = formatDetails(details);\n const logPayload: LoggerPayload = {\n level,\n message,\n [LOG_FIELD_LABEL]: scope,\n };\n if (formattedDetails) {\n logPayload[LOG_FIELD_DETAILS] = formattedDetails;\n }\n baseLogger.log(logPayload);\n};\n\nexport const configureLogging = (\n options?: LoggingOptions,\n): ResolvedLoggingOptions => {\n globalOptions = resolveLoggingOptions(options);\n return globalOptions;\n};\n\nclass LoggerTimer {\n private readonly start = performance.now();\n private lastMark = this.start;\n private finished = false;\n\n constructor(\n private readonly label: string,\n private readonly emit: TimerEmitter,\n ) {}\n\n public mark(\n message: string,\n level: LogLevel = LogLevel.Debug,\n ...details: LogDetailsInput[]\n ): void {\n if (this.finished) {\n return;\n }\n const now = performance.now();\n const totalElapsed = now - this.start;\n const segmentElapsed = now - this.lastMark;\n this.lastMark = now;\n const timerDetails: LogDetail[] = [\n `${this.label} total ${formatDurationText(totalElapsed)}`,\n ];\n if (segmentElapsed > 0 && segmentElapsed !== totalElapsed) {\n timerDetails.push(`segment ${formatDurationText(segmentElapsed)}`);\n }\n const normalized = normalizeDetails(details);\n this.emit(level, message, [...timerDetails, ...normalized]);\n }\n\n public end(\n message?: string,\n level: LogLevel = LogLevel.Info,\n ...details: LogDetailsInput[]\n ): void {\n if (this.finished) {\n return;\n }\n const totalElapsed = performance.now() - this.start;\n const normalized = normalizeDetails(details);\n const timerDetails: LogDetail[] = [\n `${this.label} total ${formatDurationText(totalElapsed)}`,\n ];\n this.emit(level, message ?? `${this.label} completed`, [\n ...timerDetails,\n ...normalized,\n ]);\n this.finished = true;\n }\n}\n\nexport class ScopedLogger {\n constructor(\n private readonly scope: string,\n private readonly localOptions?: LoggingOptions,\n ) {}\n\n public error(message: string, ...details: LogDetailsInput[]): void {\n this.write(LogLevel.Error, message, details);\n }\n\n public warn(message: string, ...details: LogDetailsInput[]): void {\n this.write(LogLevel.Warn, message, details);\n }\n\n public log(message: string, ...details: LogDetailsInput[]): void {\n this.write(LogLevel.Log, message, details);\n }\n\n public info(message: string, ...details: LogDetailsInput[]): void {\n this.write(LogLevel.Info, message, details);\n }\n\n public debug(message: string, ...details: LogDetailsInput[]): void {\n this.write(LogLevel.Debug, message, details);\n }\n\n public verbose(message: string, ...details: LogDetailsInput[]): void {\n this.write(LogLevel.Verbose, message, details);\n }\n\n public timer(label: string): LoggerTimer {\n return new LoggerTimer(label, (level, message, details) => {\n this.write(level, message, details);\n });\n }\n\n public formatDuration(durationMs: number): string {\n return formatDurationText(durationMs);\n }\n\n private write(\n level: LogLevel,\n message: string,\n details: LogDetailsInput[],\n ): void {\n const normalized = normalizeDetails(details);\n logWithDetails(\n level,\n this.scope,\n message,\n normalized,\n mergeOptions(this.localOptions),\n );\n }\n}\n\nexport const createScopedLogger = (\n scope: string,\n options?: LoggingOptions,\n): ScopedLogger => new ScopedLogger(scope, options);\n\nexport const getLoggingOptions = (): ResolvedLoggingOptions => ({\n ...globalOptions,\n levels: globalOptions.levels ? [...globalOptions.levels] : undefined,\n});\n"],"names":["ScopedLogger","configureLogging","createScopedLogger","getLoggingOptions","LOG_FIELD_LABEL","LOG_FIELD_MESSAGE","LOG_FIELD_LEVEL","LOG_FIELD_TIMESTAMP","LOG_FIELD_DETAILS","ANSI_ESCAPE_PATTERN","DETAIL_SEPARATOR","DETAIL_PREFIX","MILLISECONDS_IN_SECOND","SECONDS_IN_MINUTE","MINUTES_IN_HOUR","MILLISECONDS_IN_MINUTE","MILLISECONDS_IN_HOUR","DECIMAL_PRECISION_SHORT","DECIMAL_PRECISION_LONG","LOGGING_LEVELS_KEY","LOGGING_DETAIL_KEY","formatDetailValue","detail","undefined","Date","toISOString","Error","message","String","trimDecimals","value","Number","isInteger","toString","formatSeconds","seconds","precision","rounded","toFixed","formatDurationText","durationMs","segments","hours","Math","floor","remaining","minutes","wholeSeconds","leftoverMs","round","push","length","join","extractLevel","info","levelText","level","normalized","replace","toLowerCase","LOGGING_LEVEL_WEIGHTS","formatDetails","details","formatted","map","filter","Boolean","formatLogMessage","label","timestamp","fallbackLevel","toUpperCase","levelLabel","LOGGING_LEVEL_LABELS","levelIcon","LOGGING_LEVEL_ICONS","detailText","formattedDetails","timestampText","addColors","LOGGING_COLORS","baseLogger","createLogger","levels","LogLevel","Verbose","format","combine","LOGGING_TIMESTAMP_FORMAT","colorize","all","printf","transports","Console","silent","globalOptions","enabled","LOGGING_DEFAULT_ENABLED","resolveEnabled","hasOptions","normalizeLevels","unique","Array","from","Set","hasLevelsOption","options","Object","prototype","hasOwnProperty","call","resolveLoggingOptions","getDetailLevels","LOGGING_DETAIL_LEVELS","shouldLog","detailLevels","hasDetailFilter","hasLevelFilter","includes","mergeOptions","local","resolvedLocal","hasLocalLevels","hasLocalDetail","ignoreGlobalLevels","normalizeDetails","input","flatMap","entry","isArray","logWithDetails","scope","logPayload","log","LoggerTimer","mark","Debug","finished","now","performance","totalElapsed","start","segmentElapsed","lastMark","timerDetails","emit","end","Info","error","write","warn","Warn","Log","debug","verbose","timer","formatDuration","localOptions"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fastypest",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.40",
|
|
4
4
|
"description": "Restores the database automatically after each test. Allows serial execution of tests without having to delete and restore the database having to stop the application",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -58,30 +58,30 @@
|
|
|
58
58
|
"@eslint/js": "^10.0.1",
|
|
59
59
|
"@swc-node/jest": "^1.10.1",
|
|
60
60
|
"@swc/cli": "^0.8.1",
|
|
61
|
-
"@swc/core": "^1.15.
|
|
61
|
+
"@swc/core": "^1.15.47",
|
|
62
62
|
"@swc/helpers": "^0.5.23",
|
|
63
63
|
"@types/jest": "^30.0.0",
|
|
64
|
-
"@types/node": "^26.1.
|
|
64
|
+
"@types/node": "^26.1.2",
|
|
65
65
|
"@types/winston": "^2.4.4",
|
|
66
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
66
|
+
"@typescript-eslint/eslint-plugin": "^8.65.0",
|
|
67
67
|
"@typescript-eslint/parser": "^8.65.0",
|
|
68
68
|
"@typescript-eslint/types": "8.65.0",
|
|
69
69
|
"cpy-cli": "^6.0.0",
|
|
70
|
-
"eslint": "^10.
|
|
70
|
+
"eslint": "^10.8.0",
|
|
71
71
|
"eslint-config-standard-with-typescript": "^43.0.1",
|
|
72
72
|
"eslint-plugin-import": "^2.32.0",
|
|
73
73
|
"eslint-plugin-n": "^18.2.2",
|
|
74
74
|
"eslint-plugin-prettier": "^5.5.6",
|
|
75
75
|
"eslint-plugin-promise": "^7.3.0",
|
|
76
76
|
"execa": "^10.0.0",
|
|
77
|
-
"globals": "^17.
|
|
77
|
+
"globals": "^17.8.0",
|
|
78
78
|
"jest": "^30.4.2",
|
|
79
79
|
"lefthook": "^2.1.10",
|
|
80
|
-
"lint-staged": "^17.
|
|
80
|
+
"lint-staged": "^17.2.0",
|
|
81
81
|
"mariadb": "^3.5.3",
|
|
82
82
|
"mysql": "^2.18.1",
|
|
83
83
|
"pg": "^8.22.0",
|
|
84
|
-
"prettier": "^3.9.
|
|
84
|
+
"prettier": "^3.9.6",
|
|
85
85
|
"reflect-metadata": "^0.2.2",
|
|
86
86
|
"rimraf": "^6.1.3",
|
|
87
87
|
"standard-version": "^9.5.0",
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"tsconfig-paths": "^4.2.0",
|
|
90
90
|
"typeorm": "^0.3.29",
|
|
91
91
|
"typescript": "^5.9.3",
|
|
92
|
-
"typescript-eslint": "^8.
|
|
92
|
+
"typescript-eslint": "^8.65.0"
|
|
93
93
|
},
|
|
94
94
|
"peerDependencies": {
|
|
95
95
|
"typeorm": "^0.3.29"
|