MCPcopy Create free account
hub / github.com/chhoumann/quickadd / classifyCaptureTargetScope

Function classifyCaptureTargetScope

src/engine/helpers/captureTargetScope.ts:69–163  ·  view source on GitHub ↗
(
	deps: CaptureTargetScopeDeps,
	rawCaptureTo: string,
	captureToActiveFile: boolean,
)

Source from the content-addressed store, hash-verified

67 * legitimately collected pick is never silently dropped.
68 */
69export function classifyCaptureTargetScope(
70 deps: CaptureTargetScopeDeps,
71 rawCaptureTo: string,
72 captureToActiveFile: boolean,
73): CaptureTargetScope | null {
74 if (captureToActiveFile) return null;
75
76 const normalizedTarget = (rawCaptureTo ?? "").trim().replace(/^\/+/, "");
77
78 // A target carrying a format token (e.g. `Projects/{{VALUE}}.md`,
79 // `Notes/{{DATE}}/`, `#{{VALUE}}`) is only resolvable at run time, so in EVERY
80 // shape - file, folder, tag, property - it is never a stable picker scope: it
81 // gets no preflight requirement and the engine never honours a preselected pick
82 // for it. Returning early keeps that uniform across all branches below.
83 if (hasTemplatePathSyntax(normalizedTarget)) return null;
84
85 const propertyTarget = parsePropertyTarget(normalizedTarget);
86 const isPropertyTarget = !!propertyTarget && !!propertyTarget.field;
87
88 const fileFilterTarget = !isPropertyTarget
89 ? parseCaptureFileFilterTarget(normalizedTarget)
90 : null;
91 // A multi-select filter is not a single-destination capture scope.
92 const isFilterTarget = !!fileFilterTarget && !fileFilterTarget.multiSelect;
93
94 const isTagTarget =
95 !isPropertyTarget &&
96 !fileFilterTarget &&
97 normalizedTarget.startsWith("#");
98
99 const endsWithSlash = normalizedTarget.endsWith("/");
100
101 // A target carrying a recognized file extension with no trailing slash is never
102 // a runtime-pick scope. This mirrors resolveCaptureTarget, which tests the
103 // extension BEFORE the folder-ambiguity check, so an extensioned target that
104 // happens to collide with a same-named folder is NOT misrouted to that folder
105 // in either classifier. `.md`/`.canvas` are definite files; `.base` is
106 // unsupported (the resolver throws on it downstream) - in all three cases the
107 // engine must NOT honour an injected `__qa.captureTargetFilePath`, so returning
108 // `null` here both stops the spurious folder prompt AND preserves the #1448
109 // reserved-key confinement for a configured definite/unsupported file target.
110 const hasRecognizedFileExtension =
111 !isTagTarget &&
112 !isPropertyTarget &&
113 !isFilterTarget &&
114 !endsWithSlash &&
115 (MARKDOWN_FILE_EXTENSION_REGEX.test(normalizedTarget) ||
116 CANVAS_FILE_EXTENSION_REGEX.test(normalizedTarget) ||
117 BASE_FILE_EXTENSION_REGEX.test(normalizedTarget));
118
119 const folderProbePath = normalizedTarget.replace(/\/+$/, "");
120 // A bare name targets a folder only when the folder exists AND no same-name
121 // note does (resolveCaptureTarget's disambiguation; docs: "if both Projects/
122 // and Projects.md exist, Projects targets Projects.md"). Probing for the note
123 // keeps the classifier from offering a folder pick - and honouring an injected
124 // pick - for a bare name the write path resolves to a definite file. An empty
125 // target is the whole-vault scope and needs no probe. A trailing-slash target
126 // forces the folder regardless (handled by looksLikeFolderBySuffix below).

Callers 3

collectForCaptureChoiceFunction · 0.90

Calls 5

hasTemplatePathSyntaxFunction · 0.90
parsePropertyTargetFunction · 0.90
markdownFileExistsMethod · 0.80
isFolderMethod · 0.65

Tested by

no test coverage detected