@soda-gql/common 0.11.10 → 0.11.12
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/dist/{canonical-id-BJahCcrS.mjs → canonical-id-9alor9gv.mjs} +66 -7
- package/dist/canonical-id-9alor9gv.mjs.map +1 -0
- package/dist/{canonical-id-CgMNOZyn.cjs → canonical-id-DHdeYIsT.cjs} +76 -5
- package/dist/canonical-id-DHdeYIsT.cjs.map +1 -0
- package/dist/canonical-id.cjs +5 -3
- package/dist/canonical-id.d.cts +2 -2
- package/dist/canonical-id.d.mts +2 -2
- package/dist/canonical-id.mjs +3 -3
- package/dist/{index-Cm2Zwk9m.d.cts → index-AqkJhrm3.d.mts} +53 -3
- package/dist/index-AqkJhrm3.d.mts.map +1 -0
- package/dist/index-BCu9PNbZ.d.mts +139 -0
- package/dist/index-BCu9PNbZ.d.mts.map +1 -0
- package/dist/{index-D1tzB3W5.d.cts → index-BMa2_rDb.d.mts} +6 -35
- package/dist/index-BMa2_rDb.d.mts.map +1 -0
- package/dist/index-BMl8pzFY.d.cts +139 -0
- package/dist/index-BMl8pzFY.d.cts.map +1 -0
- package/dist/{index-B424kKYS.d.mts → index-CbQyueYV.d.cts} +6 -35
- package/dist/index-CbQyueYV.d.cts.map +1 -0
- package/dist/{index-CPpVc8Id.d.mts → index-DZSebwar.d.cts} +53 -3
- package/dist/index-DZSebwar.d.cts.map +1 -0
- package/dist/index-Dit86qkX.d.mts.map +1 -1
- package/dist/index.cjs +9 -7
- package/dist/index.d.cts +4 -4
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +4 -4
- package/dist/portable-B3K3IE7E.cjs +239 -0
- package/dist/portable-B3K3IE7E.cjs.map +1 -0
- package/dist/portable-BFrcBOaX.mjs +196 -0
- package/dist/portable-BFrcBOaX.mjs.map +1 -0
- package/dist/portable.cjs +2 -5
- package/dist/portable.d.cts +2 -2
- package/dist/portable.d.mts +2 -2
- package/dist/portable.mjs +2 -2
- package/dist/utils-Rs7YbafF.cjs +431 -0
- package/dist/utils-Rs7YbafF.cjs.map +1 -0
- package/dist/utils-ZCE_eqCf.mjs +371 -0
- package/dist/utils-ZCE_eqCf.mjs.map +1 -0
- package/dist/utils.cjs +4 -1
- package/dist/utils.d.cts +2 -2
- package/dist/utils.d.mts +2 -2
- package/dist/utils.mjs +2 -2
- package/dist/{zod-C_6JfuYV.cjs → zod-DjI3IUH3.cjs} +2 -2
- package/dist/{zod-C_6JfuYV.cjs.map → zod-DjI3IUH3.cjs.map} +1 -1
- package/dist/zod.cjs +1 -1
- package/package.json +1 -1
- package/dist/canonical-id-BJahCcrS.mjs.map +0 -1
- package/dist/canonical-id-CgMNOZyn.cjs.map +0 -1
- package/dist/index-B424kKYS.d.mts.map +0 -1
- package/dist/index-CPpVc8Id.d.mts.map +0 -1
- package/dist/index-Cm2Zwk9m.d.cts.map +0 -1
- package/dist/index-D1tzB3W5.d.cts.map +0 -1
- package/dist/index-Dv8spPt0.d.mts +0 -61
- package/dist/index-Dv8spPt0.d.mts.map +0 -1
- package/dist/index-LaXfl_e_.d.cts +0 -61
- package/dist/index-LaXfl_e_.d.cts.map +0 -1
- package/dist/portable-BT3ahkQN.mjs +0 -391
- package/dist/portable-BT3ahkQN.mjs.map +0 -1
- package/dist/portable-cJqkfeHw.cjs +0 -451
- package/dist/portable-cJqkfeHw.cjs.map +0 -1
- package/dist/utils-CsTwS1dw.cjs +0 -148
- package/dist/utils-CsTwS1dw.cjs.map +0 -1
- package/dist/utils-DLEgAn7q.mjs +0 -106
- package/dist/utils-DLEgAn7q.mjs.map +0 -1
|
@@ -1,11 +1,28 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { isAbsolute, resolve } from "node:path";
|
|
1
|
+
import { s as normalizePath } from "./utils-ZCE_eqCf.mjs";
|
|
2
|
+
import { isAbsolute, relative, resolve } from "node:path";
|
|
3
3
|
import z$1 from "zod";
|
|
4
4
|
|
|
5
5
|
//#region packages/common/src/canonical-id/canonical-id.ts
|
|
6
6
|
const canonicalIdSeparator = "::";
|
|
7
7
|
const CanonicalIdSchema = z$1.string();
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Create a canonical ID from a file path and AST path.
|
|
10
|
+
*
|
|
11
|
+
* @param filePath - The file path (absolute, or relative if baseDir is provided)
|
|
12
|
+
* @param astPath - The AST path identifying the definition within the file
|
|
13
|
+
* @param options - Optional configuration including baseDir for relative path support
|
|
14
|
+
* @returns A canonical ID in the format "{path}::{astPath}"
|
|
15
|
+
*/
|
|
16
|
+
const createCanonicalId = (filePath, astPath, options) => {
|
|
17
|
+
const { baseDir } = options ?? {};
|
|
18
|
+
if (baseDir) {
|
|
19
|
+
const absolutePath = isAbsolute(filePath) ? filePath : resolve(baseDir, filePath);
|
|
20
|
+
const resolved$1 = resolve(absolutePath);
|
|
21
|
+
const relativePath = relative(baseDir, resolved$1);
|
|
22
|
+
const normalized$1 = normalizePath(relativePath);
|
|
23
|
+
const idParts$1 = [normalized$1, astPath];
|
|
24
|
+
return idParts$1.join(canonicalIdSeparator);
|
|
25
|
+
}
|
|
9
26
|
if (!isAbsolute(filePath)) {
|
|
10
27
|
throw new Error("[INTERNAL] CANONICAL_ID_REQUIRES_ABSOLUTE_PATH");
|
|
11
28
|
}
|
|
@@ -15,6 +32,16 @@ const createCanonicalId = (filePath, astPath) => {
|
|
|
15
32
|
return idParts.join(canonicalIdSeparator);
|
|
16
33
|
};
|
|
17
34
|
/**
|
|
35
|
+
* Check if a canonical ID uses a relative path.
|
|
36
|
+
* Relative canonical IDs do not start with '/'.
|
|
37
|
+
*
|
|
38
|
+
* @param canonicalId - The canonical ID to check
|
|
39
|
+
* @returns true if the canonical ID uses a relative path
|
|
40
|
+
*/
|
|
41
|
+
const isRelativeCanonicalId = (canonicalId) => {
|
|
42
|
+
return !canonicalId.startsWith("/");
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
18
45
|
* Parse a canonical ID into its components.
|
|
19
46
|
* @param canonicalId - The canonical ID to parse (e.g., "/app/src/user.ts::userFragment")
|
|
20
47
|
* @returns An object with filePath and astPath
|
|
@@ -32,6 +59,38 @@ const parseCanonicalId = (canonicalId) => {
|
|
|
32
59
|
astPath: canonicalId.slice(idx + canonicalIdSeparator.length)
|
|
33
60
|
};
|
|
34
61
|
};
|
|
62
|
+
/**
|
|
63
|
+
* Validate a canonical ID format.
|
|
64
|
+
* A valid canonical ID has format: "{filePath}::{astPath}"
|
|
65
|
+
* where both filePath and astPath are non-empty.
|
|
66
|
+
*
|
|
67
|
+
* @param canonicalId - The canonical ID to validate
|
|
68
|
+
* @returns Validation result with isValid boolean and optional error reason
|
|
69
|
+
*/
|
|
70
|
+
const validateCanonicalId = (canonicalId) => {
|
|
71
|
+
const idx = canonicalId.indexOf(canonicalIdSeparator);
|
|
72
|
+
if (idx === -1) {
|
|
73
|
+
return {
|
|
74
|
+
isValid: false,
|
|
75
|
+
reason: "missing '::' separator"
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const filePath = canonicalId.slice(0, idx);
|
|
79
|
+
const astPath = canonicalId.slice(idx + canonicalIdSeparator.length);
|
|
80
|
+
if (filePath === "") {
|
|
81
|
+
return {
|
|
82
|
+
isValid: false,
|
|
83
|
+
reason: "empty file path"
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
if (astPath === "") {
|
|
87
|
+
return {
|
|
88
|
+
isValid: false,
|
|
89
|
+
reason: "empty AST path"
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
return { isValid: true };
|
|
93
|
+
};
|
|
35
94
|
|
|
36
95
|
//#endregion
|
|
37
96
|
//#region packages/common/src/canonical-id/path-tracker.ts
|
|
@@ -68,7 +127,7 @@ const _buildAstPath = (stack) => {
|
|
|
68
127
|
* ```
|
|
69
128
|
*/
|
|
70
129
|
const createCanonicalTracker = (options) => {
|
|
71
|
-
const { filePath, getExportName } = options;
|
|
130
|
+
const { filePath, baseDir, getExportName } = options;
|
|
72
131
|
const scopeStack = [];
|
|
73
132
|
const occurrenceCounters = new Map();
|
|
74
133
|
const usedPaths = new Set();
|
|
@@ -124,7 +183,7 @@ const createCanonicalTracker = (options) => {
|
|
|
124
183
|
};
|
|
125
184
|
},
|
|
126
185
|
resolveCanonicalId(astPath) {
|
|
127
|
-
return createCanonicalId(filePath, astPath);
|
|
186
|
+
return createCanonicalId(filePath, astPath, { baseDir });
|
|
128
187
|
},
|
|
129
188
|
registerExportBinding(local, exported) {
|
|
130
189
|
exportBindings.set(local, exported);
|
|
@@ -169,5 +228,5 @@ const buildAstPath = (stack) => {
|
|
|
169
228
|
};
|
|
170
229
|
|
|
171
230
|
//#endregion
|
|
172
|
-
export { CanonicalIdSchema as a, createPathTracker as i, createCanonicalTracker as n, createCanonicalId as o, createOccurrenceTracker as r,
|
|
173
|
-
//# sourceMappingURL=canonical-id-
|
|
231
|
+
export { CanonicalIdSchema as a, parseCanonicalId as c, createPathTracker as i, validateCanonicalId as l, createCanonicalTracker as n, createCanonicalId as o, createOccurrenceTracker as r, isRelativeCanonicalId as s, buildAstPath as t };
|
|
232
|
+
//# sourceMappingURL=canonical-id-9alor9gv.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canonical-id-9alor9gv.mjs","names":["CanonicalIdSchema: z.ZodType<CanonicalId>","z","resolved","normalized","idParts","scopeStack: ScopeFrame[]","frame: ScopeFrame","exportBinding: string | undefined"],"sources":["../src/canonical-id/canonical-id.ts","../src/canonical-id/path-tracker.ts"],"sourcesContent":["import { isAbsolute, relative, resolve } from \"node:path\";\nimport z from \"zod\";\nimport { normalizePath } from \"../utils\";\n\nexport type CanonicalId = string & { readonly __brand: \"CanonicalId\" };\n\nconst canonicalIdSeparator = \"::\" as const;\n\nexport const CanonicalIdSchema: z.ZodType<CanonicalId> = z.string() as unknown as z.ZodType<CanonicalId>;\n\n/**\n * Options for creating a canonical ID.\n */\nexport type CreateCanonicalIdOptions = {\n /**\n * Base directory for relative path computation.\n * When provided, the canonical ID will use a relative path from baseDir.\n * When undefined, an absolute path is required and used as-is.\n */\n readonly baseDir?: string;\n};\n\n/**\n * Create a canonical ID from a file path and AST path.\n *\n * @param filePath - The file path (absolute, or relative if baseDir is provided)\n * @param astPath - The AST path identifying the definition within the file\n * @param options - Optional configuration including baseDir for relative path support\n * @returns A canonical ID in the format \"{path}::{astPath}\"\n */\nexport const createCanonicalId = (filePath: string, astPath: string, options?: CreateCanonicalIdOptions): CanonicalId => {\n const { baseDir } = options ?? {};\n\n if (baseDir) {\n // With baseDir, compute relative path\n const absolutePath = isAbsolute(filePath) ? filePath : resolve(baseDir, filePath);\n const resolved = resolve(absolutePath);\n const relativePath = relative(baseDir, resolved);\n const normalized = normalizePath(relativePath);\n\n const idParts = [normalized, astPath];\n return idParts.join(canonicalIdSeparator) as CanonicalId;\n }\n\n // Without baseDir, require absolute path (legacy behavior)\n if (!isAbsolute(filePath)) {\n throw new Error(\"[INTERNAL] CANONICAL_ID_REQUIRES_ABSOLUTE_PATH\");\n }\n\n const resolved = resolve(filePath);\n const normalized = normalizePath(resolved);\n\n // Create a 2-part ID: {absPath}::{astPath}\n // astPath uniquely identifies the definition's location in the AST (e.g., \"MyComponent.useQuery.def\")\n const idParts = [normalized, astPath];\n\n return idParts.join(canonicalIdSeparator) as CanonicalId;\n};\n\n/**\n * Check if a canonical ID uses a relative path.\n * Relative canonical IDs do not start with '/'.\n *\n * @param canonicalId - The canonical ID to check\n * @returns true if the canonical ID uses a relative path\n */\nexport const isRelativeCanonicalId = (canonicalId: CanonicalId | string): boolean => {\n return !canonicalId.startsWith(\"/\");\n};\n\n/**\n * Parse a canonical ID into its components.\n * @param canonicalId - The canonical ID to parse (e.g., \"/app/src/user.ts::userFragment\")\n * @returns An object with filePath and astPath\n */\nexport const parseCanonicalId = (\n canonicalId: CanonicalId | string,\n): {\n filePath: string;\n astPath: string;\n} => {\n const idx = canonicalId.indexOf(canonicalIdSeparator);\n if (idx === -1) {\n return { filePath: canonicalId, astPath: \"\" };\n }\n return {\n filePath: canonicalId.slice(0, idx),\n astPath: canonicalId.slice(idx + canonicalIdSeparator.length),\n };\n};\n\n/**\n * Validation result for canonical ID format.\n */\nexport type CanonicalIdValidationResult = { readonly isValid: true } | { readonly isValid: false; readonly reason: string };\n\n/**\n * Validate a canonical ID format.\n * A valid canonical ID has format: \"{filePath}::{astPath}\"\n * where both filePath and astPath are non-empty.\n *\n * @param canonicalId - The canonical ID to validate\n * @returns Validation result with isValid boolean and optional error reason\n */\nexport const validateCanonicalId = (canonicalId: string): CanonicalIdValidationResult => {\n const idx = canonicalId.indexOf(canonicalIdSeparator);\n\n if (idx === -1) {\n return { isValid: false, reason: \"missing '::' separator\" };\n }\n\n const filePath = canonicalId.slice(0, idx);\n const astPath = canonicalId.slice(idx + canonicalIdSeparator.length);\n\n if (filePath === \"\") {\n return { isValid: false, reason: \"empty file path\" };\n }\n\n if (astPath === \"\") {\n return { isValid: false, reason: \"empty AST path\" };\n }\n\n return { isValid: true };\n};\n","/**\n * Canonical path tracker for AST traversal.\n *\n * This module provides a stateful helper that tracks scope information during\n * AST traversal to generate canonical IDs. It's designed to integrate with\n * existing plugin visitor patterns (Babel, SWC, TypeScript) without requiring\n * a separate AST traversal.\n *\n * Usage pattern:\n * 1. Plugin creates tracker at file/program entry\n * 2. Plugin calls enterScope/exitScope during its traversal\n * 3. Plugin calls registerDefinition when discovering GQL definitions\n * 4. Tracker provides canonical ID information\n */\n\nimport type { CanonicalId } from \"./canonical-id\";\nimport { createCanonicalId } from \"./canonical-id\";\n\n/**\n * Scope frame for tracking AST path segments\n */\nexport type ScopeFrame = {\n /** Name segment (e.g., \"MyComponent\", \"useQuery\", \"arrow#1\") */\n readonly nameSegment: string;\n /** Kind of scope */\n readonly kind: \"function\" | \"class\" | \"variable\" | \"property\" | \"method\" | \"expression\";\n /** Occurrence index for disambiguation */\n readonly occurrence: number;\n};\n\n/**\n * Opaque handle for scope tracking\n */\nexport type ScopeHandle = {\n readonly __brand: \"ScopeHandle\";\n readonly depth: number;\n};\n\n/**\n * Canonical path tracker interface\n */\nexport interface CanonicalPathTracker {\n /**\n * Enter a new scope during traversal\n * @param options Scope information\n * @returns Handle to use when exiting the scope\n */\n enterScope(options: { segment: string; kind: ScopeFrame[\"kind\"]; stableKey?: string }): ScopeHandle;\n\n /**\n * Exit a scope during traversal\n * @param handle Handle returned from enterScope\n */\n exitScope(handle: ScopeHandle): void;\n\n /**\n * Register a definition discovered during traversal\n * @returns Definition metadata including astPath and canonical ID information\n */\n registerDefinition(): {\n astPath: string;\n isTopLevel: boolean;\n exportBinding?: string;\n };\n\n /**\n * Resolve a canonical ID from an astPath\n * @param astPath AST path string\n * @returns Canonical ID\n */\n resolveCanonicalId(astPath: string): CanonicalId;\n\n /**\n * Register an export binding\n * @param local Local variable name\n * @param exported Exported name\n */\n registerExportBinding(local: string, exported: string): void;\n\n /**\n * Get current scope depth\n * @returns Current depth (0 = top level)\n */\n currentDepth(): number;\n}\n\n/**\n * Build AST path from scope stack (internal helper)\n */\nconst _buildAstPath = (stack: readonly ScopeFrame[]): string => {\n return stack.map((frame) => frame.nameSegment).join(\".\");\n};\n\n/**\n * Create a canonical path tracker\n *\n * @param options Configuration options\n * @returns Tracker instance\n *\n * @example\n * ```typescript\n * // In a Babel plugin\n * const tracker = createCanonicalTracker({ filePath: state.filename });\n *\n * const visitor = {\n * FunctionDeclaration: {\n * enter(path) {\n * const handle = tracker.enterScope({\n * segment: path.node.id.name,\n * kind: 'function'\n * });\n * },\n * exit(path) {\n * tracker.exitScope(handle);\n * }\n * }\n * };\n * ```\n */\nexport const createCanonicalTracker = (options: {\n filePath: string;\n /**\n * Base directory for relative path computation in canonical IDs.\n * When provided, canonical IDs will use relative paths from baseDir.\n */\n baseDir?: string;\n getExportName?: (localName: string) => string | undefined;\n}): CanonicalPathTracker => {\n const { filePath, baseDir, getExportName } = options;\n\n // Scope stack\n const scopeStack: ScopeFrame[] = [];\n\n // Occurrence counters for disambiguating duplicate names\n const occurrenceCounters = new Map<string, number>();\n\n // Used paths for ensuring uniqueness\n const usedPaths = new Set<string>();\n\n // Export bindings map\n const exportBindings = new Map<string, string>();\n\n const getNextOccurrence = (key: string): number => {\n const current = occurrenceCounters.get(key) ?? 0;\n occurrenceCounters.set(key, current + 1);\n return current;\n };\n\n const ensureUniquePath = (basePath: string): string => {\n let path = basePath;\n let suffix = 0;\n while (usedPaths.has(path)) {\n suffix++;\n path = `${basePath}$${suffix}`;\n }\n usedPaths.add(path);\n return path;\n };\n\n return {\n enterScope({ segment, kind, stableKey }): ScopeHandle {\n const key = stableKey ?? `${kind}:${segment}`;\n const occurrence = getNextOccurrence(key);\n\n const frame: ScopeFrame = {\n nameSegment: segment,\n kind,\n occurrence,\n };\n\n scopeStack.push(frame);\n\n return {\n __brand: \"ScopeHandle\",\n depth: scopeStack.length - 1,\n } as ScopeHandle;\n },\n\n exitScope(handle: ScopeHandle): void {\n // Validate handle depth matches current stack\n if (handle.depth !== scopeStack.length - 1) {\n throw new Error(`[INTERNAL] Invalid scope exit: expected depth ${scopeStack.length - 1}, got ${handle.depth}`);\n }\n scopeStack.pop();\n },\n\n registerDefinition(): {\n astPath: string;\n isTopLevel: boolean;\n exportBinding?: string;\n } {\n const basePath = _buildAstPath(scopeStack);\n const astPath = ensureUniquePath(basePath);\n const isTopLevel = scopeStack.length === 0;\n\n // Check export binding if provided\n let exportBinding: string | undefined;\n if (getExportName && isTopLevel) {\n // For top-level definitions, try to get export name\n // This is a simplified version - real logic depends on how the definition is bound\n exportBinding = undefined;\n }\n\n return {\n astPath,\n isTopLevel,\n exportBinding,\n };\n },\n\n resolveCanonicalId(astPath: string): CanonicalId {\n return createCanonicalId(filePath, astPath, { baseDir });\n },\n\n registerExportBinding(local: string, exported: string): void {\n exportBindings.set(local, exported);\n },\n\n currentDepth(): number {\n return scopeStack.length;\n },\n };\n};\n\n/**\n * Helper to create occurrence tracker (for backward compatibility)\n */\nexport const createOccurrenceTracker = (): {\n getNextOccurrence: (key: string) => number;\n} => {\n const occurrenceCounters = new Map<string, number>();\n\n return {\n getNextOccurrence(key: string): number {\n const current = occurrenceCounters.get(key) ?? 0;\n occurrenceCounters.set(key, current + 1);\n return current;\n },\n };\n};\n\n/**\n * Helper to create path tracker (for backward compatibility)\n */\nexport const createPathTracker = (): {\n ensureUniquePath: (basePath: string) => string;\n} => {\n const usedPaths = new Set<string>();\n\n return {\n ensureUniquePath(basePath: string): string {\n let path = basePath;\n let suffix = 0;\n while (usedPaths.has(path)) {\n suffix++;\n path = `${basePath}$${suffix}`;\n }\n usedPaths.add(path);\n return path;\n },\n };\n};\n\n/**\n * Build AST path from scope stack (for backward compatibility)\n */\nexport const buildAstPath = (stack: readonly ScopeFrame[]): string => {\n return stack.map((frame) => frame.nameSegment).join(\".\");\n};\n"],"mappings":"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"}
|
|
@@ -25,7 +25,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
25
25
|
}) : target, mod));
|
|
26
26
|
|
|
27
27
|
//#endregion
|
|
28
|
-
const require_utils = require('./utils-
|
|
28
|
+
const require_utils = require('./utils-Rs7YbafF.cjs');
|
|
29
29
|
let node_path = require("node:path");
|
|
30
30
|
let zod = require("zod");
|
|
31
31
|
zod = __toESM(zod);
|
|
@@ -33,7 +33,24 @@ zod = __toESM(zod);
|
|
|
33
33
|
//#region packages/common/src/canonical-id/canonical-id.ts
|
|
34
34
|
const canonicalIdSeparator = "::";
|
|
35
35
|
const CanonicalIdSchema = zod.default.string();
|
|
36
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Create a canonical ID from a file path and AST path.
|
|
38
|
+
*
|
|
39
|
+
* @param filePath - The file path (absolute, or relative if baseDir is provided)
|
|
40
|
+
* @param astPath - The AST path identifying the definition within the file
|
|
41
|
+
* @param options - Optional configuration including baseDir for relative path support
|
|
42
|
+
* @returns A canonical ID in the format "{path}::{astPath}"
|
|
43
|
+
*/
|
|
44
|
+
const createCanonicalId = (filePath, astPath, options) => {
|
|
45
|
+
const { baseDir } = options ?? {};
|
|
46
|
+
if (baseDir) {
|
|
47
|
+
const absolutePath = (0, node_path.isAbsolute)(filePath) ? filePath : (0, node_path.resolve)(baseDir, filePath);
|
|
48
|
+
const resolved$1 = (0, node_path.resolve)(absolutePath);
|
|
49
|
+
const relativePath = (0, node_path.relative)(baseDir, resolved$1);
|
|
50
|
+
const normalized$1 = require_utils.normalizePath(relativePath);
|
|
51
|
+
const idParts$1 = [normalized$1, astPath];
|
|
52
|
+
return idParts$1.join(canonicalIdSeparator);
|
|
53
|
+
}
|
|
37
54
|
if (!(0, node_path.isAbsolute)(filePath)) {
|
|
38
55
|
throw new Error("[INTERNAL] CANONICAL_ID_REQUIRES_ABSOLUTE_PATH");
|
|
39
56
|
}
|
|
@@ -43,6 +60,16 @@ const createCanonicalId = (filePath, astPath) => {
|
|
|
43
60
|
return idParts.join(canonicalIdSeparator);
|
|
44
61
|
};
|
|
45
62
|
/**
|
|
63
|
+
* Check if a canonical ID uses a relative path.
|
|
64
|
+
* Relative canonical IDs do not start with '/'.
|
|
65
|
+
*
|
|
66
|
+
* @param canonicalId - The canonical ID to check
|
|
67
|
+
* @returns true if the canonical ID uses a relative path
|
|
68
|
+
*/
|
|
69
|
+
const isRelativeCanonicalId = (canonicalId) => {
|
|
70
|
+
return !canonicalId.startsWith("/");
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
46
73
|
* Parse a canonical ID into its components.
|
|
47
74
|
* @param canonicalId - The canonical ID to parse (e.g., "/app/src/user.ts::userFragment")
|
|
48
75
|
* @returns An object with filePath and astPath
|
|
@@ -60,6 +87,38 @@ const parseCanonicalId = (canonicalId) => {
|
|
|
60
87
|
astPath: canonicalId.slice(idx + canonicalIdSeparator.length)
|
|
61
88
|
};
|
|
62
89
|
};
|
|
90
|
+
/**
|
|
91
|
+
* Validate a canonical ID format.
|
|
92
|
+
* A valid canonical ID has format: "{filePath}::{astPath}"
|
|
93
|
+
* where both filePath and astPath are non-empty.
|
|
94
|
+
*
|
|
95
|
+
* @param canonicalId - The canonical ID to validate
|
|
96
|
+
* @returns Validation result with isValid boolean and optional error reason
|
|
97
|
+
*/
|
|
98
|
+
const validateCanonicalId = (canonicalId) => {
|
|
99
|
+
const idx = canonicalId.indexOf(canonicalIdSeparator);
|
|
100
|
+
if (idx === -1) {
|
|
101
|
+
return {
|
|
102
|
+
isValid: false,
|
|
103
|
+
reason: "missing '::' separator"
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
const filePath = canonicalId.slice(0, idx);
|
|
107
|
+
const astPath = canonicalId.slice(idx + canonicalIdSeparator.length);
|
|
108
|
+
if (filePath === "") {
|
|
109
|
+
return {
|
|
110
|
+
isValid: false,
|
|
111
|
+
reason: "empty file path"
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
if (astPath === "") {
|
|
115
|
+
return {
|
|
116
|
+
isValid: false,
|
|
117
|
+
reason: "empty AST path"
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
return { isValid: true };
|
|
121
|
+
};
|
|
63
122
|
|
|
64
123
|
//#endregion
|
|
65
124
|
//#region packages/common/src/canonical-id/path-tracker.ts
|
|
@@ -96,7 +155,7 @@ const _buildAstPath = (stack) => {
|
|
|
96
155
|
* ```
|
|
97
156
|
*/
|
|
98
157
|
const createCanonicalTracker = (options) => {
|
|
99
|
-
const { filePath, getExportName } = options;
|
|
158
|
+
const { filePath, baseDir, getExportName } = options;
|
|
100
159
|
const scopeStack = [];
|
|
101
160
|
const occurrenceCounters = new Map();
|
|
102
161
|
const usedPaths = new Set();
|
|
@@ -152,7 +211,7 @@ const createCanonicalTracker = (options) => {
|
|
|
152
211
|
};
|
|
153
212
|
},
|
|
154
213
|
resolveCanonicalId(astPath) {
|
|
155
|
-
return createCanonicalId(filePath, astPath);
|
|
214
|
+
return createCanonicalId(filePath, astPath, { baseDir });
|
|
156
215
|
},
|
|
157
216
|
registerExportBinding(local, exported) {
|
|
158
217
|
exportBindings.set(local, exported);
|
|
@@ -239,10 +298,22 @@ Object.defineProperty(exports, 'createPathTracker', {
|
|
|
239
298
|
return createPathTracker;
|
|
240
299
|
}
|
|
241
300
|
});
|
|
301
|
+
Object.defineProperty(exports, 'isRelativeCanonicalId', {
|
|
302
|
+
enumerable: true,
|
|
303
|
+
get: function () {
|
|
304
|
+
return isRelativeCanonicalId;
|
|
305
|
+
}
|
|
306
|
+
});
|
|
242
307
|
Object.defineProperty(exports, 'parseCanonicalId', {
|
|
243
308
|
enumerable: true,
|
|
244
309
|
get: function () {
|
|
245
310
|
return parseCanonicalId;
|
|
246
311
|
}
|
|
247
312
|
});
|
|
248
|
-
|
|
313
|
+
Object.defineProperty(exports, 'validateCanonicalId', {
|
|
314
|
+
enumerable: true,
|
|
315
|
+
get: function () {
|
|
316
|
+
return validateCanonicalId;
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
//# sourceMappingURL=canonical-id-DHdeYIsT.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canonical-id-DHdeYIsT.cjs","names":["CanonicalIdSchema: z.ZodType<CanonicalId>","z","resolved","normalized","normalizePath","idParts","scopeStack: ScopeFrame[]","frame: ScopeFrame","exportBinding: string | undefined"],"sources":["../src/canonical-id/canonical-id.ts","../src/canonical-id/path-tracker.ts"],"sourcesContent":["import { isAbsolute, relative, resolve } from \"node:path\";\nimport z from \"zod\";\nimport { normalizePath } from \"../utils\";\n\nexport type CanonicalId = string & { readonly __brand: \"CanonicalId\" };\n\nconst canonicalIdSeparator = \"::\" as const;\n\nexport const CanonicalIdSchema: z.ZodType<CanonicalId> = z.string() as unknown as z.ZodType<CanonicalId>;\n\n/**\n * Options for creating a canonical ID.\n */\nexport type CreateCanonicalIdOptions = {\n /**\n * Base directory for relative path computation.\n * When provided, the canonical ID will use a relative path from baseDir.\n * When undefined, an absolute path is required and used as-is.\n */\n readonly baseDir?: string;\n};\n\n/**\n * Create a canonical ID from a file path and AST path.\n *\n * @param filePath - The file path (absolute, or relative if baseDir is provided)\n * @param astPath - The AST path identifying the definition within the file\n * @param options - Optional configuration including baseDir for relative path support\n * @returns A canonical ID in the format \"{path}::{astPath}\"\n */\nexport const createCanonicalId = (filePath: string, astPath: string, options?: CreateCanonicalIdOptions): CanonicalId => {\n const { baseDir } = options ?? {};\n\n if (baseDir) {\n // With baseDir, compute relative path\n const absolutePath = isAbsolute(filePath) ? filePath : resolve(baseDir, filePath);\n const resolved = resolve(absolutePath);\n const relativePath = relative(baseDir, resolved);\n const normalized = normalizePath(relativePath);\n\n const idParts = [normalized, astPath];\n return idParts.join(canonicalIdSeparator) as CanonicalId;\n }\n\n // Without baseDir, require absolute path (legacy behavior)\n if (!isAbsolute(filePath)) {\n throw new Error(\"[INTERNAL] CANONICAL_ID_REQUIRES_ABSOLUTE_PATH\");\n }\n\n const resolved = resolve(filePath);\n const normalized = normalizePath(resolved);\n\n // Create a 2-part ID: {absPath}::{astPath}\n // astPath uniquely identifies the definition's location in the AST (e.g., \"MyComponent.useQuery.def\")\n const idParts = [normalized, astPath];\n\n return idParts.join(canonicalIdSeparator) as CanonicalId;\n};\n\n/**\n * Check if a canonical ID uses a relative path.\n * Relative canonical IDs do not start with '/'.\n *\n * @param canonicalId - The canonical ID to check\n * @returns true if the canonical ID uses a relative path\n */\nexport const isRelativeCanonicalId = (canonicalId: CanonicalId | string): boolean => {\n return !canonicalId.startsWith(\"/\");\n};\n\n/**\n * Parse a canonical ID into its components.\n * @param canonicalId - The canonical ID to parse (e.g., \"/app/src/user.ts::userFragment\")\n * @returns An object with filePath and astPath\n */\nexport const parseCanonicalId = (\n canonicalId: CanonicalId | string,\n): {\n filePath: string;\n astPath: string;\n} => {\n const idx = canonicalId.indexOf(canonicalIdSeparator);\n if (idx === -1) {\n return { filePath: canonicalId, astPath: \"\" };\n }\n return {\n filePath: canonicalId.slice(0, idx),\n astPath: canonicalId.slice(idx + canonicalIdSeparator.length),\n };\n};\n\n/**\n * Validation result for canonical ID format.\n */\nexport type CanonicalIdValidationResult = { readonly isValid: true } | { readonly isValid: false; readonly reason: string };\n\n/**\n * Validate a canonical ID format.\n * A valid canonical ID has format: \"{filePath}::{astPath}\"\n * where both filePath and astPath are non-empty.\n *\n * @param canonicalId - The canonical ID to validate\n * @returns Validation result with isValid boolean and optional error reason\n */\nexport const validateCanonicalId = (canonicalId: string): CanonicalIdValidationResult => {\n const idx = canonicalId.indexOf(canonicalIdSeparator);\n\n if (idx === -1) {\n return { isValid: false, reason: \"missing '::' separator\" };\n }\n\n const filePath = canonicalId.slice(0, idx);\n const astPath = canonicalId.slice(idx + canonicalIdSeparator.length);\n\n if (filePath === \"\") {\n return { isValid: false, reason: \"empty file path\" };\n }\n\n if (astPath === \"\") {\n return { isValid: false, reason: \"empty AST path\" };\n }\n\n return { isValid: true };\n};\n","/**\n * Canonical path tracker for AST traversal.\n *\n * This module provides a stateful helper that tracks scope information during\n * AST traversal to generate canonical IDs. It's designed to integrate with\n * existing plugin visitor patterns (Babel, SWC, TypeScript) without requiring\n * a separate AST traversal.\n *\n * Usage pattern:\n * 1. Plugin creates tracker at file/program entry\n * 2. Plugin calls enterScope/exitScope during its traversal\n * 3. Plugin calls registerDefinition when discovering GQL definitions\n * 4. Tracker provides canonical ID information\n */\n\nimport type { CanonicalId } from \"./canonical-id\";\nimport { createCanonicalId } from \"./canonical-id\";\n\n/**\n * Scope frame for tracking AST path segments\n */\nexport type ScopeFrame = {\n /** Name segment (e.g., \"MyComponent\", \"useQuery\", \"arrow#1\") */\n readonly nameSegment: string;\n /** Kind of scope */\n readonly kind: \"function\" | \"class\" | \"variable\" | \"property\" | \"method\" | \"expression\";\n /** Occurrence index for disambiguation */\n readonly occurrence: number;\n};\n\n/**\n * Opaque handle for scope tracking\n */\nexport type ScopeHandle = {\n readonly __brand: \"ScopeHandle\";\n readonly depth: number;\n};\n\n/**\n * Canonical path tracker interface\n */\nexport interface CanonicalPathTracker {\n /**\n * Enter a new scope during traversal\n * @param options Scope information\n * @returns Handle to use when exiting the scope\n */\n enterScope(options: { segment: string; kind: ScopeFrame[\"kind\"]; stableKey?: string }): ScopeHandle;\n\n /**\n * Exit a scope during traversal\n * @param handle Handle returned from enterScope\n */\n exitScope(handle: ScopeHandle): void;\n\n /**\n * Register a definition discovered during traversal\n * @returns Definition metadata including astPath and canonical ID information\n */\n registerDefinition(): {\n astPath: string;\n isTopLevel: boolean;\n exportBinding?: string;\n };\n\n /**\n * Resolve a canonical ID from an astPath\n * @param astPath AST path string\n * @returns Canonical ID\n */\n resolveCanonicalId(astPath: string): CanonicalId;\n\n /**\n * Register an export binding\n * @param local Local variable name\n * @param exported Exported name\n */\n registerExportBinding(local: string, exported: string): void;\n\n /**\n * Get current scope depth\n * @returns Current depth (0 = top level)\n */\n currentDepth(): number;\n}\n\n/**\n * Build AST path from scope stack (internal helper)\n */\nconst _buildAstPath = (stack: readonly ScopeFrame[]): string => {\n return stack.map((frame) => frame.nameSegment).join(\".\");\n};\n\n/**\n * Create a canonical path tracker\n *\n * @param options Configuration options\n * @returns Tracker instance\n *\n * @example\n * ```typescript\n * // In a Babel plugin\n * const tracker = createCanonicalTracker({ filePath: state.filename });\n *\n * const visitor = {\n * FunctionDeclaration: {\n * enter(path) {\n * const handle = tracker.enterScope({\n * segment: path.node.id.name,\n * kind: 'function'\n * });\n * },\n * exit(path) {\n * tracker.exitScope(handle);\n * }\n * }\n * };\n * ```\n */\nexport const createCanonicalTracker = (options: {\n filePath: string;\n /**\n * Base directory for relative path computation in canonical IDs.\n * When provided, canonical IDs will use relative paths from baseDir.\n */\n baseDir?: string;\n getExportName?: (localName: string) => string | undefined;\n}): CanonicalPathTracker => {\n const { filePath, baseDir, getExportName } = options;\n\n // Scope stack\n const scopeStack: ScopeFrame[] = [];\n\n // Occurrence counters for disambiguating duplicate names\n const occurrenceCounters = new Map<string, number>();\n\n // Used paths for ensuring uniqueness\n const usedPaths = new Set<string>();\n\n // Export bindings map\n const exportBindings = new Map<string, string>();\n\n const getNextOccurrence = (key: string): number => {\n const current = occurrenceCounters.get(key) ?? 0;\n occurrenceCounters.set(key, current + 1);\n return current;\n };\n\n const ensureUniquePath = (basePath: string): string => {\n let path = basePath;\n let suffix = 0;\n while (usedPaths.has(path)) {\n suffix++;\n path = `${basePath}$${suffix}`;\n }\n usedPaths.add(path);\n return path;\n };\n\n return {\n enterScope({ segment, kind, stableKey }): ScopeHandle {\n const key = stableKey ?? `${kind}:${segment}`;\n const occurrence = getNextOccurrence(key);\n\n const frame: ScopeFrame = {\n nameSegment: segment,\n kind,\n occurrence,\n };\n\n scopeStack.push(frame);\n\n return {\n __brand: \"ScopeHandle\",\n depth: scopeStack.length - 1,\n } as ScopeHandle;\n },\n\n exitScope(handle: ScopeHandle): void {\n // Validate handle depth matches current stack\n if (handle.depth !== scopeStack.length - 1) {\n throw new Error(`[INTERNAL] Invalid scope exit: expected depth ${scopeStack.length - 1}, got ${handle.depth}`);\n }\n scopeStack.pop();\n },\n\n registerDefinition(): {\n astPath: string;\n isTopLevel: boolean;\n exportBinding?: string;\n } {\n const basePath = _buildAstPath(scopeStack);\n const astPath = ensureUniquePath(basePath);\n const isTopLevel = scopeStack.length === 0;\n\n // Check export binding if provided\n let exportBinding: string | undefined;\n if (getExportName && isTopLevel) {\n // For top-level definitions, try to get export name\n // This is a simplified version - real logic depends on how the definition is bound\n exportBinding = undefined;\n }\n\n return {\n astPath,\n isTopLevel,\n exportBinding,\n };\n },\n\n resolveCanonicalId(astPath: string): CanonicalId {\n return createCanonicalId(filePath, astPath, { baseDir });\n },\n\n registerExportBinding(local: string, exported: string): void {\n exportBindings.set(local, exported);\n },\n\n currentDepth(): number {\n return scopeStack.length;\n },\n };\n};\n\n/**\n * Helper to create occurrence tracker (for backward compatibility)\n */\nexport const createOccurrenceTracker = (): {\n getNextOccurrence: (key: string) => number;\n} => {\n const occurrenceCounters = new Map<string, number>();\n\n return {\n getNextOccurrence(key: string): number {\n const current = occurrenceCounters.get(key) ?? 0;\n occurrenceCounters.set(key, current + 1);\n return current;\n },\n };\n};\n\n/**\n * Helper to create path tracker (for backward compatibility)\n */\nexport const createPathTracker = (): {\n ensureUniquePath: (basePath: string) => string;\n} => {\n const usedPaths = new Set<string>();\n\n return {\n ensureUniquePath(basePath: string): string {\n let path = basePath;\n let suffix = 0;\n while (usedPaths.has(path)) {\n suffix++;\n path = `${basePath}$${suffix}`;\n }\n usedPaths.add(path);\n return path;\n },\n };\n};\n\n/**\n * Build AST path from scope stack (for backward compatibility)\n */\nexport const buildAstPath = (stack: readonly ScopeFrame[]): string => {\n return stack.map((frame) => frame.nameSegment).join(\".\");\n};\n"],"mappings":"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"}
|
package/dist/canonical-id.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const require_canonical_id = require('./canonical-id-
|
|
2
|
-
require('./utils-
|
|
1
|
+
const require_canonical_id = require('./canonical-id-DHdeYIsT.cjs');
|
|
2
|
+
require('./utils-Rs7YbafF.cjs');
|
|
3
3
|
|
|
4
4
|
exports.CanonicalIdSchema = require_canonical_id.CanonicalIdSchema;
|
|
5
5
|
exports.buildAstPath = require_canonical_id.buildAstPath;
|
|
@@ -7,4 +7,6 @@ exports.createCanonicalId = require_canonical_id.createCanonicalId;
|
|
|
7
7
|
exports.createCanonicalTracker = require_canonical_id.createCanonicalTracker;
|
|
8
8
|
exports.createOccurrenceTracker = require_canonical_id.createOccurrenceTracker;
|
|
9
9
|
exports.createPathTracker = require_canonical_id.createPathTracker;
|
|
10
|
-
exports.
|
|
10
|
+
exports.isRelativeCanonicalId = require_canonical_id.isRelativeCanonicalId;
|
|
11
|
+
exports.parseCanonicalId = require_canonical_id.parseCanonicalId;
|
|
12
|
+
exports.validateCanonicalId = require_canonical_id.validateCanonicalId;
|
package/dist/canonical-id.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as createCanonicalTracker, c as CanonicalId, d as
|
|
2
|
-
export { CanonicalId, CanonicalIdSchema, CanonicalPathTracker, ScopeFrame, ScopeHandle, buildAstPath, createCanonicalId, createCanonicalTracker, createOccurrenceTracker, createPathTracker, parseCanonicalId };
|
|
1
|
+
import { a as createCanonicalTracker, c as CanonicalId, d as CreateCanonicalIdOptions, f as createCanonicalId, h as validateCanonicalId, i as buildAstPath, l as CanonicalIdSchema, m as parseCanonicalId, n as ScopeFrame, o as createOccurrenceTracker, p as isRelativeCanonicalId, r as ScopeHandle, s as createPathTracker, t as CanonicalPathTracker, u as CanonicalIdValidationResult } from "./index-DZSebwar.cjs";
|
|
2
|
+
export { CanonicalId, CanonicalIdSchema, CanonicalIdValidationResult, CanonicalPathTracker, CreateCanonicalIdOptions, ScopeFrame, ScopeHandle, buildAstPath, createCanonicalId, createCanonicalTracker, createOccurrenceTracker, createPathTracker, isRelativeCanonicalId, parseCanonicalId, validateCanonicalId };
|
package/dist/canonical-id.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as createCanonicalTracker, c as CanonicalId, d as
|
|
2
|
-
export { CanonicalId, CanonicalIdSchema, CanonicalPathTracker, ScopeFrame, ScopeHandle, buildAstPath, createCanonicalId, createCanonicalTracker, createOccurrenceTracker, createPathTracker, parseCanonicalId };
|
|
1
|
+
import { a as createCanonicalTracker, c as CanonicalId, d as CreateCanonicalIdOptions, f as createCanonicalId, h as validateCanonicalId, i as buildAstPath, l as CanonicalIdSchema, m as parseCanonicalId, n as ScopeFrame, o as createOccurrenceTracker, p as isRelativeCanonicalId, r as ScopeHandle, s as createPathTracker, t as CanonicalPathTracker, u as CanonicalIdValidationResult } from "./index-AqkJhrm3.mjs";
|
|
2
|
+
export { CanonicalId, CanonicalIdSchema, CanonicalIdValidationResult, CanonicalPathTracker, CreateCanonicalIdOptions, ScopeFrame, ScopeHandle, buildAstPath, createCanonicalId, createCanonicalTracker, createOccurrenceTracker, createPathTracker, isRelativeCanonicalId, parseCanonicalId, validateCanonicalId };
|
package/dist/canonical-id.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "./utils-
|
|
2
|
-
import { a as CanonicalIdSchema, i as createPathTracker, n as createCanonicalTracker, o as createCanonicalId, r as createOccurrenceTracker, s as
|
|
1
|
+
import "./utils-ZCE_eqCf.mjs";
|
|
2
|
+
import { a as CanonicalIdSchema, c as parseCanonicalId, i as createPathTracker, l as validateCanonicalId, n as createCanonicalTracker, o as createCanonicalId, r as createOccurrenceTracker, s as isRelativeCanonicalId, t as buildAstPath } from "./canonical-id-9alor9gv.mjs";
|
|
3
3
|
|
|
4
|
-
export { CanonicalIdSchema, buildAstPath, createCanonicalId, createCanonicalTracker, createOccurrenceTracker, createPathTracker, parseCanonicalId };
|
|
4
|
+
export { CanonicalIdSchema, buildAstPath, createCanonicalId, createCanonicalTracker, createOccurrenceTracker, createPathTracker, isRelativeCanonicalId, parseCanonicalId, validateCanonicalId };
|
|
@@ -5,7 +5,34 @@ type CanonicalId = string & {
|
|
|
5
5
|
readonly __brand: "CanonicalId";
|
|
6
6
|
};
|
|
7
7
|
declare const CanonicalIdSchema: z$1.ZodType<CanonicalId>;
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Options for creating a canonical ID.
|
|
10
|
+
*/
|
|
11
|
+
type CreateCanonicalIdOptions = {
|
|
12
|
+
/**
|
|
13
|
+
* Base directory for relative path computation.
|
|
14
|
+
* When provided, the canonical ID will use a relative path from baseDir.
|
|
15
|
+
* When undefined, an absolute path is required and used as-is.
|
|
16
|
+
*/
|
|
17
|
+
readonly baseDir?: string;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Create a canonical ID from a file path and AST path.
|
|
21
|
+
*
|
|
22
|
+
* @param filePath - The file path (absolute, or relative if baseDir is provided)
|
|
23
|
+
* @param astPath - The AST path identifying the definition within the file
|
|
24
|
+
* @param options - Optional configuration including baseDir for relative path support
|
|
25
|
+
* @returns A canonical ID in the format "{path}::{astPath}"
|
|
26
|
+
*/
|
|
27
|
+
declare const createCanonicalId: (filePath: string, astPath: string, options?: CreateCanonicalIdOptions) => CanonicalId;
|
|
28
|
+
/**
|
|
29
|
+
* Check if a canonical ID uses a relative path.
|
|
30
|
+
* Relative canonical IDs do not start with '/'.
|
|
31
|
+
*
|
|
32
|
+
* @param canonicalId - The canonical ID to check
|
|
33
|
+
* @returns true if the canonical ID uses a relative path
|
|
34
|
+
*/
|
|
35
|
+
declare const isRelativeCanonicalId: (canonicalId: CanonicalId | string) => boolean;
|
|
9
36
|
/**
|
|
10
37
|
* Parse a canonical ID into its components.
|
|
11
38
|
* @param canonicalId - The canonical ID to parse (e.g., "/app/src/user.ts::userFragment")
|
|
@@ -15,6 +42,24 @@ declare const parseCanonicalId: (canonicalId: CanonicalId | string) => {
|
|
|
15
42
|
filePath: string;
|
|
16
43
|
astPath: string;
|
|
17
44
|
};
|
|
45
|
+
/**
|
|
46
|
+
* Validation result for canonical ID format.
|
|
47
|
+
*/
|
|
48
|
+
type CanonicalIdValidationResult = {
|
|
49
|
+
readonly isValid: true;
|
|
50
|
+
} | {
|
|
51
|
+
readonly isValid: false;
|
|
52
|
+
readonly reason: string;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Validate a canonical ID format.
|
|
56
|
+
* A valid canonical ID has format: "{filePath}::{astPath}"
|
|
57
|
+
* where both filePath and astPath are non-empty.
|
|
58
|
+
*
|
|
59
|
+
* @param canonicalId - The canonical ID to validate
|
|
60
|
+
* @returns Validation result with isValid boolean and optional error reason
|
|
61
|
+
*/
|
|
62
|
+
declare const validateCanonicalId: (canonicalId: string) => CanonicalIdValidationResult;
|
|
18
63
|
//#endregion
|
|
19
64
|
//#region packages/common/src/canonical-id/path-tracker.d.ts
|
|
20
65
|
|
|
@@ -110,6 +155,11 @@ interface CanonicalPathTracker {
|
|
|
110
155
|
*/
|
|
111
156
|
declare const createCanonicalTracker: (options: {
|
|
112
157
|
filePath: string;
|
|
158
|
+
/**
|
|
159
|
+
* Base directory for relative path computation in canonical IDs.
|
|
160
|
+
* When provided, canonical IDs will use relative paths from baseDir.
|
|
161
|
+
*/
|
|
162
|
+
baseDir?: string;
|
|
113
163
|
getExportName?: (localName: string) => string | undefined;
|
|
114
164
|
}) => CanonicalPathTracker;
|
|
115
165
|
/**
|
|
@@ -129,5 +179,5 @@ declare const createPathTracker: () => {
|
|
|
129
179
|
*/
|
|
130
180
|
declare const buildAstPath: (stack: readonly ScopeFrame[]) => string;
|
|
131
181
|
//#endregion
|
|
132
|
-
export { createCanonicalTracker as a, CanonicalId as c,
|
|
133
|
-
//# sourceMappingURL=index-
|
|
182
|
+
export { createCanonicalTracker as a, CanonicalId as c, CreateCanonicalIdOptions as d, createCanonicalId as f, validateCanonicalId as h, buildAstPath as i, CanonicalIdSchema as l, parseCanonicalId as m, ScopeFrame as n, createOccurrenceTracker as o, isRelativeCanonicalId as p, ScopeHandle as r, createPathTracker as s, CanonicalPathTracker as t, CanonicalIdValidationResult as u };
|
|
183
|
+
//# sourceMappingURL=index-AqkJhrm3.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-AqkJhrm3.d.mts","names":[],"sources":["../src/canonical-id/canonical-id.ts","../src/canonical-id/path-tracker.ts"],"sourcesContent":[],"mappings":";;;KAIY,WAAA;;AAAZ,CAAA;AAIa,cAAA,iBAA6B,EAAV,GAAA,CAAE,OAAF,CAAU,WAAD,CAAA;AAKzC;AAiBA;AAoCA;AASa,KA9DD,wBAAA,GA+DG;EAkBH;AAUZ;;;;ECnFY,SAAA,OAAU,CAAA,EAAA,MAAA;AAYtB,CAAA;AAQA;;;;;;AA8EA;AA4GA;AAiBa,cDtNA,iBCuOZ,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,EAAA,OAAA,CAAA,EDvO8E,wBCuO9E,EAAA,GDvOyG,WCuOzG;AAKD;;;;;;;cDxMa,qCAAsC;;;;;;cAStC,gCACE;;;;;;;KAkBH,2BAAA;;;;;;;;;;;;;;cAUC,8CAA6C;;;;ACvE1D;AAQA;;AAM0F,KA1B9E,UAAA,GA0B8E;EAMtE;EAiBmB,SAAA,WAAA,EAAA,MAAA;EAAW;EAiDrC,SAAA,IAAA,EAAA,UAuGZ,GAAA,OAAA,GA/FG,UAAA,GAAA,UA+FH,GAAA,QAAA,GAAA,YAAA;EAKY;EAiBA,SAAA,UAAA,EAiBZ,MAAA;AAKD,CAAA;;;;KAzOY,WAAA;;;;;;;UAQK,oBAAA;;;;;;;;UAM8B;;MAA2C;;;;;oBAMtE;;;;;;;;;;;;;;;uCAiBmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAiD1B;;;;;;;;MAQT;;;;cAoGS;;;;;;cAiBA;;;;;;cAsBA,+BAAgC"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { Result } from "neverthrow";
|
|
2
|
+
|
|
3
|
+
//#region packages/common/src/utils/tsconfig.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Parsed tsconfig.json paths configuration.
|
|
7
|
+
* All paths are resolved to absolute paths.
|
|
8
|
+
*/
|
|
9
|
+
type TsconfigPathsConfig = {
|
|
10
|
+
/** Absolute base URL for path resolution */
|
|
11
|
+
readonly baseUrl: string;
|
|
12
|
+
/** Path mappings with absolute paths */
|
|
13
|
+
readonly paths: Readonly<Record<string, readonly string[]>>;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Error types for tsconfig reading.
|
|
17
|
+
*/
|
|
18
|
+
type TsconfigReadError = {
|
|
19
|
+
readonly code: "TSCONFIG_READ_FAILED" | "TSCONFIG_PARSE_FAILED" | "TSCONFIG_INVALID";
|
|
20
|
+
readonly message: string;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Read and parse tsconfig.json to extract paths configuration.
|
|
24
|
+
* Currently does not support `extends` - reads only the specified file.
|
|
25
|
+
*
|
|
26
|
+
* @param tsconfigPath - Absolute path to tsconfig.json
|
|
27
|
+
* @returns Parsed paths configuration or null if no paths defined
|
|
28
|
+
*/
|
|
29
|
+
declare const readTsconfigPaths: (tsconfigPath: string) => Result<TsconfigPathsConfig | null, TsconfigReadError>;
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region packages/common/src/utils/alias-resolver.d.ts
|
|
32
|
+
/**
|
|
33
|
+
* Alias resolver interface for resolving path aliases to file paths.
|
|
34
|
+
*/
|
|
35
|
+
type AliasResolver = {
|
|
36
|
+
/**
|
|
37
|
+
* Resolve an alias specifier to an absolute file path.
|
|
38
|
+
* Returns null if the specifier doesn't match any alias pattern
|
|
39
|
+
* or if the resolved file doesn't exist.
|
|
40
|
+
*/
|
|
41
|
+
readonly resolve: (specifier: string) => string | null;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Create an alias resolver from tsconfig paths configuration.
|
|
45
|
+
*
|
|
46
|
+
* Resolution behavior:
|
|
47
|
+
* 1. Try each pattern in order (first match wins per TS spec)
|
|
48
|
+
* 2. For each matched pattern, try all target paths in order
|
|
49
|
+
* 3. For each target, apply extension resolution
|
|
50
|
+
* 4. Return first found file, or null if none found
|
|
51
|
+
*/
|
|
52
|
+
declare const createAliasResolver: (config: TsconfigPathsConfig) => AliasResolver;
|
|
53
|
+
//#endregion
|
|
54
|
+
//#region packages/common/src/utils/cached-fn.d.ts
|
|
55
|
+
declare const cachedFn: <T>(fn: () => T) => {
|
|
56
|
+
(): T;
|
|
57
|
+
clear(): void;
|
|
58
|
+
};
|
|
59
|
+
//#endregion
|
|
60
|
+
//#region packages/common/src/utils/path.d.ts
|
|
61
|
+
/**
|
|
62
|
+
* File extensions to try when resolving module specifiers.
|
|
63
|
+
* Ordered to match TypeScript's module resolution order.
|
|
64
|
+
* @see https://www.typescriptlang.org/docs/handbook/module-resolution.html
|
|
65
|
+
*/
|
|
66
|
+
declare const MODULE_EXTENSION_CANDIDATES: readonly [".ts", ".tsx", ".mts", ".cts", ".js", ".mjs", ".cjs", ".jsx"];
|
|
67
|
+
/**
|
|
68
|
+
* Result of parsing a JS extension from a specifier.
|
|
69
|
+
*/
|
|
70
|
+
type JsExtensionInfo = {
|
|
71
|
+
/** The specifier without the JS extension */
|
|
72
|
+
readonly base: string;
|
|
73
|
+
/** The JS extension found (e.g., ".js", ".mjs") */
|
|
74
|
+
readonly jsExtension: string;
|
|
75
|
+
/** The corresponding TS extensions to try (e.g., [".ts", ".tsx"] for ".js") */
|
|
76
|
+
readonly tsExtensions: readonly string[];
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Parse a JS extension from a specifier for ESM-style import resolution.
|
|
80
|
+
* Returns the base path (without extension), the JS extension, and corresponding TS extensions.
|
|
81
|
+
*
|
|
82
|
+
* @param specifier - The import specifier to parse
|
|
83
|
+
* @returns Object with base, jsExtension, and tsExtensions, or null if no JS extension found
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* parseJsExtension("./foo.js") // { base: "./foo", jsExtension: ".js", tsExtensions: [".ts", ".tsx"] }
|
|
87
|
+
* parseJsExtension("./foo.mjs") // { base: "./foo", jsExtension: ".mjs", tsExtensions: [".mts"] }
|
|
88
|
+
* parseJsExtension("./foo") // null
|
|
89
|
+
* parseJsExtension("./foo.ts") // null
|
|
90
|
+
*/
|
|
91
|
+
declare const parseJsExtension: (specifier: string) => JsExtensionInfo | null;
|
|
92
|
+
/**
|
|
93
|
+
* Normalize path to use forward slashes (cross-platform).
|
|
94
|
+
* Ensures consistent path handling across platforms.
|
|
95
|
+
*/
|
|
96
|
+
declare const normalizePath: (value: string) => string;
|
|
97
|
+
/**
|
|
98
|
+
* Resolve a relative import specifier to an absolute file path.
|
|
99
|
+
* Tries the specifier as-is, with extensions, and as a directory with index files.
|
|
100
|
+
*
|
|
101
|
+
* @param from - Absolute path to the importing file
|
|
102
|
+
* @param specifier - Relative module specifier (must start with '.')
|
|
103
|
+
* @returns Absolute POSIX path to the resolved file, or null if not found
|
|
104
|
+
*/
|
|
105
|
+
declare const resolveRelativeImportWithExistenceCheck: ({
|
|
106
|
+
filePath,
|
|
107
|
+
specifier
|
|
108
|
+
}: {
|
|
109
|
+
filePath: string;
|
|
110
|
+
specifier: string;
|
|
111
|
+
}) => string | null;
|
|
112
|
+
/**
|
|
113
|
+
* Resolve a relative import specifier to an absolute file path.
|
|
114
|
+
* Tries the specifier as-is, with extensions, and as a directory with index files.
|
|
115
|
+
*
|
|
116
|
+
* @param from - Absolute path to the importing file
|
|
117
|
+
* @param specifier - Relative module specifier (must start with '.')
|
|
118
|
+
* @returns Absolute POSIX path to the resolved file, or null if not found
|
|
119
|
+
*/
|
|
120
|
+
declare const resolveRelativeImportWithReferences: <_>({
|
|
121
|
+
filePath,
|
|
122
|
+
specifier,
|
|
123
|
+
references
|
|
124
|
+
}: {
|
|
125
|
+
filePath: string;
|
|
126
|
+
specifier: string;
|
|
127
|
+
references: Map<string, _> | Set<string>;
|
|
128
|
+
}) => string | null;
|
|
129
|
+
/**
|
|
130
|
+
* Check if a module specifier is relative (starts with '.' or '..')
|
|
131
|
+
*/
|
|
132
|
+
declare const isRelativeSpecifier: (specifier: string) => boolean;
|
|
133
|
+
/**
|
|
134
|
+
* Check if a module specifier is external (package name, not relative)
|
|
135
|
+
*/
|
|
136
|
+
declare const isExternalSpecifier: (specifier: string) => boolean;
|
|
137
|
+
//#endregion
|
|
138
|
+
export { normalizePath as a, resolveRelativeImportWithReferences as c, createAliasResolver as d, TsconfigPathsConfig as f, isRelativeSpecifier as i, cachedFn as l, readTsconfigPaths as m, MODULE_EXTENSION_CANDIDATES as n, parseJsExtension as o, TsconfigReadError as p, isExternalSpecifier as r, resolveRelativeImportWithExistenceCheck as s, JsExtensionInfo as t, AliasResolver as u };
|
|
139
|
+
//# sourceMappingURL=index-BCu9PNbZ.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-BCu9PNbZ.d.mts","names":[],"sources":["../src/utils/tsconfig.ts","../src/utils/alias-resolver.ts","../src/utils/cached-fn.ts","../src/utils/path.ts"],"sourcesContent":[],"mappings":";;;;;;AAQA;AAUA;AA4Ba,KAtCD,mBAAA,GAgGX;EA1D+D;EAA4B,SAAA,OAAA,EAAA,MAAA;EAAnC;EAAM,SAAA,KAAA,EAlC7C,QAkC6C,CAlCpC,MAkCoC,CAAA,MAAA,EAAA,SAAA,MAAA,EAAA,CAAA,CAAA;;;;ACtC/D;AAoJa,KD1ID,iBAAA,GCyKX;;;;AC3LD;;;;ACQA;AAgBA;AAsBA;AAiBa,cHjBA,iBGiB+E,EAAA,CAAA,YAAA,EAAA,MAAA,EAAA,GHjBnC,MGiBmC,CHjB5B,mBGiB4B,GAAA,IAAA,EHjBA,iBGiBA,CAAA;;;;;AHvD5F;AAUY,KCVA,aAAA,GDUiB;EA4BhB;;;;;;;;ACtCb;AAoJA;;;;AC5JA;;;cD4Ja,8BAA+B,wBAAsB;;;cC5JrD,wBAAyB;MAAA;;AFQtC,CAAA;;;;;;AAAA;AAUA;AA4Ba,cGtCA,2BHgGZ,EAAA,SAAA,CAAA,KAAA,EAAA,MAAA,EAAA,MAAA,EAAA,MAAA,EAAA,KAAA,EAAA,MAAA,EAAA,MAAA,EAAA,MAAA,CAAA;;;;AA1D8D,KGtBnD,eAAA,GHsBmD;;;;ECtCnD,SAAA,WAAa,EAAA,MAAA;EAoJZ;;;;AC5Jb;;;;ACQA;AAgBA;AAsBA;AAiBA;AAUA;AA+EA;;;AAAuD,cA1G1C,gBA0G0C,EAAA,CAAA,SAAA,EAAA,MAAA,EAAA,GA1GF,eA0GE,GAAA,IAAA;;;;;AA4D1C,cArJA,aAqJ+G,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,GAAA,MAAA;AAK5H;;;;;;;;cAhJa;;;;;;;;;;;;;;;cA+EA;;;;;;;cAOC,YAAY,KAAK;;;;;cAqDlB;;;;cAKA"}
|