import type { Driver } from "neo4j-driver"; /** * Options for {@link dumpRbacMatrix}. */ export interface DumpRbacMatrixOptions { /** * A connected `neo4j-driver` Driver. The function opens a single session * and closes it on exit, but does NOT close the driver — the caller owns * the driver lifecycle. */ driver: Driver; /** * Optional database name. If omitted, the driver's default database is * used. Pass this when your deployment uses a non-default database * (e.g. `process.env.NEO4J_DATABASE`). */ database?: string; /** * UUID → PascalCase name map for roles. The serializer emits * `RoleId.` references using these names; without them, the * generated file contains raw UUIDs. * * Typical construction from a `RoleId` enum: * ```ts * Object.fromEntries(Object.entries(RoleId).map(([k, v]) => [v, k])) * ``` */ roleNames: Record; /** * UUID → PascalCase name map for modules. Same shape and purpose as * `roleNames`, applied to `ModuleId.` references in the output. */ moduleNames: Record; /** * UUID of the Administrator role. The dump writes * `[RoleId.Administrator]: perm.full` for every declared module so the * file matches the convention enforced by `RbacReconcilerService` * (which deliberately skips Administrator edges — Admin is hardwired in * code, not represented as `HAS_PERMISSIONS` edges in the DB). */ administratorRoleId: string; /** * Output path for the emitted TypeScript file. Absolute, or relative to * `process.cwd()`. Parent directories are created if missing. * * Convention: place the file under your API app's `src/rbac/` directory * (e.g. `"src/rbac/permissions.ts"` when running from the api package * cwd, or `"apps/api/src/rbac/permissions.ts"` from the monorepo root). */ outputPath: string; /** * Import lines emitted verbatim, in order, at the head of the generated * file. Supply these when your app's `RoleId` / `ModuleId` / module-paths * map do not live where the package default expects them — otherwise the * dump is not re-runnable, because a re-run would overwrite a hand-fixed * header with imports that do not resolve in your app. * * Omit to keep the default header * ({@link DEFAULT_IMPORT_LINES} in `serializer/matrix-to-ts`), which is the * neural-erp convention and stays byte-identical. * * ```ts * importLines: [ * `import { RoleId } from "../config/enums/role.id";`, * `import { ModuleId } from "@your-org/shared";`, * `import { perm, defineRbac } from "@carlonicora/nestjs-neo4jsonapi";`, * `import { MODULE_USER_PATHS } from "../features/rbac/module-relationships.map";`, * ] * ``` */ importLines?: string[]; } /** * Result of {@link dumpRbacMatrix}. */ export interface DumpRbacMatrixResult { /** Number of bytes written to the output file. */ bytesWritten: number; /** Resolved absolute path that was written. */ path: string; } /** * Read the current RBAC state from Neo4j and emit a declarative-matrix * `permissions.ts` source file for the consuming app to commit. * * **Developer-only.** This is meant to run as a one-shot CLI step when * bootstrapping a new project (or re-dumping after manual DB edits during * development). Do not expose this from a runtime endpoint — production * servers should never write source files. * * By default the emitted file imports `RoleId` / `ModuleId` from * `@neural-erp/shared`, and `perm` / `defineRbac` from * `@carlonicora/nestjs-neo4jsonapi`. Apps whose enums live elsewhere MUST * pass {@link DumpRbacMatrixOptions.importLines} reproducing their own * header, otherwise re-running the dump overwrites a hand-fixed header with * imports that do not resolve — i.e. the dump is a one-shot instead of a * repeatable command. * * **Import this function from the `/foundations/rbac` subpath, NOT from the * package root barrel.** Loading the root barrel pulls in the whole package * graph, which corrupts the TypeScript parser bundled with `prettier` (the * serialiser formats its output with it) and makes the dump fail — a * session-verified defect from the Wave 1 foundation migration. Note the * `exports` map currently exposes subpaths via the `./foundations/*` * wildcard (`./dist/foundations/*.js`), so the form that resolves today is * `@carlonicora/nestjs-neo4jsonapi/foundations/rbac/index`; the bare * `.../foundations/rbac` needs an explicit `"./foundations/rbac"` export * entry. * * @example * ```ts * // apps/api/scripts/rbac-dump.ts * import * as dotenv from "dotenv"; * import * as path from "path"; * dotenv.config({ path: path.resolve(__dirname, "../../../.env") }); * * import neo4j from "neo4j-driver"; * import { RoleId, ModuleId } from "@neural-erp/shared"; * // Subpath import — the package ROOT barrel breaks prettier's bundled * // TypeScript parser (see the note above). * import { dumpRbacMatrix } from "@carlonicora/nestjs-neo4jsonapi/foundations/rbac/index"; * * async function main() { * const driver = neo4j.driver( * process.env.NEO4J_URI!, * neo4j.auth.basic(process.env.NEO4J_USER!, process.env.NEO4J_PASSWORD!), * ); * try { * const result = await dumpRbacMatrix({ * driver, * database: process.env.NEO4J_DATABASE, * roleNames: Object.fromEntries( * Object.entries(RoleId).map(([k, v]) => [v, k]), * ), * moduleNames: Object.fromEntries( * Object.entries(ModuleId).map(([k, v]) => [v, k]), * ), * administratorRoleId: RoleId.Administrator, * outputPath: path.resolve(__dirname, "../src/rbac/permissions.ts"), * // Reproduce YOUR app's header verbatim so the dump is re-runnable. * importLines: [ * `import { RoleId, ModuleId } from "@neural-erp/shared";`, * `import { perm, defineRbac } from "@carlonicora/nestjs-neo4jsonapi";`, * `import { MODULE_USER_PATHS } from "../features/rbac/module-relationships.map";`, * ], * }); * console.log(`Wrote ${result.bytesWritten} bytes to ${result.path}`); * } finally { * await driver.close(); * } * } * * main().catch((err) => { * console.error(err); * process.exit(1); * }); * ``` */ export declare function dumpRbacMatrix(opts: DumpRbacMatrixOptions): Promise; //# sourceMappingURL=dump.d.ts.map