@kuckit/db 3.0.8 → 3.0.10

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.
@@ -3,6 +3,11 @@
3
3
  * Get schema paths for Drizzle configuration.
4
4
  * Derives paths from kuckit.config.ts (single source of truth).
5
5
  *
6
+ * Schema directory priority:
7
+ * 1. kuckit.config.ts schemaDir option
8
+ * 2. package.json kuckit.schemaDir field
9
+ * 3. Default: 'src/server/adapters'
10
+ *
6
11
  * Uses require.resolve to dynamically locate packages, supporting:
7
12
  * - Modules in packages/ directory
8
13
  * - Modules in apps/ directory
@@ -1 +1 @@
1
- {"version":3,"file":"schema-discovery.d.ts","names":[],"sources":["../src/schema-discovery.ts"],"sourcesContent":[],"mappings":";;AAiHA;;;;;;;;;;;iBAAgB,oBAAA,CAAA"}
1
+ {"version":3,"file":"schema-discovery.d.ts","names":[],"sources":["../src/schema-discovery.ts"],"sourcesContent":[],"mappings":";;AAmJA;;;;;;;;;;;;;;;;iBAAgB,oBAAA,CAAA"}
@@ -93,37 +93,61 @@ function findPackageInWorkspace(packageName, projectRoot) {
93
93
  return null;
94
94
  }
95
95
  /**
96
- * Resolve a module's package root directory using require.resolve.
96
+ * Read package.json kuckit.schemaDir field if present.
97
+ */
98
+ function readPackageSchemaDir(packageRoot) {
99
+ try {
100
+ const pkgJsonPath = resolve(packageRoot, "package.json");
101
+ return JSON.parse(require("fs").readFileSync(pkgJsonPath, "utf-8")).kuckit?.schemaDir;
102
+ } catch {
103
+ return;
104
+ }
105
+ }
106
+ /**
107
+ * Resolve a module's package root directory and optional schemaDir from package.json.
97
108
  * Falls back to workspace scanning in monorepo context.
98
109
  *
99
110
  * @param packageName - NPM package name (e.g., '@kuckit/users-module')
100
- * @returns Absolute path to package root, or null if not found
111
+ * @returns Package info with root path and optional schemaDir, or null if not found
101
112
  */
102
- function resolvePackageRoot(packageName) {
113
+ function resolvePackageInfo(packageName) {
114
+ let root = null;
103
115
  try {
104
- return dirname(require.resolve(`${packageName}/package.json`));
116
+ root = dirname(require.resolve(`${packageName}/package.json`));
105
117
  } catch {
106
118
  try {
107
119
  let dir = dirname(require.resolve(packageName));
108
120
  for (let i = 0; i < 10; i++) {
109
- if (existsSync(resolve(dir, "package.json"))) return dir;
121
+ if (existsSync(resolve(dir, "package.json"))) {
122
+ root = dir;
123
+ break;
124
+ }
110
125
  const parent = dirname(dir);
111
126
  if (parent === dir) break;
112
127
  dir = parent;
113
128
  }
114
129
  } catch {}
115
130
  }
116
- const projectRoot = findProjectRoot();
117
- if (projectRoot) {
118
- const wsPath = findPackageInWorkspace(packageName, projectRoot);
119
- if (wsPath) return wsPath;
131
+ if (!root) {
132
+ const projectRoot = findProjectRoot();
133
+ if (projectRoot) root = findPackageInWorkspace(packageName, projectRoot);
120
134
  }
121
- return null;
135
+ if (!root) return null;
136
+ return {
137
+ root,
138
+ schemaDir: readPackageSchemaDir(root)
139
+ };
122
140
  }
141
+ const DEFAULT_SCHEMA_DIR = "src/server/adapters";
123
142
  /**
124
143
  * Get schema paths for Drizzle configuration.
125
144
  * Derives paths from kuckit.config.ts (single source of truth).
126
145
  *
146
+ * Schema directory priority:
147
+ * 1. kuckit.config.ts schemaDir option
148
+ * 2. package.json kuckit.schemaDir field
149
+ * 3. Default: 'src/server/adapters'
150
+ *
127
151
  * Uses require.resolve to dynamically locate packages, supporting:
128
152
  * - Modules in packages/ directory
129
153
  * - Modules in apps/ directory
@@ -137,9 +161,10 @@ function getModuleSchemaPaths() {
137
161
  const config = loadKuckitConfigSync();
138
162
  if (!config) return [coreSchema];
139
163
  return [coreSchema, ...config.modules.filter((m) => m.enabled !== false).map((m) => {
140
- const packageRoot = resolvePackageRoot(m.package);
141
- if (!packageRoot) return null;
142
- return resolve(packageRoot, m.schemaDir ?? "src/server/schema");
164
+ const pkgInfo = resolvePackageInfo(m.package);
165
+ if (!pkgInfo) return null;
166
+ const schemaDir = m.schemaDir ?? pkgInfo.schemaDir ?? DEFAULT_SCHEMA_DIR;
167
+ return resolve(pkgInfo.root, schemaDir);
143
168
  }).filter((p) => p !== null && existsSync(p))];
144
169
  }
145
170
 
@@ -1 +1 @@
1
- {"version":3,"file":"schema-discovery.js","names":["dirname","resolve","existsSync","createRequire"],"sources":["../../sdk/dist/loader-BJ2ClBV6.js","../src/schema-discovery.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\nimport { existsSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\n\n//#region rolldown:runtime\nvar __require = /* @__PURE__ */ createRequire(import.meta.url);\n\n//#endregion\n//#region src/config/loader.ts\nconst CONFIG_FILES = [\n\t\"kuckit.config.ts\",\n\t\"kuckit.config.js\",\n\t\"kuckit.config.mjs\"\n];\n/**\n* Find the config file path by searching from cwd upward\n*/\nfunction findConfigFile(cwd = process.cwd()) {\n\tlet dir = cwd;\n\twhile (dir !== dirname(dir)) {\n\t\tfor (const file of CONFIG_FILES) {\n\t\t\tconst configPath = resolve(dir, file);\n\t\t\tif (existsSync(configPath)) return configPath;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\tfor (const file of CONFIG_FILES) {\n\t\tconst configPath = resolve(dir, file);\n\t\tif (existsSync(configPath)) return configPath;\n\t}\n\treturn null;\n}\n/**\n* Check if a unified config file exists\n*/\nfunction hasUnifiedConfig(cwd = process.cwd()) {\n\treturn findConfigFile(cwd) !== null;\n}\n/**\n* Load Kuckit configuration from file\n*\n* Uses jiti for TypeScript support at runtime.\n* Falls back to dynamic import for JS/MJS files.\n*\n* @param cwd - Directory to start searching from (default: process.cwd())\n* @throws Error if config file not found or invalid\n*/\nasync function loadKuckitConfig(cwd = process.cwd()) {\n\tconst configPath = findConfigFile(cwd);\n\tif (!configPath) throw new Error(`No Kuckit config file found. Create a kuckit.config.ts at your project root.\\nSearched from: ${cwd}`);\n\tlet config;\n\tif (configPath.endsWith(\".ts\")) {\n\t\tconst { createJiti } = await import(\"jiti\");\n\t\tconst loaded = await createJiti(cwd, { interopDefault: true }).import(configPath);\n\t\tconfig = loaded.default ?? loaded;\n\t} else {\n\t\tconst loaded = await import(configPath);\n\t\tconfig = loaded.default ?? loaded;\n\t}\n\tif (!config || typeof config !== \"object\") throw new Error(`Invalid Kuckit config at ${configPath}: expected an object`);\n\tif (!Array.isArray(config.modules)) throw new Error(`Invalid Kuckit config at ${configPath}: 'modules' must be an array`);\n\treturn {\n\t\t...config,\n\t\t_configPath: configPath\n\t};\n}\n/**\n* Synchronously load config (for non-async contexts like drizzle.config.ts)\n* Uses jiti synchronously to load TypeScript config\n*/\nfunction loadKuckitConfigSync(cwd = process.cwd()) {\n\tconst configPath = findConfigFile(cwd);\n\tif (!configPath) return null;\n\ttry {\n\t\tconst { createJiti } = __require(\"jiti\");\n\t\tconst loaded = createJiti(cwd, { interopDefault: true })(configPath);\n\t\tconst config = loaded.default ?? loaded;\n\t\tif (!config || typeof config !== \"object\" || !Array.isArray(config.modules)) return null;\n\t\treturn {\n\t\t\t...config,\n\t\t\t_configPath: configPath\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n/**\n* Try to load config, returning null if not found\n*/\nasync function tryLoadKuckitConfig(cwd = process.cwd()) {\n\ttry {\n\t\treturn await loadKuckitConfig(cwd);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n//#endregion\nexport { tryLoadKuckitConfig as a, loadKuckitConfigSync as i, hasUnifiedConfig as n, loadKuckitConfig as r, findConfigFile as t };\n//# sourceMappingURL=loader-BJ2ClBV6.js.map","import { existsSync, readdirSync } from 'fs'\nimport { resolve, dirname } from 'path'\nimport { fileURLToPath } from 'url'\nimport { createRequire } from 'module'\nimport { loadKuckitConfigSync, type KuckitModuleConfig } from '@kuckit/sdk/config/node'\n\nconst currentDirPath = dirname(fileURLToPath(import.meta.url))\nconst require = createRequire(import.meta.url)\n\n/**\n * Find the monorepo/project root by walking up from current directory.\n * Looks for kuckit.config.ts or package.json with workspaces.\n */\nfunction findProjectRoot(): string | null {\n\tlet dir = currentDirPath\n\tfor (let i = 0; i < 10; i++) {\n\t\tif (existsSync(resolve(dir, 'kuckit.config.ts'))) {\n\t\t\treturn dir\n\t\t}\n\t\tconst parent = dirname(dir)\n\t\tif (parent === dir) break\n\t\tdir = parent\n\t}\n\treturn null\n}\n\n/**\n * Scan workspace directories (packages/, apps/) for a package.\n * Fallback when require.resolve fails in monorepo context.\n */\nfunction findPackageInWorkspace(packageName: string, projectRoot: string): string | null {\n\tconst workspaceDirs = ['packages', 'apps']\n\n\tfor (const wsDir of workspaceDirs) {\n\t\tconst wsPath = resolve(projectRoot, wsDir)\n\t\tif (!existsSync(wsPath)) continue\n\n\t\ttry {\n\t\t\tconst entries = readdirSync(wsPath, { withFileTypes: true })\n\t\t\tfor (const entry of entries) {\n\t\t\t\tif (!entry.isDirectory()) continue\n\n\t\t\t\tconst pkgJsonPath = resolve(wsPath, entry.name, 'package.json')\n\t\t\t\tif (!existsSync(pkgJsonPath)) continue\n\n\t\t\t\ttry {\n\t\t\t\t\tconst pkgJson = JSON.parse(require('fs').readFileSync(pkgJsonPath, 'utf-8'))\n\t\t\t\t\tif (pkgJson.name === packageName) {\n\t\t\t\t\t\treturn resolve(wsPath, entry.name)\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Skip invalid package.json\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Skip unreadable directories\n\t\t}\n\t}\n\treturn null\n}\n\n/**\n * Resolve a module's package root directory using require.resolve.\n * Falls back to workspace scanning in monorepo context.\n *\n * @param packageName - NPM package name (e.g., '@kuckit/users-module')\n * @returns Absolute path to package root, or null if not found\n */\nfunction resolvePackageRoot(packageName: string): string | null {\n\t// First try require.resolve (works for installed packages)\n\ttry {\n\t\tconst packageJsonPath = require.resolve(`${packageName}/package.json`)\n\t\treturn dirname(packageJsonPath)\n\t} catch {\n\t\t// Package not installed or doesn't have package.json exports\n\t\ttry {\n\t\t\tconst mainPath = require.resolve(packageName)\n\t\t\tlet dir = dirname(mainPath)\n\t\t\tfor (let i = 0; i < 10; i++) {\n\t\t\t\tif (existsSync(resolve(dir, 'package.json'))) {\n\t\t\t\t\treturn dir\n\t\t\t\t}\n\t\t\t\tconst parent = dirname(dir)\n\t\t\t\tif (parent === dir) break\n\t\t\t\tdir = parent\n\t\t\t}\n\t\t} catch {\n\t\t\t// Package not resolvable - try workspace scanning\n\t\t}\n\t}\n\n\t// Fallback: scan workspace directories (monorepo support)\n\tconst projectRoot = findProjectRoot()\n\tif (projectRoot) {\n\t\tconst wsPath = findPackageInWorkspace(packageName, projectRoot)\n\t\tif (wsPath) return wsPath\n\t}\n\n\treturn null\n}\n\n/**\n * Get schema paths for Drizzle configuration.\n * Derives paths from kuckit.config.ts (single source of truth).\n *\n * Uses require.resolve to dynamically locate packages, supporting:\n * - Modules in packages/ directory\n * - Modules in apps/ directory\n * - External modules in node_modules\n * - Nested package directories\n *\n * @returns Array of absolute paths to schema directories, starting with core schema\n */\nexport function getModuleSchemaPaths(): string[] {\n\tconst coreSchema = resolve(currentDirPath, './schema')\n\n\t// Load config using the SDK's pure config loader (no side effects)\n\tconst config = loadKuckitConfigSync()\n\tif (!config) {\n\t\t// Fall back to just core schema if no config found\n\t\treturn [coreSchema]\n\t}\n\n\tconst modulePaths = config.modules\n\t\t.filter((m: KuckitModuleConfig) => m.enabled !== false)\n\t\t.map((m: KuckitModuleConfig) => {\n\t\t\tconst packageRoot = resolvePackageRoot(m.package)\n\t\t\tif (!packageRoot) return null\n\n\t\t\tconst schemaDir = m.schemaDir ?? 'src/server/schema'\n\t\t\treturn resolve(packageRoot, schemaDir)\n\t\t})\n\t\t.filter((p): p is string => p !== null && existsSync(p))\n\n\treturn [coreSchema, ...modulePaths]\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"schema-discovery.js","names":["dirname","resolve","existsSync","createRequire","root: string | null"],"sources":["../../sdk/dist/loader-BJ2ClBV6.js","../src/schema-discovery.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\nimport { existsSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\n\n//#region rolldown:runtime\nvar __require = /* @__PURE__ */ createRequire(import.meta.url);\n\n//#endregion\n//#region src/config/loader.ts\nconst CONFIG_FILES = [\n\t\"kuckit.config.ts\",\n\t\"kuckit.config.js\",\n\t\"kuckit.config.mjs\"\n];\n/**\n* Find the config file path by searching from cwd upward\n*/\nfunction findConfigFile(cwd = process.cwd()) {\n\tlet dir = cwd;\n\twhile (dir !== dirname(dir)) {\n\t\tfor (const file of CONFIG_FILES) {\n\t\t\tconst configPath = resolve(dir, file);\n\t\t\tif (existsSync(configPath)) return configPath;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\tfor (const file of CONFIG_FILES) {\n\t\tconst configPath = resolve(dir, file);\n\t\tif (existsSync(configPath)) return configPath;\n\t}\n\treturn null;\n}\n/**\n* Check if a unified config file exists\n*/\nfunction hasUnifiedConfig(cwd = process.cwd()) {\n\treturn findConfigFile(cwd) !== null;\n}\n/**\n* Load Kuckit configuration from file\n*\n* Uses jiti for TypeScript support at runtime.\n* Falls back to dynamic import for JS/MJS files.\n*\n* @param cwd - Directory to start searching from (default: process.cwd())\n* @throws Error if config file not found or invalid\n*/\nasync function loadKuckitConfig(cwd = process.cwd()) {\n\tconst configPath = findConfigFile(cwd);\n\tif (!configPath) throw new Error(`No Kuckit config file found. Create a kuckit.config.ts at your project root.\\nSearched from: ${cwd}`);\n\tlet config;\n\tif (configPath.endsWith(\".ts\")) {\n\t\tconst { createJiti } = await import(\"jiti\");\n\t\tconst loaded = await createJiti(cwd, { interopDefault: true }).import(configPath);\n\t\tconfig = loaded.default ?? loaded;\n\t} else {\n\t\tconst loaded = await import(configPath);\n\t\tconfig = loaded.default ?? loaded;\n\t}\n\tif (!config || typeof config !== \"object\") throw new Error(`Invalid Kuckit config at ${configPath}: expected an object`);\n\tif (!Array.isArray(config.modules)) throw new Error(`Invalid Kuckit config at ${configPath}: 'modules' must be an array`);\n\treturn {\n\t\t...config,\n\t\t_configPath: configPath\n\t};\n}\n/**\n* Synchronously load config (for non-async contexts like drizzle.config.ts)\n* Uses jiti synchronously to load TypeScript config\n*/\nfunction loadKuckitConfigSync(cwd = process.cwd()) {\n\tconst configPath = findConfigFile(cwd);\n\tif (!configPath) return null;\n\ttry {\n\t\tconst { createJiti } = __require(\"jiti\");\n\t\tconst loaded = createJiti(cwd, { interopDefault: true })(configPath);\n\t\tconst config = loaded.default ?? loaded;\n\t\tif (!config || typeof config !== \"object\" || !Array.isArray(config.modules)) return null;\n\t\treturn {\n\t\t\t...config,\n\t\t\t_configPath: configPath\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n/**\n* Try to load config, returning null if not found\n*/\nasync function tryLoadKuckitConfig(cwd = process.cwd()) {\n\ttry {\n\t\treturn await loadKuckitConfig(cwd);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n//#endregion\nexport { tryLoadKuckitConfig as a, loadKuckitConfigSync as i, hasUnifiedConfig as n, loadKuckitConfig as r, findConfigFile as t };\n//# sourceMappingURL=loader-BJ2ClBV6.js.map","import { existsSync, readdirSync } from 'fs'\nimport { resolve, dirname } from 'path'\nimport { fileURLToPath } from 'url'\nimport { createRequire } from 'module'\nimport { loadKuckitConfigSync, type KuckitModuleConfig } from '@kuckit/sdk/config/node'\n\nconst currentDirPath = dirname(fileURLToPath(import.meta.url))\nconst require = createRequire(import.meta.url)\n\n/**\n * Find the monorepo/project root by walking up from current directory.\n * Looks for kuckit.config.ts or package.json with workspaces.\n */\nfunction findProjectRoot(): string | null {\n\tlet dir = currentDirPath\n\tfor (let i = 0; i < 10; i++) {\n\t\tif (existsSync(resolve(dir, 'kuckit.config.ts'))) {\n\t\t\treturn dir\n\t\t}\n\t\tconst parent = dirname(dir)\n\t\tif (parent === dir) break\n\t\tdir = parent\n\t}\n\treturn null\n}\n\n/**\n * Scan workspace directories (packages/, apps/) for a package.\n * Fallback when require.resolve fails in monorepo context.\n */\nfunction findPackageInWorkspace(packageName: string, projectRoot: string): string | null {\n\tconst workspaceDirs = ['packages', 'apps']\n\n\tfor (const wsDir of workspaceDirs) {\n\t\tconst wsPath = resolve(projectRoot, wsDir)\n\t\tif (!existsSync(wsPath)) continue\n\n\t\ttry {\n\t\t\tconst entries = readdirSync(wsPath, { withFileTypes: true })\n\t\t\tfor (const entry of entries) {\n\t\t\t\tif (!entry.isDirectory()) continue\n\n\t\t\t\tconst pkgJsonPath = resolve(wsPath, entry.name, 'package.json')\n\t\t\t\tif (!existsSync(pkgJsonPath)) continue\n\n\t\t\t\ttry {\n\t\t\t\t\tconst pkgJson = JSON.parse(require('fs').readFileSync(pkgJsonPath, 'utf-8'))\n\t\t\t\t\tif (pkgJson.name === packageName) {\n\t\t\t\t\t\treturn resolve(wsPath, entry.name)\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Skip invalid package.json\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Skip unreadable directories\n\t\t}\n\t}\n\treturn null\n}\n\ninterface PackageInfo {\n\troot: string\n\tschemaDir?: string\n}\n\n/**\n * Read package.json kuckit.schemaDir field if present.\n */\nfunction readPackageSchemaDir(packageRoot: string): string | undefined {\n\ttry {\n\t\tconst pkgJsonPath = resolve(packageRoot, 'package.json')\n\t\tconst pkgJson = JSON.parse(require('fs').readFileSync(pkgJsonPath, 'utf-8'))\n\t\treturn pkgJson.kuckit?.schemaDir\n\t} catch {\n\t\treturn undefined\n\t}\n}\n\n/**\n * Resolve a module's package root directory and optional schemaDir from package.json.\n * Falls back to workspace scanning in monorepo context.\n *\n * @param packageName - NPM package name (e.g., '@kuckit/users-module')\n * @returns Package info with root path and optional schemaDir, or null if not found\n */\nfunction resolvePackageInfo(packageName: string): PackageInfo | null {\n\tlet root: string | null = null\n\n\t// First try require.resolve (works for installed packages)\n\ttry {\n\t\tconst packageJsonPath = require.resolve(`${packageName}/package.json`)\n\t\troot = dirname(packageJsonPath)\n\t} catch {\n\t\t// Package not installed or doesn't have package.json exports\n\t\ttry {\n\t\t\tconst mainPath = require.resolve(packageName)\n\t\t\tlet dir = dirname(mainPath)\n\t\t\tfor (let i = 0; i < 10; i++) {\n\t\t\t\tif (existsSync(resolve(dir, 'package.json'))) {\n\t\t\t\t\troot = dir\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tconst parent = dirname(dir)\n\t\t\t\tif (parent === dir) break\n\t\t\t\tdir = parent\n\t\t\t}\n\t\t} catch {\n\t\t\t// Package not resolvable - try workspace scanning\n\t\t}\n\t}\n\n\t// Fallback: scan workspace directories (monorepo support)\n\tif (!root) {\n\t\tconst projectRoot = findProjectRoot()\n\t\tif (projectRoot) {\n\t\t\troot = findPackageInWorkspace(packageName, projectRoot)\n\t\t}\n\t}\n\n\tif (!root) return null\n\n\treturn {\n\t\troot,\n\t\tschemaDir: readPackageSchemaDir(root),\n\t}\n}\n\nconst DEFAULT_SCHEMA_DIR = 'src/server/adapters'\n\n/**\n * Get schema paths for Drizzle configuration.\n * Derives paths from kuckit.config.ts (single source of truth).\n *\n * Schema directory priority:\n * 1. kuckit.config.ts schemaDir option\n * 2. package.json kuckit.schemaDir field\n * 3. Default: 'src/server/adapters'\n *\n * Uses require.resolve to dynamically locate packages, supporting:\n * - Modules in packages/ directory\n * - Modules in apps/ directory\n * - External modules in node_modules\n * - Nested package directories\n *\n * @returns Array of absolute paths to schema directories, starting with core schema\n */\nexport function getModuleSchemaPaths(): string[] {\n\tconst coreSchema = resolve(currentDirPath, './schema')\n\n\t// Load config using the SDK's pure config loader (no side effects)\n\tconst config = loadKuckitConfigSync()\n\tif (!config) {\n\t\t// Fall back to just core schema if no config found\n\t\treturn [coreSchema]\n\t}\n\n\tconst modulePaths = config.modules\n\t\t.filter((m: KuckitModuleConfig) => m.enabled !== false)\n\t\t.map((m: KuckitModuleConfig) => {\n\t\t\tconst pkgInfo = resolvePackageInfo(m.package)\n\t\t\tif (!pkgInfo) return null\n\n\t\t\t// Priority: kuckit.config.ts > package.json kuckit.schemaDir > default\n\t\t\tconst schemaDir = m.schemaDir ?? pkgInfo.schemaDir ?? DEFAULT_SCHEMA_DIR\n\t\t\treturn resolve(pkgInfo.root, schemaDir)\n\t\t})\n\t\t.filter((p): p is string => p !== null && existsSync(p))\n\n\treturn [coreSchema, ...modulePaths]\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kuckit/db",
3
- "version": "3.0.8",
3
+ "version": "3.0.10",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",