@rehearsal-db/core 0.1.0-beta.13 → 0.1.0-beta.15

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.
Files changed (169) hide show
  1. package/CHANGELOG.md +93 -0
  2. package/README.md +4 -1
  3. package/dist/package.json +100 -0
  4. package/dist/scripts/install/create_root_config.d.mts +3 -0
  5. package/dist/scripts/install/create_root_config.mjs +13 -0
  6. package/dist/scripts/runtime/manage_database.d.mts +6 -0
  7. package/{scripts → dist/scripts}/runtime/manage_database.mjs +6 -8
  8. package/dist/src/application/session.d.mts +96 -0
  9. package/dist/src/application/session.mjs +380 -0
  10. package/dist/src/baseline/artifact.d.mts +119 -0
  11. package/dist/src/baseline/artifact.mjs +522 -0
  12. package/dist/src/baseline/builder.d.mts +19 -0
  13. package/dist/src/baseline/builder.mjs +142 -0
  14. package/dist/src/baseline/input_discovery.d.mts +13 -0
  15. package/dist/src/baseline/input_discovery.mjs +149 -0
  16. package/dist/src/baseline/policy_review.d.mts +56 -0
  17. package/dist/src/baseline/policy_review.mjs +73 -0
  18. package/dist/src/baseline/preparation.d.mts +63 -0
  19. package/dist/src/baseline/preparation.mjs +295 -0
  20. package/dist/src/baseline/privacy_engine.d.mts +162 -0
  21. package/dist/src/baseline/privacy_engine.mjs +1162 -0
  22. package/dist/src/baseline/privacy_structured_json.d.mts +66 -0
  23. package/dist/src/baseline/privacy_structured_json.mjs +464 -0
  24. package/dist/src/baseline/sanitization_policy.d.mts +69 -0
  25. package/dist/src/baseline/sanitization_policy.mjs +227 -0
  26. package/dist/src/baseline/schema_snapshot.d.mts +19 -0
  27. package/dist/src/baseline/schema_snapshot.mjs +79 -0
  28. package/dist/src/cli/arguments.d.mts +43 -0
  29. package/dist/src/cli/arguments.mjs +135 -0
  30. package/dist/src/cli/guided.d.mts +51 -0
  31. package/dist/src/cli/guided.mjs +713 -0
  32. package/dist/src/cli/init_command.d.mts +21 -0
  33. package/dist/src/cli/init_command.mjs +90 -0
  34. package/dist/src/cli/project_commands.d.mts +157 -0
  35. package/dist/src/cli/project_commands.mjs +183 -0
  36. package/dist/src/cli/rehearsal.d.mts +7 -0
  37. package/dist/src/cli/rehearsal.mjs +706 -0
  38. package/dist/src/cli/renderers.d.mts +299 -0
  39. package/dist/src/cli/renderers.mjs +554 -0
  40. package/dist/src/cli/runtime_commands.d.mts +265 -0
  41. package/dist/src/cli/runtime_commands.mjs +599 -0
  42. package/dist/src/cli/source_commands.d.mts +432 -0
  43. package/dist/src/cli/source_commands.mjs +299 -0
  44. package/dist/src/cli/terminal.d.mts +59 -0
  45. package/dist/src/cli/terminal.mjs +230 -0
  46. package/dist/src/identity/claim.d.mts +144 -0
  47. package/dist/src/identity/claim.mjs +947 -0
  48. package/dist/src/identity/provider_configuration.d.mts +37 -0
  49. package/dist/src/identity/provider_configuration.mjs +132 -0
  50. package/dist/src/identity/storage.d.mts +21 -0
  51. package/dist/src/identity/storage.mjs +122 -0
  52. package/dist/src/index.d.mts +4 -0
  53. package/dist/src/index.mjs +3 -0
  54. package/dist/src/project/configuration.d.mts +181 -0
  55. package/dist/src/project/configuration.mjs +958 -0
  56. package/dist/src/project/install_scaffold.d.mts +42 -0
  57. package/dist/src/project/install_scaffold.mjs +263 -0
  58. package/dist/src/project/setup.d.mts +87 -0
  59. package/dist/src/project/setup.mjs +414 -0
  60. package/dist/src/project/support_report.d.mts +88 -0
  61. package/dist/src/project/support_report.mjs +83 -0
  62. package/dist/src/runtime/cleanup.d.mts +85 -0
  63. package/dist/src/runtime/cleanup.mjs +311 -0
  64. package/dist/src/runtime/migration_history.d.mts +51 -0
  65. package/dist/src/runtime/migration_history.mjs +170 -0
  66. package/dist/src/runtime/plan.d.mts +134 -0
  67. package/dist/src/runtime/plan.mjs +636 -0
  68. package/dist/src/runtime/policy.d.mts +66 -0
  69. package/dist/src/runtime/policy.mjs +369 -0
  70. package/dist/src/runtime/restore.d.mts +22 -0
  71. package/dist/src/runtime/restore.mjs +276 -0
  72. package/dist/src/runtime/service_environment.d.mts +11 -0
  73. package/dist/src/runtime/service_environment.mjs +58 -0
  74. package/dist/src/runtime/topology.d.mts +51 -0
  75. package/dist/src/runtime/topology.mjs +128 -0
  76. package/dist/src/shared/diagnostics.d.mts +97 -0
  77. package/dist/src/shared/diagnostics.mjs +170 -0
  78. package/dist/src/shared/human_output.d.mts +2 -0
  79. package/{src → dist/src}/shared/human_output.mjs +1 -3
  80. package/dist/src/shared/node_runtime.d.mts +14 -0
  81. package/dist/src/shared/node_runtime.mjs +25 -0
  82. package/dist/src/shared/operation_guard.d.mts +22 -0
  83. package/dist/src/shared/operation_guard.mjs +150 -0
  84. package/dist/src/shared/process_environment.d.mts +15 -0
  85. package/dist/src/shared/process_environment.mjs +50 -0
  86. package/dist/src/source/access.d.mts +165 -0
  87. package/dist/src/source/access.mjs +602 -0
  88. package/dist/src/source/asset_transfer.d.mts +27 -0
  89. package/dist/src/source/asset_transfer.mjs +202 -0
  90. package/dist/src/source/baseline.d.mts +66 -0
  91. package/dist/src/source/baseline.mjs +372 -0
  92. package/dist/src/source/external_reader.d.mts +42 -0
  93. package/dist/src/source/external_reader.mjs +278 -0
  94. package/dist/src/source/postgresql_access.d.mts +86 -0
  95. package/dist/src/source/postgresql_access.mjs +454 -0
  96. package/dist/src/source/privacy_paths.d.mts +10 -0
  97. package/dist/src/source/privacy_paths.mjs +27 -0
  98. package/dist/src/targets/driver.d.mts +2 -0
  99. package/dist/src/targets/driver.mjs +13 -0
  100. package/dist/src/targets/postgresql.d.mts +5 -0
  101. package/dist/src/targets/postgresql.mjs +641 -0
  102. package/dist/src/targets/supabase.d.mts +8 -0
  103. package/dist/src/targets/supabase.mjs +659 -0
  104. package/dist/src/targets/supabase_environment.d.mts +49 -0
  105. package/dist/src/targets/supabase_environment.mjs +162 -0
  106. package/dist/src/targets/target.d.mts +33 -0
  107. package/dist/src/targets/target.mjs +39 -0
  108. package/docs/README.md +1 -0
  109. package/docs/architecture.md +17 -9
  110. package/docs/configuration.md +49 -8
  111. package/docs/getting-started.md +28 -0
  112. package/docs/index.md +1 -0
  113. package/docs/production-source.md +43 -7
  114. package/docs/releasing.md +5 -3
  115. package/docs/roadmap.md +3 -2
  116. package/docs/sanitization.md +415 -14
  117. package/docs/standalone-workflow.md +12 -6
  118. package/docs/troubleshooting.md +5 -1
  119. package/docs/tutorial.md +5 -0
  120. package/docs/typescript.md +87 -0
  121. package/package.json +35 -29
  122. package/scripts/install/create_root_config.mjs +0 -36
  123. package/src/README.md +0 -17
  124. package/src/application/session.mjs +0 -435
  125. package/src/baseline/artifact.mjs +0 -684
  126. package/src/baseline/builder.mjs +0 -164
  127. package/src/baseline/input_discovery.mjs +0 -155
  128. package/src/baseline/policy_review.mjs +0 -92
  129. package/src/baseline/preparation.mjs +0 -323
  130. package/src/baseline/privacy_engine.mjs +0 -952
  131. package/src/baseline/sanitization_policy.mjs +0 -299
  132. package/src/baseline/schema_snapshot.mjs +0 -113
  133. package/src/cli/arguments.mjs +0 -126
  134. package/src/cli/guided.mjs +0 -814
  135. package/src/cli/init_command.mjs +0 -94
  136. package/src/cli/rehearsal.mjs +0 -970
  137. package/src/cli/renderers.mjs +0 -626
  138. package/src/cli/runtime_commands.mjs +0 -707
  139. package/src/cli/source_commands.mjs +0 -347
  140. package/src/cli/terminal.mjs +0 -275
  141. package/src/identity/claim.mjs +0 -1163
  142. package/src/identity/provider_configuration.mjs +0 -177
  143. package/src/identity/storage.mjs +0 -165
  144. package/src/project/configuration.mjs +0 -1337
  145. package/src/project/install_scaffold.mjs +0 -291
  146. package/src/project/setup.mjs +0 -466
  147. package/src/project/support_report.mjs +0 -105
  148. package/src/runtime/cleanup.mjs +0 -381
  149. package/src/runtime/migration_history.mjs +0 -220
  150. package/src/runtime/plan.mjs +0 -722
  151. package/src/runtime/policy.mjs +0 -438
  152. package/src/runtime/restore.mjs +0 -337
  153. package/src/runtime/service_environment.mjs +0 -82
  154. package/src/runtime/topology.mjs +0 -177
  155. package/src/shared/diagnostics.mjs +0 -207
  156. package/src/shared/node_runtime.mjs +0 -31
  157. package/src/shared/operation_guard.mjs +0 -162
  158. package/src/shared/process_environment.mjs +0 -68
  159. package/src/source/access.mjs +0 -753
  160. package/src/source/asset_transfer.mjs +0 -207
  161. package/src/source/baseline.mjs +0 -482
  162. package/src/source/external_reader.mjs +0 -255
  163. package/src/source/postgresql_access.mjs +0 -581
  164. package/src/source/privacy_paths.mjs +0 -38
  165. package/src/targets/postgresql.mjs +0 -808
  166. package/src/targets/supabase.mjs +0 -840
  167. package/src/targets/supabase_environment.mjs +0 -229
  168. package/src/targets/target.mjs +0 -66
  169. /package/{src/project → types}/configuration.d.mts +0 -0
@@ -1,291 +0,0 @@
1
- /**
2
- * Purpose: Resolve an npm consumer root conservatively and create the same
3
- * project-owned scaffolding used by the guided setup command.
4
- */
5
-
6
- import { access, readFile, readdir, stat } from "node:fs/promises";
7
- import { isAbsolute, join, relative, resolve, sep } from "node:path";
8
- import { applyRehearsalSetup, planRehearsalSetup } from "./setup.mjs";
9
- import {
10
- findRehearsalConfigPath,
11
- inspectDetectedProject,
12
- loadRehearsalConfig,
13
- } from "./configuration.mjs";
14
-
15
- const PACKAGE_NAME = "@rehearsal-db/core";
16
- const DEPENDENCY_GROUPS = Object.freeze([
17
- "dependencies",
18
- "devDependencies",
19
- "optionalDependencies",
20
- "peerDependencies",
21
- ]);
22
- const CACHE_SEGMENTS = new Set(["_cacache", "_npx", ".cache"]);
23
-
24
- const pathExists = (path) =>
25
- access(path)
26
- .then(() => true)
27
- .catch((error) => {
28
- if (error?.code === "ENOENT") return false;
29
- throw error;
30
- });
31
-
32
- const readJson = async (path) => JSON.parse(await readFile(path, "utf8"));
33
-
34
- const isInside = (parent, child) => {
35
- const path = relative(resolve(parent), resolve(child));
36
- return path === "" || (!path.startsWith(`..${sep}`) && path !== "..");
37
- };
38
-
39
- const pathSegments = (path) => resolve(path).split(sep).filter(Boolean);
40
-
41
- const isCachePath = (path) =>
42
- pathSegments(path).some((segment) => CACHE_SEGMENTS.has(segment));
43
-
44
- const isInstalledPackagePath = (packageRoot) => {
45
- const segments = pathSegments(packageRoot);
46
- return (
47
- segments.at(-3) === "node_modules" &&
48
- segments.at(-2) === "@rehearsal-db" &&
49
- segments.at(-1) === "core"
50
- );
51
- };
52
-
53
- const declaresRehearsal = (manifest) =>
54
- DEPENDENCY_GROUPS.some((group) =>
55
- Object.hasOwn(manifest[group] ?? {}, PACKAGE_NAME),
56
- );
57
-
58
- const readProject = async (root) => {
59
- const path = join(root, "package.json");
60
- if (!(await pathExists(path))) return null;
61
- const metadata = await stat(path);
62
- if (!metadata.isFile()) return null;
63
- return { root: resolve(root), manifest: await readJson(path) };
64
- };
65
-
66
- const workspacePatterns = (manifest) => {
67
- const value = manifest.workspaces;
68
- if (Array.isArray(value)) return value;
69
- if (value && Array.isArray(value.packages)) return value.packages;
70
- return [];
71
- };
72
-
73
- const expandWorkspacePattern = async (root, pattern) => {
74
- if (
75
- typeof pattern !== "string" ||
76
- !pattern ||
77
- isAbsolute(pattern) ||
78
- pattern.split(/[\\/]/u).includes("..")
79
- ) {
80
- return [];
81
- }
82
- if (!pattern.includes("*")) return [resolve(root, pattern)];
83
- if (!pattern.endsWith("/*") || pattern.slice(0, -2).includes("*")) {
84
- return [];
85
- }
86
- const parent = resolve(root, pattern.slice(0, -2));
87
- const entries = await readdir(parent, { withFileTypes: true }).catch(
88
- (error) => {
89
- if (error?.code === "ENOENT") return [];
90
- throw error;
91
- },
92
- );
93
- return entries
94
- .filter((entry) => entry.isDirectory() && entry.name !== "node_modules")
95
- .map((entry) => join(parent, entry.name));
96
- };
97
-
98
- const workspaceProjectsFromManifest = async (project) => {
99
- const roots = (
100
- await Promise.all(
101
- workspacePatterns(project.manifest).map((pattern) =>
102
- expandWorkspacePattern(project.root, pattern),
103
- ),
104
- )
105
- ).flat();
106
- return (
107
- await Promise.all(
108
- roots.map((root) =>
109
- isInside(project.root, root) ? readProject(root) : null,
110
- ),
111
- )
112
- ).filter(Boolean);
113
- };
114
-
115
- const workspaceProjectsFromLock = async (root) => {
116
- const path = join(root, "package-lock.json");
117
- if (!(await pathExists(path))) return [];
118
- const lock = await readJson(path);
119
- return (
120
- await Promise.all(
121
- Object.entries(lock.packages ?? {})
122
- .filter(
123
- ([name, manifest]) =>
124
- name &&
125
- !name.split("/").includes("node_modules") &&
126
- declaresRehearsal(manifest),
127
- )
128
- .map(([name]) => readProject(resolve(root, name))),
129
- )
130
- ).filter(Boolean);
131
- };
132
-
133
- const uniqueProjects = (projects) => [
134
- ...new Map(
135
- projects.filter(Boolean).map((entry) => [entry.root, entry]),
136
- ).values(),
137
- ];
138
-
139
- const skip = (reason) => ({ status: "skipped", reason });
140
-
141
- export const resolveRehearsalConsumerRoot = async ({
142
- packageRoot,
143
- initCwd,
144
- localPrefix,
145
- globalInstall = false,
146
- workspace,
147
- } = {}) => {
148
- if (globalInstall === true || ["1", "true"].includes(globalInstall)) {
149
- return skip("global installations do not own an application project");
150
- }
151
- if (!packageRoot || !isInstalledPackagePath(packageRoot)) {
152
- return skip("the package is not running from a consumer node_modules tree");
153
- }
154
- if (isCachePath(packageRoot)) {
155
- return skip(
156
- "package-cache and temporary npx installs are not project roots",
157
- );
158
- }
159
-
160
- const anchorRoots = [...new Set([initCwd, localPrefix].filter(Boolean))]
161
- .map((path) => resolve(path))
162
- .filter(
163
- (path) =>
164
- !pathSegments(path).includes("node_modules") && !isCachePath(path),
165
- );
166
- const anchors = uniqueProjects(
167
- await Promise.all(anchorRoots.map((root) => readProject(root))),
168
- );
169
- if (anchors.length === 0) {
170
- return skip("no application package.json was found for this installation");
171
- }
172
- const installationAnchors = anchors.filter((project) =>
173
- isInside(project.root, packageRoot),
174
- );
175
- if (installationAnchors.length === 0) {
176
- return skip(
177
- "the installed package is outside the candidate application root",
178
- );
179
- }
180
-
181
- const declared = [];
182
- const workspaces = [];
183
- for (const anchor of installationAnchors) {
184
- if (declaresRehearsal(anchor.manifest)) declared.push(anchor);
185
- const [manifestWorkspaces, lockWorkspaces] = await Promise.all([
186
- workspaceProjectsFromManifest(anchor),
187
- workspaceProjectsFromLock(anchor.root),
188
- ]);
189
- workspaces.push(...manifestWorkspaces, ...lockWorkspaces);
190
- declared.push(
191
- ...manifestWorkspaces.filter((project) =>
192
- declaresRehearsal(project.manifest),
193
- ),
194
- ...lockWorkspaces,
195
- );
196
- }
197
- if (workspace) {
198
- const requested = String(workspace).trim().replace(/\\/gu, "/");
199
- const selected = uniqueProjects(workspaces).filter(
200
- (project) =>
201
- project.manifest.name === requested ||
202
- installationAnchors.some(
203
- (anchor) =>
204
- relative(anchor.root, project.root).replace(/\\/gu, "/") ===
205
- requested.replace(/^\.\//u, ""),
206
- ),
207
- );
208
- if (selected.length === 1) {
209
- return { status: "resolved", projectRoot: selected[0].root };
210
- }
211
- if (selected.length > 1) {
212
- return skip("the npm workspace selector matched multiple applications");
213
- }
214
- }
215
- const candidates = uniqueProjects(declared);
216
- if (candidates.length === 1) {
217
- return { status: "resolved", projectRoot: candidates[0].root };
218
- }
219
- if (candidates.length > 1) {
220
- return skip(
221
- `multiple workspace applications declare ${PACKAGE_NAME}; run Rehearsal inside each application`,
222
- );
223
- }
224
-
225
- const exact = initCwd ? await readProject(resolve(initCwd)) : null;
226
- const workspaceRoot = installationAnchors.some(
227
- (project) => workspacePatterns(project.manifest).length > 0,
228
- );
229
- if (
230
- exact &&
231
- installationAnchors.some((anchor) => isInside(anchor.root, exact.root)) &&
232
- (!workspaceRoot || exact.root !== installationAnchors[0].root)
233
- ) {
234
- return { status: "resolved", projectRoot: exact.root };
235
- }
236
- if (!workspaceRoot && installationAnchors.length === 1) {
237
- return {
238
- status: "resolved",
239
- projectRoot: installationAnchors[0].root,
240
- };
241
- }
242
- return skip("the workspace application root is ambiguous");
243
- };
244
-
245
- export const createInstalledRehearsalScaffold = async ({
246
- packageRoot,
247
- environment = process.env,
248
- isPortAvailable,
249
- } = {}) => {
250
- const resolution = await resolveRehearsalConsumerRoot({
251
- packageRoot,
252
- initCwd: environment.INIT_CWD,
253
- localPrefix: environment.npm_config_local_prefix,
254
- globalInstall: environment.npm_config_global,
255
- workspace: environment.npm_config_workspace,
256
- });
257
- if (resolution.status !== "resolved") return resolution;
258
-
259
- const detected = await inspectDetectedProject({
260
- projectRoot: resolution.projectRoot,
261
- });
262
- const hasExistingConfig = await findRehearsalConfigPath({
263
- projectRoot: resolution.projectRoot,
264
- })
265
- .then(() => true)
266
- .catch((error) => {
267
- if (
268
- String(error?.message ?? error).startsWith("No Rehearsal configuration")
269
- ) {
270
- return false;
271
- }
272
- throw error;
273
- });
274
- const plan = await planRehearsalSetup({
275
- projectRoot: resolution.projectRoot,
276
- target: hasExistingConfig
277
- ? undefined
278
- : detected.hasSupabaseConfig
279
- ? "supabase"
280
- : "postgresql",
281
- isPortAvailable,
282
- });
283
- const result = await applyRehearsalSetup(plan);
284
- await loadRehearsalConfig({ projectRoot: resolution.projectRoot });
285
- return {
286
- status: "ready",
287
- projectRoot: resolution.projectRoot,
288
- target: plan.target,
289
- files: result.files,
290
- };
291
- };