@rejot-dev/thalo 0.0.0
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/LICENSE +21 -0
- package/README.md +396 -0
- package/dist/ast/ast-types.d.ts +469 -0
- package/dist/ast/ast-types.d.ts.map +1 -0
- package/dist/ast/ast-types.js +11 -0
- package/dist/ast/ast-types.js.map +1 -0
- package/dist/ast/builder.js +158 -0
- package/dist/ast/builder.js.map +1 -0
- package/dist/ast/extract.js +748 -0
- package/dist/ast/extract.js.map +1 -0
- package/dist/ast/node-at-position.d.ts +147 -0
- package/dist/ast/node-at-position.d.ts.map +1 -0
- package/dist/ast/node-at-position.js +382 -0
- package/dist/ast/node-at-position.js.map +1 -0
- package/dist/ast/visitor.js +232 -0
- package/dist/ast/visitor.js.map +1 -0
- package/dist/checker/check.d.ts +53 -0
- package/dist/checker/check.d.ts.map +1 -0
- package/dist/checker/check.js +105 -0
- package/dist/checker/check.js.map +1 -0
- package/dist/checker/rules/actualize-missing-updated.js +34 -0
- package/dist/checker/rules/actualize-missing-updated.js.map +1 -0
- package/dist/checker/rules/actualize-unresolved-target.js +42 -0
- package/dist/checker/rules/actualize-unresolved-target.js.map +1 -0
- package/dist/checker/rules/alter-before-define.js +53 -0
- package/dist/checker/rules/alter-before-define.js.map +1 -0
- package/dist/checker/rules/alter-undefined-entity.js +32 -0
- package/dist/checker/rules/alter-undefined-entity.js.map +1 -0
- package/dist/checker/rules/create-requires-section.js +34 -0
- package/dist/checker/rules/create-requires-section.js.map +1 -0
- package/dist/checker/rules/define-entity-requires-section.js +31 -0
- package/dist/checker/rules/define-entity-requires-section.js.map +1 -0
- package/dist/checker/rules/duplicate-entity-definition.js +37 -0
- package/dist/checker/rules/duplicate-entity-definition.js.map +1 -0
- package/dist/checker/rules/duplicate-field-in-schema.js +38 -0
- package/dist/checker/rules/duplicate-field-in-schema.js.map +1 -0
- package/dist/checker/rules/duplicate-link-id.js +52 -0
- package/dist/checker/rules/duplicate-link-id.js.map +1 -0
- package/dist/checker/rules/duplicate-metadata-key.js +21 -0
- package/dist/checker/rules/duplicate-metadata-key.js.map +1 -0
- package/dist/checker/rules/duplicate-section-heading.js +41 -0
- package/dist/checker/rules/duplicate-section-heading.js.map +1 -0
- package/dist/checker/rules/duplicate-section-in-schema.js +38 -0
- package/dist/checker/rules/duplicate-section-in-schema.js.map +1 -0
- package/dist/checker/rules/duplicate-timestamp.js +104 -0
- package/dist/checker/rules/duplicate-timestamp.js.map +1 -0
- package/dist/checker/rules/empty-required-value.js +45 -0
- package/dist/checker/rules/empty-required-value.js.map +1 -0
- package/dist/checker/rules/empty-section.js +21 -0
- package/dist/checker/rules/empty-section.js.map +1 -0
- package/dist/checker/rules/invalid-date-range-value.js +56 -0
- package/dist/checker/rules/invalid-date-range-value.js.map +1 -0
- package/dist/checker/rules/invalid-default-value.js +86 -0
- package/dist/checker/rules/invalid-default-value.js.map +1 -0
- package/dist/checker/rules/invalid-field-type.js +45 -0
- package/dist/checker/rules/invalid-field-type.js.map +1 -0
- package/dist/checker/rules/missing-required-field.js +48 -0
- package/dist/checker/rules/missing-required-field.js.map +1 -0
- package/dist/checker/rules/missing-required-section.js +51 -0
- package/dist/checker/rules/missing-required-section.js.map +1 -0
- package/dist/checker/rules/missing-title.js +56 -0
- package/dist/checker/rules/missing-title.js.map +1 -0
- package/dist/checker/rules/remove-undefined-field.js +42 -0
- package/dist/checker/rules/remove-undefined-field.js.map +1 -0
- package/dist/checker/rules/remove-undefined-section.js +42 -0
- package/dist/checker/rules/remove-undefined-section.js.map +1 -0
- package/dist/checker/rules/rules.d.ts +71 -0
- package/dist/checker/rules/rules.d.ts.map +1 -0
- package/dist/checker/rules/rules.js +102 -0
- package/dist/checker/rules/rules.js.map +1 -0
- package/dist/checker/rules/synthesis-empty-query.js +35 -0
- package/dist/checker/rules/synthesis-empty-query.js.map +1 -0
- package/dist/checker/rules/synthesis-missing-prompt.js +42 -0
- package/dist/checker/rules/synthesis-missing-prompt.js.map +1 -0
- package/dist/checker/rules/synthesis-missing-sources.js +32 -0
- package/dist/checker/rules/synthesis-missing-sources.js.map +1 -0
- package/dist/checker/rules/synthesis-unknown-query-entity.js +39 -0
- package/dist/checker/rules/synthesis-unknown-query-entity.js.map +1 -0
- package/dist/checker/rules/timestamp-out-of-order.js +55 -0
- package/dist/checker/rules/timestamp-out-of-order.js.map +1 -0
- package/dist/checker/rules/unknown-entity.js +32 -0
- package/dist/checker/rules/unknown-entity.js.map +1 -0
- package/dist/checker/rules/unknown-field.js +40 -0
- package/dist/checker/rules/unknown-field.js.map +1 -0
- package/dist/checker/rules/unknown-section.js +47 -0
- package/dist/checker/rules/unknown-section.js.map +1 -0
- package/dist/checker/rules/unresolved-link.js +34 -0
- package/dist/checker/rules/unresolved-link.js.map +1 -0
- package/dist/checker/rules/update-without-create.js +65 -0
- package/dist/checker/rules/update-without-create.js.map +1 -0
- package/dist/checker/visitor.d.ts +69 -0
- package/dist/checker/visitor.d.ts.map +1 -0
- package/dist/checker/visitor.js +67 -0
- package/dist/checker/visitor.js.map +1 -0
- package/dist/checker/workspace-index.d.ts +50 -0
- package/dist/checker/workspace-index.d.ts.map +1 -0
- package/dist/checker/workspace-index.js +108 -0
- package/dist/checker/workspace-index.js.map +1 -0
- package/dist/commands/actualize.d.ts +113 -0
- package/dist/commands/actualize.d.ts.map +1 -0
- package/dist/commands/actualize.js +111 -0
- package/dist/commands/actualize.js.map +1 -0
- package/dist/commands/check.d.ts +65 -0
- package/dist/commands/check.d.ts.map +1 -0
- package/dist/commands/check.js +61 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/format.d.ts +90 -0
- package/dist/commands/format.d.ts.map +1 -0
- package/dist/commands/format.js +80 -0
- package/dist/commands/format.js.map +1 -0
- package/dist/commands/query.d.ts +152 -0
- package/dist/commands/query.d.ts.map +1 -0
- package/dist/commands/query.js +151 -0
- package/dist/commands/query.js.map +1 -0
- package/dist/constants.d.ts +31 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +51 -0
- package/dist/constants.js.map +1 -0
- package/dist/files.d.ts +58 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +103 -0
- package/dist/files.js.map +1 -0
- package/dist/formatters.d.ts +39 -0
- package/dist/formatters.d.ts.map +1 -0
- package/dist/formatters.js +200 -0
- package/dist/formatters.js.map +1 -0
- package/dist/fragment.d.ts +22 -0
- package/dist/fragment.d.ts.map +1 -0
- package/dist/git/git.js +240 -0
- package/dist/git/git.js.map +1 -0
- package/dist/merge/conflict-detector.d.ts +89 -0
- package/dist/merge/conflict-detector.d.ts.map +1 -0
- package/dist/merge/conflict-detector.js +352 -0
- package/dist/merge/conflict-detector.js.map +1 -0
- package/dist/merge/conflict-formatter.js +143 -0
- package/dist/merge/conflict-formatter.js.map +1 -0
- package/dist/merge/driver.d.ts +54 -0
- package/dist/merge/driver.d.ts.map +1 -0
- package/dist/merge/driver.js +112 -0
- package/dist/merge/driver.js.map +1 -0
- package/dist/merge/entry-matcher.d.ts +50 -0
- package/dist/merge/entry-matcher.d.ts.map +1 -0
- package/dist/merge/entry-matcher.js +141 -0
- package/dist/merge/entry-matcher.js.map +1 -0
- package/dist/merge/entry-merger.js +194 -0
- package/dist/merge/entry-merger.js.map +1 -0
- package/dist/merge/merge-result-builder.d.ts +62 -0
- package/dist/merge/merge-result-builder.d.ts.map +1 -0
- package/dist/merge/merge-result-builder.js +89 -0
- package/dist/merge/merge-result-builder.js.map +1 -0
- package/dist/mod.d.ts +31 -0
- package/dist/mod.js +23 -0
- package/dist/model/document.d.ts +134 -0
- package/dist/model/document.d.ts.map +1 -0
- package/dist/model/document.js +275 -0
- package/dist/model/document.js.map +1 -0
- package/dist/model/line-index.d.ts +85 -0
- package/dist/model/line-index.d.ts.map +1 -0
- package/dist/model/line-index.js +159 -0
- package/dist/model/line-index.js.map +1 -0
- package/dist/model/workspace.d.ts +296 -0
- package/dist/model/workspace.d.ts.map +1 -0
- package/dist/model/workspace.js +562 -0
- package/dist/model/workspace.js.map +1 -0
- package/dist/parser.js +27 -0
- package/dist/parser.js.map +1 -0
- package/dist/parser.native.d.ts +51 -0
- package/dist/parser.native.d.ts.map +1 -0
- package/dist/parser.native.js +62 -0
- package/dist/parser.native.js.map +1 -0
- package/dist/parser.shared.d.ts +99 -0
- package/dist/parser.shared.d.ts.map +1 -0
- package/dist/parser.shared.js +124 -0
- package/dist/parser.shared.js.map +1 -0
- package/dist/parser.web.d.ts +67 -0
- package/dist/parser.web.d.ts.map +1 -0
- package/dist/parser.web.js +49 -0
- package/dist/parser.web.js.map +1 -0
- package/dist/schema/registry.d.ts +108 -0
- package/dist/schema/registry.d.ts.map +1 -0
- package/dist/schema/registry.js +281 -0
- package/dist/schema/registry.js.map +1 -0
- package/dist/semantic/analyzer.d.ts +107 -0
- package/dist/semantic/analyzer.d.ts.map +1 -0
- package/dist/semantic/analyzer.js +261 -0
- package/dist/semantic/analyzer.js.map +1 -0
- package/dist/services/change-tracker/change-tracker.d.ts +111 -0
- package/dist/services/change-tracker/change-tracker.d.ts.map +1 -0
- package/dist/services/change-tracker/change-tracker.js +62 -0
- package/dist/services/change-tracker/change-tracker.js.map +1 -0
- package/dist/services/change-tracker/create-tracker.d.ts +42 -0
- package/dist/services/change-tracker/create-tracker.d.ts.map +1 -0
- package/dist/services/change-tracker/create-tracker.js +53 -0
- package/dist/services/change-tracker/create-tracker.js.map +1 -0
- package/dist/services/change-tracker/git-tracker.d.ts +59 -0
- package/dist/services/change-tracker/git-tracker.d.ts.map +1 -0
- package/dist/services/change-tracker/git-tracker.js +218 -0
- package/dist/services/change-tracker/git-tracker.js.map +1 -0
- package/dist/services/change-tracker/timestamp-tracker.d.ts +22 -0
- package/dist/services/change-tracker/timestamp-tracker.d.ts.map +1 -0
- package/dist/services/change-tracker/timestamp-tracker.js +74 -0
- package/dist/services/change-tracker/timestamp-tracker.js.map +1 -0
- package/dist/services/definition.d.ts +37 -0
- package/dist/services/definition.d.ts.map +1 -0
- package/dist/services/definition.js +43 -0
- package/dist/services/definition.js.map +1 -0
- package/dist/services/entity-navigation.d.ts +200 -0
- package/dist/services/entity-navigation.d.ts.map +1 -0
- package/dist/services/entity-navigation.js +211 -0
- package/dist/services/entity-navigation.js.map +1 -0
- package/dist/services/hover.d.ts +81 -0
- package/dist/services/hover.d.ts.map +1 -0
- package/dist/services/hover.js +669 -0
- package/dist/services/hover.js.map +1 -0
- package/dist/services/query.d.ts +116 -0
- package/dist/services/query.d.ts.map +1 -0
- package/dist/services/query.js +225 -0
- package/dist/services/query.js.map +1 -0
- package/dist/services/references.d.ts +52 -0
- package/dist/services/references.d.ts.map +1 -0
- package/dist/services/references.js +66 -0
- package/dist/services/references.js.map +1 -0
- package/dist/services/semantic-tokens.d.ts +54 -0
- package/dist/services/semantic-tokens.d.ts.map +1 -0
- package/dist/services/semantic-tokens.js +213 -0
- package/dist/services/semantic-tokens.js.map +1 -0
- package/dist/services/synthesis.d.ts +90 -0
- package/dist/services/synthesis.d.ts.map +1 -0
- package/dist/services/synthesis.js +113 -0
- package/dist/services/synthesis.js.map +1 -0
- package/dist/source-map.d.ts +42 -0
- package/dist/source-map.d.ts.map +1 -0
- package/dist/source-map.js +170 -0
- package/dist/source-map.js.map +1 -0
- package/package.json +128 -0
- package/tree-sitter-thalo.wasm +0 -0
- package/web-tree-sitter.wasm +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract.js","names":["errors: SyntaxNode[]","entries: Entry[]","syntaxErrors: SyntaxErrorNode[]","header: InstanceHeader","header: SynthesisHeader","header: ActualizeHeader","header: SchemaHeader","elementType: PrimitiveType | LiteralType | UnionType","members: (PrimitiveType | LiteralType | ArrayType)[]","children: (MarkdownHeader | ContentLine)[]","elements: (Link | QuotedValue | DatetimeValue | DaterangeValue | NumberValue | Query)[]","conditions: QueryCondition[]","content: DefaultValue[\"content\"]"],"sources":["../../src/ast/extract.ts"],"sourcesContent":["import type { SyntaxNode } from \"./ast-types.js\";\nimport { buildTimestamp, createSyntaxError } from \"./builder.js\";\nimport type {\n AstNode,\n Location,\n SourceFile,\n Entry,\n InstanceEntry,\n InstanceHeader,\n InstanceDirective,\n Entity,\n SchemaEntry,\n SchemaHeader,\n SchemaDirective,\n SynthesisEntry,\n SynthesisHeader,\n ActualizeEntry,\n ActualizeHeader,\n MetadataBlock,\n SectionsBlock,\n RemoveMetadataBlock,\n RemoveSectionsBlock,\n FieldDefinition,\n FieldRemoval,\n SectionDefinition,\n SectionRemoval,\n TypeExpression,\n PrimitiveType,\n LiteralType,\n ArrayType,\n UnionType,\n SyntaxErrorNode,\n Metadata,\n Content,\n MarkdownHeader,\n ContentLine,\n Timestamp,\n Title,\n Link,\n Tag,\n Identifier,\n Key,\n Value,\n ValueContent,\n QuotedValue,\n DatetimeValue,\n DaterangeValue,\n NumberValue,\n ValueArray,\n Query,\n QueryCondition,\n FieldName,\n SectionName,\n Description,\n DefaultValue,\n} from \"./ast-types.js\";\n\n/**\n * Extract location information from a tree-sitter node\n */\nfunction extractLocation(node: SyntaxNode): Location {\n return {\n startIndex: node.startIndex,\n endIndex: node.endIndex,\n startPosition: node.startPosition,\n endPosition: node.endPosition,\n };\n}\n\n/**\n * Create the base AST node properties\n */\nfunction baseNode<T extends string>(node: SyntaxNode, type: T): AstNode & { type: T } {\n return {\n type,\n location: extractLocation(node),\n syntaxNode: node,\n };\n}\n\n/**\n * Get a required child by field name\n */\nfunction getChildByField(node: SyntaxNode, field: string): SyntaxNode {\n const child = node.childForFieldName(field);\n if (!child) {\n throw new Error(`Missing required field '${field}' in ${node.type}`);\n }\n return child;\n}\n\n/**\n * Get an optional child by field name\n */\nfunction getOptionalChildByField(node: SyntaxNode, field: string): SyntaxNode | null {\n return node.childForFieldName(field);\n}\n\n/**\n * Get all children of a specific type\n */\nfunction getChildrenByType(node: SyntaxNode, type: string): SyntaxNode[] {\n return node.namedChildren.filter(\n (child): child is SyntaxNode => child !== null && child.type === type,\n );\n}\n\n/**\n * Get the first child of a specific type\n */\nfunction getChildByType(node: SyntaxNode, type: string): SyntaxNode | null {\n return (\n node.namedChildren.find(\n (child): child is SyntaxNode => child !== null && child.type === type,\n ) ?? null\n );\n}\n\n/**\n * Strip quotes from a quoted string\n */\nfunction stripQuotes(text: string): string {\n if (text.startsWith('\"') && text.endsWith('\"')) {\n return text.slice(1, -1);\n }\n return text;\n}\n\n/**\n * Recursively find all ERROR nodes within a syntax tree.\n * Used to capture syntax errors nested inside entries.\n */\nfunction findErrorNodes(node: SyntaxNode): SyntaxNode[] {\n const errors: SyntaxNode[] = [];\n\n function walk(n: SyntaxNode): void {\n if (n.type === \"ERROR\") {\n errors.push(n);\n // Don't recurse into ERROR nodes - they may contain fragments\n // that look like valid nodes but are part of the error\n return;\n }\n for (const child of n.children) {\n if (child) {\n walk(child);\n }\n }\n }\n\n walk(node);\n return errors;\n}\n\n/**\n * Convert an ERROR syntax node to a SyntaxErrorNode\n */\nfunction errorNodeToSyntaxError(node: SyntaxNode): SyntaxErrorNode {\n const text = node.text.trim();\n return {\n type: \"syntax_error\",\n code: \"parse_error\",\n message: `Parse error: unexpected content \"${text.slice(0, 50)}${text.length > 50 ? \"...\" : \"\"}\"`,\n text: node.text,\n location: extractLocation(node),\n syntaxNode: node,\n };\n}\n\n// ===================\n// Extractors\n// ===================\n\n/**\n * Extract a SourceFile from the root node\n */\nexport function extractSourceFile(node: SyntaxNode): SourceFile {\n if (node.type !== \"source_file\") {\n throw new Error(`Expected source_file, got ${node.type}`);\n }\n\n const entries: Entry[] = [];\n const syntaxErrors: SyntaxErrorNode[] = [];\n\n for (const child of node.namedChildren) {\n if (!child) {\n // Skip nulls (web-tree-sitter can return null in arrays)\n continue;\n }\n\n if (child.type === \"entry\") {\n const entry = extractEntry(child);\n if (entry) {\n entries.push(entry);\n }\n // Collect ERROR nodes nested inside entries (tree-sitter may nest errors\n // inside entries when there's recoverable content after the error)\n if (child.hasError) {\n const nestedErrors = findErrorNodes(child);\n for (const errorNode of nestedErrors) {\n syntaxErrors.push(errorNodeToSyntaxError(errorNode));\n }\n }\n } else if (child.type === \"ERROR\") {\n syntaxErrors.push(errorNodeToSyntaxError(child));\n }\n }\n\n return {\n ...baseNode(node, \"source_file\"),\n entries,\n syntaxErrors,\n };\n}\n\n/**\n * Extract an Entry from an entry node\n */\nexport function extractEntry(node: SyntaxNode): Entry | null {\n const child = node.namedChildren[0];\n if (!child) {\n return null;\n }\n\n if (child.type === \"data_entry\") {\n return extractDataEntry(child);\n }\n if (child.type === \"schema_entry\") {\n return extractSchemaEntry(child);\n }\n return null;\n}\n\n/**\n * Extract a DataEntry - handles instance, synthesis, and actualize entries\n * based on the directive type\n */\nexport function extractDataEntry(\n node: SyntaxNode,\n): InstanceEntry | SynthesisEntry | ActualizeEntry {\n const directiveNode = getChildByField(node, \"directive\");\n const directive = directiveNode.text;\n\n if (directive === \"define-synthesis\") {\n return extractSynthesisEntryFromData(node);\n }\n if (directive === \"actualize-synthesis\") {\n return extractActualizeEntryFromData(node);\n }\n // Default: instance entry (create/update)\n return extractInstanceEntryFromData(node);\n}\n\n/**\n * Extract an InstanceEntry from a data_entry node\n */\nexport function extractInstanceEntryFromData(node: SyntaxNode): InstanceEntry {\n const timestampNode = getChildByField(node, \"timestamp\");\n const directiveNode = getChildByField(node, \"directive\");\n const argumentNode = getOptionalChildByField(node, \"argument\");\n const titleNode = getOptionalChildByField(node, \"title\");\n\n const linkNodes = getChildrenByType(node, \"link\");\n const tagNodes = getChildrenByType(node, \"tag\");\n const metadataNodes = getChildrenByType(node, \"metadata\");\n const contentNode = getChildByType(node, \"content\");\n\n // For instance entries, argument is the entity (identifier)\n const entityValue = argumentNode?.text || \"\";\n\n // Create a synthetic header for compatibility\n const header: InstanceHeader = {\n ...baseNode(node, \"instance_header\"),\n timestamp: extractTimestamp(timestampNode),\n directive: directiveNode.text as InstanceDirective,\n entity: entityValue as Entity,\n title: titleNode\n ? extractTitle(titleNode)\n : { type: \"title\", location: extractLocation(node), syntaxNode: node, value: \"\" },\n // Filter out the argument link from trailing links\n link:\n linkNodes.filter((l) => l !== argumentNode).length > 0\n ? extractLink(linkNodes.filter((l) => l !== argumentNode)[0])\n : null,\n tags: tagNodes.map(extractTag),\n };\n\n return {\n ...baseNode(node, \"instance_entry\"),\n header,\n metadata: metadataNodes.map(extractMetadata),\n content: contentNode ? extractContent(contentNode) : null,\n };\n}\n\n/**\n * Extract a SynthesisEntry from a data_entry node\n */\nexport function extractSynthesisEntryFromData(node: SyntaxNode): SynthesisEntry {\n const timestampNode = getChildByField(node, \"timestamp\");\n const titleNode = getOptionalChildByField(node, \"title\");\n const argumentNode = getOptionalChildByField(node, \"argument\");\n\n const linkNodes = getChildrenByType(node, \"link\");\n const tagNodes = getChildrenByType(node, \"tag\");\n const metadataNodes = getChildrenByType(node, \"metadata\");\n const contentNode = getChildByType(node, \"content\");\n\n // For define-synthesis, the argument is the link_id\n // The link_id is either the argument field, or the first link\n const linkIdNode = argumentNode?.type === \"link\" ? argumentNode : linkNodes[0];\n\n // Create a synthetic header for compatibility\n const header: SynthesisHeader = {\n ...baseNode(node, \"synthesis_header\"),\n timestamp: extractTimestamp(timestampNode),\n title: titleNode\n ? extractTitle(titleNode)\n : { type: \"title\", location: extractLocation(node), syntaxNode: node, value: \"\" },\n linkId: linkIdNode\n ? extractLink(linkIdNode)\n : { type: \"link\", location: extractLocation(node), syntaxNode: node, id: \"\" },\n // Filter out the linkId from trailing tags\n tags: tagNodes.map(extractTag),\n };\n\n return {\n ...baseNode(node, \"synthesis_entry\"),\n header,\n metadata: metadataNodes.map(extractMetadata),\n content: contentNode ? extractContent(contentNode) : null,\n };\n}\n\n/**\n * Extract an ActualizeEntry from a data_entry node\n */\nexport function extractActualizeEntryFromData(node: SyntaxNode): ActualizeEntry {\n const timestampNode = getChildByField(node, \"timestamp\");\n const argumentNode = getOptionalChildByField(node, \"argument\");\n\n const linkNodes = getChildrenByType(node, \"link\");\n const metadataNodes = getChildrenByType(node, \"metadata\");\n\n // For actualize-synthesis, the argument (or first link) is the target\n const targetNode = argumentNode?.type === \"link\" ? argumentNode : linkNodes[0];\n\n // Create a synthetic header for compatibility\n const header: ActualizeHeader = {\n ...baseNode(node, \"actualize_header\"),\n timestamp: extractTimestamp(timestampNode),\n target: targetNode\n ? extractLink(targetNode)\n : { type: \"link\", location: extractLocation(node), syntaxNode: node, id: \"\" },\n };\n\n return {\n ...baseNode(node, \"actualize_entry\"),\n header,\n metadata: metadataNodes.map(extractMetadata),\n };\n}\n\n/**\n * Extract a SchemaEntry - header fields are now inline\n */\nexport function extractSchemaEntry(node: SyntaxNode): SchemaEntry {\n const timestampNode = getChildByField(node, \"timestamp\");\n const directiveNode = getChildByField(node, \"directive\");\n const argumentNode = getOptionalChildByField(node, \"argument\");\n const titleNode = getChildByField(node, \"title\");\n\n const linkNodes = getChildrenByType(node, \"link\");\n const tagNodes = getChildrenByType(node, \"tag\");\n\n const metadataBlockNode = getChildByType(node, \"metadata_block\");\n const sectionsBlockNode = getChildByType(node, \"sections_block\");\n const removeMetadataBlockNode = getChildByType(node, \"remove_metadata_block\");\n const removeSectionsBlockNode = getChildByType(node, \"remove_sections_block\");\n\n // Create a synthetic header for compatibility\n const header: SchemaHeader = {\n ...baseNode(node, \"schema_header\"),\n timestamp: extractTimestamp(timestampNode),\n directive: directiveNode.text as SchemaDirective,\n entityName: argumentNode\n ? extractIdentifier(argumentNode)\n : { type: \"identifier\", location: extractLocation(node), syntaxNode: node, value: \"\" },\n title: extractTitle(titleNode),\n link: linkNodes.length > 0 ? extractLink(linkNodes[0]) : null,\n tags: tagNodes.map(extractTag),\n };\n\n return {\n ...baseNode(node, \"schema_entry\"),\n header,\n metadataBlock: metadataBlockNode ? extractMetadataBlock(metadataBlockNode) : null,\n sectionsBlock: sectionsBlockNode ? extractSectionsBlock(sectionsBlockNode) : null,\n removeMetadataBlock: removeMetadataBlockNode\n ? extractRemoveMetadataBlock(removeMetadataBlockNode)\n : null,\n removeSectionsBlock: removeSectionsBlockNode\n ? extractRemoveSectionsBlock(removeSectionsBlockNode)\n : null,\n };\n}\n\n/**\n * Extract a MetadataBlock\n */\nexport function extractMetadataBlock(node: SyntaxNode): MetadataBlock {\n const fieldNodes = getChildrenByType(node, \"field_definition\");\n return {\n ...baseNode(node, \"metadata_block\"),\n fields: fieldNodes.map(extractFieldDefinition),\n };\n}\n\n/**\n * Extract a SectionsBlock\n */\nexport function extractSectionsBlock(node: SyntaxNode): SectionsBlock {\n const sectionNodes = getChildrenByType(node, \"section_definition\");\n return {\n ...baseNode(node, \"sections_block\"),\n sections: sectionNodes.map(extractSectionDefinition),\n };\n}\n\n/**\n * Extract a RemoveMetadataBlock\n */\nexport function extractRemoveMetadataBlock(node: SyntaxNode): RemoveMetadataBlock {\n const fieldNodes = getChildrenByType(node, \"field_removal\");\n return {\n ...baseNode(node, \"remove_metadata_block\"),\n fields: fieldNodes.map(extractFieldRemoval),\n };\n}\n\n/**\n * Extract a RemoveSectionsBlock\n */\nexport function extractRemoveSectionsBlock(node: SyntaxNode): RemoveSectionsBlock {\n const sectionNodes = getChildrenByType(node, \"section_removal\");\n return {\n ...baseNode(node, \"remove_sections_block\"),\n sections: sectionNodes.map(extractSectionRemoval),\n };\n}\n\n/**\n * Extract a FieldDefinition\n */\nexport function extractFieldDefinition(node: SyntaxNode): FieldDefinition {\n const nameNode = getChildByType(node, \"field_name\");\n if (!nameNode) {\n throw new Error(\"Missing field_name in field_definition\");\n }\n\n const optionalMarker = getChildByType(node, \"optional_marker\");\n const typeNode = getChildByField(node, \"type\");\n const defaultNode = getOptionalChildByField(node, \"default\");\n const descriptionNode = getOptionalChildByField(node, \"description\");\n\n return {\n ...baseNode(node, \"field_definition\"),\n name: extractFieldName(nameNode),\n optional: optionalMarker !== null,\n typeExpr: extractTypeExpression(typeNode),\n defaultValue: defaultNode ? extractDefaultValue(defaultNode) : null,\n description: descriptionNode ? extractDescription(descriptionNode) : null,\n };\n}\n\n/**\n * Extract a FieldRemoval\n */\nexport function extractFieldRemoval(node: SyntaxNode): FieldRemoval {\n const nameNode = getChildByType(node, \"field_name\");\n if (!nameNode) {\n throw new Error(\"Missing field_name in field_removal\");\n }\n\n const reasonNode = getOptionalChildByField(node, \"reason\");\n\n return {\n ...baseNode(node, \"field_removal\"),\n name: extractFieldName(nameNode),\n reason: reasonNode ? extractDescription(reasonNode) : null,\n };\n}\n\n/**\n * Extract a SectionDefinition\n */\nexport function extractSectionDefinition(node: SyntaxNode): SectionDefinition {\n const nameNode = getChildByType(node, \"section_name\");\n if (!nameNode) {\n throw new Error(\"Missing section_name in section_definition\");\n }\n\n const optionalMarker = getChildByType(node, \"optional_marker\");\n const descriptionNode = getOptionalChildByField(node, \"description\");\n\n return {\n ...baseNode(node, \"section_definition\"),\n name: extractSectionName(nameNode),\n optional: optionalMarker !== null,\n description: descriptionNode ? extractDescription(descriptionNode) : null,\n };\n}\n\n/**\n * Extract a SectionRemoval\n */\nexport function extractSectionRemoval(node: SyntaxNode): SectionRemoval {\n const nameNode = getChildByType(node, \"section_name\");\n if (!nameNode) {\n throw new Error(\"Missing section_name in section_removal\");\n }\n\n const reasonNode = getOptionalChildByField(node, \"reason\");\n\n return {\n ...baseNode(node, \"section_removal\"),\n name: extractSectionName(nameNode),\n reason: reasonNode ? extractDescription(reasonNode) : null,\n };\n}\n\n/**\n * Extract a TypeExpression.\n * Returns a SyntaxErrorNode if an unknown type identifier is encountered.\n */\nexport function extractTypeExpression(\n node: SyntaxNode,\n): TypeExpression | SyntaxErrorNode<\"unknown_type\"> {\n // type_expression wraps the actual type\n const child = node.namedChildren[0];\n if (!child) {\n throw new Error(\"Empty type_expression\");\n }\n\n switch (child.type) {\n case \"primitive_type\":\n return extractPrimitiveType(child);\n case \"literal_type\":\n return extractLiteralType(child);\n case \"array_type\":\n return extractArrayType(child);\n case \"union_type\":\n return extractUnionType(child);\n case \"unknown_type\":\n return createSyntaxError(\n \"unknown_type\",\n `Unknown type '${child.text}'. Valid types: string, datetime, daterange, link, number`,\n child.text,\n child,\n );\n default:\n throw new Error(`Unknown type expression: ${child.type}`);\n }\n}\n\n/**\n * Extract a PrimitiveType\n */\nexport function extractPrimitiveType(node: SyntaxNode): PrimitiveType {\n return {\n ...baseNode(node, \"primitive_type\"),\n name: node.text as PrimitiveType[\"name\"],\n };\n}\n\n/**\n * Extract a LiteralType\n */\nexport function extractLiteralType(node: SyntaxNode): LiteralType {\n return {\n ...baseNode(node, \"literal_type\"),\n value: stripQuotes(node.text),\n };\n}\n\n/**\n * Extract an ArrayType.\n * Returns a SyntaxErrorNode if the element type is unknown.\n */\nexport function extractArrayType(node: SyntaxNode): ArrayType | SyntaxErrorNode<\"unknown_type\"> {\n const child = node.namedChildren[0];\n if (!child) {\n throw new Error(\"Empty array_type\");\n }\n\n let elementType: PrimitiveType | LiteralType | UnionType;\n if (child.type === \"primitive_type\") {\n elementType = extractPrimitiveType(child);\n } else if (child.type === \"literal_type\") {\n elementType = extractLiteralType(child);\n } else if (child.type === \"unknown_type\") {\n // Unknown element type in array - return syntax error for whole type\n return createSyntaxError(\n \"unknown_type\",\n `Unknown type '${child.text}'. Valid types: string, datetime, daterange, link, number`,\n node.text,\n node,\n );\n } else if (child.type === \"paren_type\") {\n // Parenthesized type: extract the inner type_expression\n const innerTypeExpr = child.namedChildren[0];\n if (!innerTypeExpr) {\n throw new Error(\"Empty paren_type\");\n }\n const extracted = extractTypeExpression(innerTypeExpr);\n // Propagate syntax errors from inner type\n if (extracted.type === \"syntax_error\") {\n return extracted;\n }\n // paren_type is only valid with union types in arrays\n if (extracted.type !== \"union_type\") {\n throw new Error(`Unexpected paren_type content: ${extracted.type}`);\n }\n elementType = extracted;\n } else {\n throw new Error(`Invalid array element type: ${child.type}`);\n }\n\n return {\n ...baseNode(node, \"array_type\"),\n elementType,\n };\n}\n\n/**\n * Extract a UnionType.\n * Returns a SyntaxErrorNode if any member is an unknown type.\n */\nexport function extractUnionType(node: SyntaxNode): UnionType | SyntaxErrorNode<\"unknown_type\"> {\n const members: (PrimitiveType | LiteralType | ArrayType)[] = [];\n\n for (const child of node.namedChildren) {\n if (!child) {\n continue;\n } // Skip nulls\n switch (child.type) {\n case \"primitive_type\":\n members.push(extractPrimitiveType(child));\n break;\n case \"literal_type\":\n members.push(extractLiteralType(child));\n break;\n case \"array_type\": {\n const arrayType = extractArrayType(child);\n if (arrayType.type === \"syntax_error\") {\n return arrayType; // Bubble up the error\n }\n members.push(arrayType);\n break;\n }\n case \"unknown_type\":\n // Unknown type in union - return syntax error for whole type\n return createSyntaxError(\n \"unknown_type\",\n `Unknown type '${child.text}'. Valid types: string, datetime, daterange, link, number`,\n node.text,\n node,\n );\n }\n }\n\n return {\n ...baseNode(node, \"union_type\"),\n members,\n };\n}\n\n/**\n * Extract a Metadata entry\n */\nexport function extractMetadata(node: SyntaxNode): Metadata {\n const keyNode = getChildByField(node, \"key\");\n const valueNode = getChildByField(node, \"value\");\n\n return {\n ...baseNode(node, \"metadata\"),\n key: extractKey(keyNode),\n value: extractValue(valueNode),\n };\n}\n\n/**\n * Extract Content\n */\nexport function extractContent(node: SyntaxNode): Content {\n const children: (MarkdownHeader | ContentLine)[] = [];\n\n for (const child of node.namedChildren) {\n if (!child) {\n continue;\n } // Skip nulls\n if (child.type === \"markdown_header\") {\n children.push(extractMarkdownHeader(child));\n } else if (child.type === \"content_line\") {\n children.push(extractContentLine(child));\n }\n }\n\n return {\n ...baseNode(node, \"content\"),\n children,\n };\n}\n\n/**\n * Extract a MarkdownHeader\n */\nexport function extractMarkdownHeader(node: SyntaxNode): MarkdownHeader {\n // Tree-sitter includes any trailing spaces in the node range, which can cause\n // diagnostics to highlight \"invisible\" whitespace. Trim the *location* to the\n // last non-whitespace character while still keeping the original syntaxNode.\n const raw = node.text;\n const trimmedRight = raw.replace(/[ \\t]+$/, \"\");\n const trimDelta = raw.length - trimmedRight.length;\n const base = baseNode(node, \"markdown_header\");\n\n return {\n ...base,\n location:\n trimDelta === 0\n ? base.location\n : {\n ...base.location,\n endIndex: base.location.endIndex - trimDelta,\n endPosition: {\n ...base.location.endPosition,\n column: Math.max(0, base.location.endPosition.column - trimDelta),\n },\n },\n text: raw.trim(),\n };\n}\n\n/**\n * Extract a ContentLine\n */\nexport function extractContentLine(node: SyntaxNode): ContentLine {\n return {\n ...baseNode(node, \"content_line\"),\n text: node.text.trim(),\n };\n}\n\n// ===================\n// Terminal Extractors\n// ===================\n\nexport function extractTimestamp(node: SyntaxNode): Timestamp {\n return buildTimestamp(node);\n}\n\nexport function extractTitle(node: SyntaxNode): Title {\n return {\n ...baseNode(node, \"title\"),\n value: stripQuotes(node.text),\n };\n}\n\nexport function extractLink(node: SyntaxNode): Link {\n const text = node.text.trim();\n return {\n ...baseNode(node, \"link\"),\n id: text.slice(1), // Remove ^ prefix\n };\n}\n\nexport function extractTag(node: SyntaxNode): Tag {\n const text = node.text.trim();\n return {\n ...baseNode(node, \"tag\"),\n name: text.slice(1), // Remove # prefix\n };\n}\n\nexport function extractIdentifier(node: SyntaxNode): Identifier {\n return {\n ...baseNode(node, \"identifier\"),\n value: node.text,\n };\n}\n\nexport function extractKey(node: SyntaxNode): Key {\n return {\n ...baseNode(node, \"key\"),\n value: node.text,\n };\n}\n\nexport function extractValue(node: SyntaxNode): Value {\n const child = node.namedChildren[0];\n if (!child) {\n // Fallback for empty or unrecognized values - treat as empty quoted value\n return {\n ...baseNode(node, \"value\"),\n raw: node.text.trim(),\n content: {\n ...baseNode(node, \"quoted_value\"),\n value: node.text.trim(),\n },\n };\n }\n\n return {\n ...baseNode(node, \"value\"),\n raw: node.text.trim(),\n content: extractValueContent(child),\n };\n}\n\n/**\n * Extract typed value content from a child node of value\n */\nfunction extractValueContent(node: SyntaxNode): ValueContent {\n switch (node.type) {\n case \"quoted_value\":\n return extractQuotedValue(node);\n case \"link\":\n return {\n ...baseNode(node, \"link_value\"),\n link: extractLink(node),\n };\n case \"datetime_value\":\n return extractDatetimeValue(node);\n case \"daterange\":\n return {\n ...baseNode(node, \"daterange\"),\n raw: node.text.trim(),\n };\n case \"number_value\":\n return {\n ...baseNode(node, \"number_value\"),\n raw: node.text.trim(),\n value: parseFloat(node.text.trim()),\n };\n case \"value_array\":\n return extractValueArray(node);\n case \"query\":\n return {\n ...baseNode(node, \"query_value\"),\n query: extractQuery(node),\n };\n default:\n // Fallback: treat as quoted value\n return {\n ...baseNode(node, \"quoted_value\"),\n value: node.text.trim(),\n };\n }\n}\n\n/**\n * Extract a datetime value with its split components\n */\nfunction extractDatetimeValue(node: SyntaxNode): DatetimeValue {\n const dateNode = node.childForFieldName(\"date\");\n const timeNode = node.childForFieldName(\"time\");\n const tzNode = node.childForFieldName(\"tz\");\n\n return {\n ...baseNode(node, \"datetime_value\"),\n value: node.text.trim(),\n date: dateNode?.text ?? \"\",\n time: timeNode?.text ?? null,\n tz: tzNode?.text ?? null,\n };\n}\n\nfunction extractQuotedValue(node: SyntaxNode): QuotedValue {\n return {\n ...baseNode(node, \"quoted_value\"),\n value: stripQuotes(node.text),\n };\n}\n\nfunction extractValueArray(node: SyntaxNode): ValueArray {\n const elements: (Link | QuotedValue | DatetimeValue | DaterangeValue | NumberValue | Query)[] =\n [];\n\n for (const child of node.namedChildren) {\n if (!child) {\n continue;\n } // Skip nulls\n if (child.type === \"link\") {\n elements.push(extractLink(child));\n } else if (child.type === \"quoted_value\") {\n elements.push(extractQuotedValue(child));\n } else if (child.type === \"datetime_value\") {\n elements.push(extractDatetimeValue(child));\n } else if (child.type === \"daterange\") {\n elements.push({\n ...baseNode(child, \"daterange\"),\n raw: child.text.trim(),\n });\n } else if (child.type === \"number_value\") {\n elements.push({\n ...baseNode(child, \"number_value\"),\n raw: child.text.trim(),\n value: parseFloat(child.text.trim()),\n });\n } else if (child.type === \"query\") {\n elements.push(extractQuery(child));\n }\n }\n\n return {\n ...baseNode(node, \"value_array\"),\n elements,\n };\n}\n\nfunction extractQuery(node: SyntaxNode): Query {\n const entityNode = node.childForFieldName(\"entity\");\n const conditionsNode = node.childForFieldName(\"conditions\");\n\n // Get entity text - handle nested query_entity from alias\n let entityText = \"\";\n if (entityNode) {\n // The aliased query_entity may have a child query_entity\n const innerEntity = entityNode.namedChildren[0];\n entityText = innerEntity ? innerEntity.text : entityNode.text;\n }\n\n const conditions: QueryCondition[] = [];\n if (conditionsNode) {\n for (const child of conditionsNode.namedChildren) {\n if (!child) {\n continue;\n } // Skip nulls\n if (child.type === \"query_condition\") {\n const condition = extractQueryCondition(child);\n if (condition) {\n conditions.push(condition);\n }\n }\n }\n }\n\n return {\n ...baseNode(node, \"query\"),\n entity: entityText,\n conditions,\n };\n}\n\nfunction extractQueryCondition(node: SyntaxNode): QueryCondition | null {\n const child = node.namedChildren[0];\n if (!child) {\n return null;\n }\n\n switch (child.type) {\n case \"field_condition\": {\n const fieldNode = child.childForFieldName(\"field\");\n const valueNode = child.childForFieldName(\"value\");\n\n // Handle nested alias for condition_field\n let fieldText = \"\";\n if (fieldNode) {\n const innerField = fieldNode.namedChildren[0];\n fieldText = innerField ? innerField.text : fieldNode.text;\n }\n\n // Handle value - could be link, quoted_value, or condition_plain_value\n // Keep the raw text (including quotes) to match metadata raw values\n let valueText = \"\";\n if (valueNode) {\n if (valueNode.type === \"link\") {\n valueText = valueNode.text;\n } else if (valueNode.type === \"quoted_value\") {\n // Keep quotes to match metadata.value.raw format\n valueText = valueNode.text;\n } else {\n // condition_plain_value (aliased)\n const inner = valueNode.namedChildren[0];\n valueText = inner ? inner.text : valueNode.text;\n }\n }\n\n return {\n ...baseNode(child, \"field_condition\"),\n field: fieldText,\n value: valueText,\n };\n }\n case \"tag_condition\": {\n const tagNode = getChildByType(child, \"tag\");\n return {\n ...baseNode(child, \"tag_condition\"),\n tag: tagNode ? tagNode.text.slice(1) : \"\", // Remove # prefix\n };\n }\n case \"link_condition\": {\n const linkNode = getChildByType(child, \"link\");\n return {\n ...baseNode(child, \"link_condition\"),\n linkId: linkNode ? linkNode.text.slice(1) : \"\", // Remove ^ prefix\n };\n }\n default:\n return null;\n }\n}\n\nexport function extractFieldName(node: SyntaxNode): FieldName {\n return {\n ...baseNode(node, \"field_name\"),\n value: node.text.trim(),\n };\n}\n\nexport function extractSectionName(node: SyntaxNode): SectionName {\n return {\n ...baseNode(node, \"section_name\"),\n value: node.text.trim(),\n };\n}\n\nexport function extractDescription(node: SyntaxNode): Description {\n return {\n ...baseNode(node, \"description\"),\n value: stripQuotes(node.text),\n };\n}\n\nexport function extractDefaultValue(node: SyntaxNode): DefaultValue {\n const child = node.namedChildren[0];\n if (!child) {\n throw new Error(\"Empty default_value\");\n }\n\n let content: DefaultValue[\"content\"];\n switch (child.type) {\n case \"quoted_value\":\n content = extractQuotedValue(child);\n break;\n case \"link\":\n content = extractLink(child);\n break;\n case \"datetime_value\":\n content = extractDatetimeValue(child);\n break;\n case \"number_value\":\n content = {\n ...baseNode(child, \"number_value\"),\n raw: child.text.trim(),\n value: parseFloat(child.text.trim()),\n };\n break;\n default:\n throw new Error(`Unknown default_value child type: ${child.type}`);\n }\n\n return {\n ...baseNode(node, \"default_value\"),\n raw: node.text,\n content,\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { FieldName, Identifier, Key, Link, Location, SectionName, Tag, Timestamp, TypeExpression } from "./ast-types.js";
|
|
2
|
+
import { Position, SourceMap } from "../source-map.js";
|
|
3
|
+
import { GenericTree, ParsedDocument } from "../parser.shared.js";
|
|
4
|
+
|
|
5
|
+
//#region src/ast/node-at-position.d.ts
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Context for a link node (^link-id)
|
|
9
|
+
*/
|
|
10
|
+
interface LinkContext {
|
|
11
|
+
kind: "link";
|
|
12
|
+
linkId: string;
|
|
13
|
+
node: Link;
|
|
14
|
+
sourceMap: SourceMap;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Context for a tag node (#tag)
|
|
18
|
+
*/
|
|
19
|
+
interface TagContext {
|
|
20
|
+
kind: "tag";
|
|
21
|
+
tagName: string;
|
|
22
|
+
node: Tag;
|
|
23
|
+
sourceMap: SourceMap;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Context for a timestamp node
|
|
27
|
+
*/
|
|
28
|
+
interface TimestampContext {
|
|
29
|
+
kind: "timestamp";
|
|
30
|
+
value: string;
|
|
31
|
+
node: Timestamp;
|
|
32
|
+
sourceMap: SourceMap;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Context for a directive (create, update, define-entity, etc.)
|
|
36
|
+
*/
|
|
37
|
+
interface DirectiveContext {
|
|
38
|
+
kind: "directive";
|
|
39
|
+
directive: string;
|
|
40
|
+
location: Location;
|
|
41
|
+
sourceMap: SourceMap;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Context for an entity name in instance entries
|
|
45
|
+
*/
|
|
46
|
+
interface EntityContext {
|
|
47
|
+
kind: "entity";
|
|
48
|
+
entityName: string;
|
|
49
|
+
location: Location;
|
|
50
|
+
sourceMap: SourceMap;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Context for an entity name in schema entries (define-entity/alter-entity)
|
|
54
|
+
*/
|
|
55
|
+
interface SchemaEntityContext {
|
|
56
|
+
kind: "schema_entity";
|
|
57
|
+
entityName: string;
|
|
58
|
+
node: Identifier;
|
|
59
|
+
sourceMap: SourceMap;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Context for a metadata key
|
|
63
|
+
*/
|
|
64
|
+
interface MetadataKeyContext {
|
|
65
|
+
kind: "metadata_key";
|
|
66
|
+
key: string;
|
|
67
|
+
node: Key;
|
|
68
|
+
/** The entity type of the containing entry (if known) */
|
|
69
|
+
entityContext?: string;
|
|
70
|
+
sourceMap: SourceMap;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Context for a section header in content (# SectionName)
|
|
74
|
+
*/
|
|
75
|
+
interface SectionHeaderContext {
|
|
76
|
+
kind: "section_header";
|
|
77
|
+
sectionName: string;
|
|
78
|
+
location: Location;
|
|
79
|
+
/** The entity type of the containing entry (if known) */
|
|
80
|
+
entityContext?: string;
|
|
81
|
+
sourceMap: SourceMap;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Context for a type expression in schema definitions
|
|
85
|
+
*/
|
|
86
|
+
interface TypeContext {
|
|
87
|
+
kind: "type";
|
|
88
|
+
typeName: string;
|
|
89
|
+
node: TypeExpression;
|
|
90
|
+
sourceMap: SourceMap;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Context for a field name in schema definitions
|
|
94
|
+
*/
|
|
95
|
+
interface FieldNameContext {
|
|
96
|
+
kind: "field_name";
|
|
97
|
+
fieldName: string;
|
|
98
|
+
node: FieldName;
|
|
99
|
+
/** The entity being defined/altered */
|
|
100
|
+
entityContext?: string;
|
|
101
|
+
sourceMap: SourceMap;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Context for a section name in schema definitions
|
|
105
|
+
*/
|
|
106
|
+
interface SectionNameContext {
|
|
107
|
+
kind: "section_name";
|
|
108
|
+
sectionName: string;
|
|
109
|
+
node: SectionName;
|
|
110
|
+
/** The entity being defined/altered */
|
|
111
|
+
entityContext?: string;
|
|
112
|
+
sourceMap: SourceMap;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Context for a title
|
|
116
|
+
*/
|
|
117
|
+
interface TitleContext {
|
|
118
|
+
kind: "title";
|
|
119
|
+
title: string;
|
|
120
|
+
location: Location;
|
|
121
|
+
sourceMap: SourceMap;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Unknown context - position doesn't map to a recognized element
|
|
125
|
+
*/
|
|
126
|
+
interface UnknownContext {
|
|
127
|
+
kind: "unknown";
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* All possible node contexts
|
|
131
|
+
*/
|
|
132
|
+
type NodeContext = LinkContext | TagContext | TimestampContext | DirectiveContext | EntityContext | SchemaEntityContext | MetadataKeyContext | SectionHeaderContext | TypeContext | FieldNameContext | SectionNameContext | TitleContext | UnknownContext;
|
|
133
|
+
/**
|
|
134
|
+
* Find the semantic context of a node at a given position in a parsed document.
|
|
135
|
+
*
|
|
136
|
+
* This function handles both standalone .thalo files and embedded thalo blocks
|
|
137
|
+
* in markdown files. It uses the source map to convert file-absolute positions
|
|
138
|
+
* to block-relative positions before querying the AST.
|
|
139
|
+
*
|
|
140
|
+
* @param parsed - The parsed document (may contain multiple blocks for markdown)
|
|
141
|
+
* @param position - File-absolute position (0-based line and column)
|
|
142
|
+
* @returns The semantic context at the position, or { kind: "unknown" } if not recognized
|
|
143
|
+
*/
|
|
144
|
+
declare function findNodeAtPosition(parsed: ParsedDocument<GenericTree>, position: Position): NodeContext;
|
|
145
|
+
//#endregion
|
|
146
|
+
export { DirectiveContext, EntityContext, FieldNameContext, LinkContext, MetadataKeyContext, NodeContext, SchemaEntityContext, SectionHeaderContext, SectionNameContext, TagContext, TimestampContext, TitleContext, TypeContext, UnknownContext, findNodeAtPosition };
|
|
147
|
+
//# sourceMappingURL=node-at-position.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-at-position.d.ts","names":[],"sources":["../../src/ast/node-at-position.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAqCA;AAUiB,UAVA,WAAA,CAUU;EAUV,IAAA,EAAA,MAAA;EAUA,MAAA,EAAA,MAAA;EAUA,IAAA,EArCT,IAqCS;EAUA,SAAA,EA9CJ,SA8CI;AAUjB;AAYA;AAYA;AAUA;AAYiB,UAhGA,UAAA,CAgGkB;EAYlB,IAAA,EAAA,KAAA;EAUA,OAAA,EAAA,MAAA;EAOL,IAAA,EA1HJ,GA0HI;EACR,SAAA,EA1HS,SA0HT;;;;;AAKA,UAzHa,gBAAA,CAyHb;EACA,IAAA,EAAA,WAAA;EACA,KAAA,EAAA,MAAA;EACA,IAAA,EAzHI,SAyHJ;EACA,SAAA,EAzHS,SAyHT;;;;;AAyIY,UA5PC,gBAAA,CA4PiB;EACT,IAAA,EAAA,WAAA;EAAf,SAAA,EAAA,MAAA;EACE,QAAA,EA3PA,QA2PA;EACT,SAAA,EA3PU,SA2PV;;;;;UArPc,aAAA;;;YAGL;aACC;;;;;UAMI,mBAAA;;;QAGT;aACK;;;;;UAMI,kBAAA;;;QAGT;;;aAGK;;;;;UAMI,oBAAA;;;YAGL;;;aAGC;;;;;UAMI,WAAA;;;QAGT;aACK;;;;;UAMI,gBAAA;;;QAGT;;;aAGK;;;;;UAMI,kBAAA;;;QAGT;;;aAGK;;;;;UAMI,YAAA;;;YAGL;aACC;;;;;UAMI,cAAA;;;;;;KAOL,WAAA,GACR,cACA,aACA,mBACA,mBACA,gBACA,sBACA,qBACA,uBACA,cACA,mBACA,qBACA,eACA;;;;;;;;;;;;iBAsIY,kBAAA,SACN,eAAe,wBACb,WACT"}
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
import { findBlockAtPosition, positionToPoint } from "../source-map.js";
|
|
2
|
+
import { extractFieldName, extractIdentifier, extractKey, extractLink, extractSectionName, extractTag, extractTimestamp, extractTypeExpression } from "./extract.js";
|
|
3
|
+
|
|
4
|
+
//#region src/ast/node-at-position.ts
|
|
5
|
+
/**
|
|
6
|
+
* Extract location from a syntax node
|
|
7
|
+
*/
|
|
8
|
+
function extractLocation(node) {
|
|
9
|
+
return {
|
|
10
|
+
startIndex: node.startIndex,
|
|
11
|
+
endIndex: node.endIndex,
|
|
12
|
+
startPosition: node.startPosition,
|
|
13
|
+
endPosition: node.endPosition
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Find the entry that contains a given node by walking up the tree
|
|
18
|
+
*/
|
|
19
|
+
function findContainingEntry(node) {
|
|
20
|
+
let current = node;
|
|
21
|
+
while (current) {
|
|
22
|
+
if (current.type === "entry") return current;
|
|
23
|
+
current = current.parent;
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Get the entity context (entity type name) from an entry node
|
|
29
|
+
*/
|
|
30
|
+
function getEntityContextFromEntry(entryNode) {
|
|
31
|
+
const child = entryNode.namedChildren[0];
|
|
32
|
+
if (!child) return;
|
|
33
|
+
if (child.type === "data_entry") {
|
|
34
|
+
const directive = child.childForFieldName("directive")?.text;
|
|
35
|
+
if (directive === "define-synthesis" || directive === "actualize-synthesis") return "synthesis";
|
|
36
|
+
const argumentNode = child.childForFieldName("argument");
|
|
37
|
+
if (argumentNode?.type === "identifier") return argumentNode.text;
|
|
38
|
+
} else if (child.type === "schema_entry") {
|
|
39
|
+
const argumentNode = child.childForFieldName("argument");
|
|
40
|
+
if (argumentNode) return argumentNode.text;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Check if position is within a node
|
|
45
|
+
*/
|
|
46
|
+
function isPositionInNode(point, node) {
|
|
47
|
+
const start = node.startPosition;
|
|
48
|
+
const end = node.endPosition;
|
|
49
|
+
if (point.row < start.row || point.row === start.row && point.column < start.column) return false;
|
|
50
|
+
if (point.row > end.row || point.row === end.row && point.column > end.column) return false;
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Check if position is on a directive keyword within an entry
|
|
55
|
+
*/
|
|
56
|
+
function checkForDirective(node, point, sourceMap) {
|
|
57
|
+
let current = node;
|
|
58
|
+
while (current) {
|
|
59
|
+
if (current.type === "data_entry" || current.type === "schema_entry") {
|
|
60
|
+
const directiveNode = current.childForFieldName("directive");
|
|
61
|
+
if (directiveNode && isPositionInNode(point, directiveNode)) return {
|
|
62
|
+
kind: "directive",
|
|
63
|
+
directive: directiveNode.text,
|
|
64
|
+
location: extractLocation(directiveNode),
|
|
65
|
+
sourceMap
|
|
66
|
+
};
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
current = current.parent;
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Find the semantic context of a node at a given position in a parsed document.
|
|
75
|
+
*
|
|
76
|
+
* This function handles both standalone .thalo files and embedded thalo blocks
|
|
77
|
+
* in markdown files. It uses the source map to convert file-absolute positions
|
|
78
|
+
* to block-relative positions before querying the AST.
|
|
79
|
+
*
|
|
80
|
+
* @param parsed - The parsed document (may contain multiple blocks for markdown)
|
|
81
|
+
* @param position - File-absolute position (0-based line and column)
|
|
82
|
+
* @returns The semantic context at the position, or { kind: "unknown" } if not recognized
|
|
83
|
+
*/
|
|
84
|
+
function findNodeAtPosition(parsed, position) {
|
|
85
|
+
const match = findBlockAtPosition(parsed.blocks, position);
|
|
86
|
+
if (!match) return { kind: "unknown" };
|
|
87
|
+
const { block, blockPosition } = match;
|
|
88
|
+
const point = positionToPoint(blockPosition);
|
|
89
|
+
let node = block.tree.rootNode.descendantForPosition(point);
|
|
90
|
+
if (!node) return { kind: "unknown" };
|
|
91
|
+
const endMatchingChild = findChildEndingAt(node, point);
|
|
92
|
+
if (endMatchingChild) node = endMatchingChild;
|
|
93
|
+
return classifyNode(node, point, block);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Find a child node that ends exactly at the given position.
|
|
97
|
+
* This helps handle edge cases where cursor is right at the end of a token.
|
|
98
|
+
*/
|
|
99
|
+
function findChildEndingAt(node, point) {
|
|
100
|
+
for (const child of node.namedChildren) {
|
|
101
|
+
if (!child) continue;
|
|
102
|
+
const end = child.endPosition;
|
|
103
|
+
if (end.row === point.row && end.column === point.column) return findChildEndingAt(child, point) || child;
|
|
104
|
+
if (isPositionInNode(point, child)) return findChildEndingAt(child, point);
|
|
105
|
+
}
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Check if a node is inside an ERROR context (parse error recovery)
|
|
110
|
+
*/
|
|
111
|
+
function isInsideErrorNode(node) {
|
|
112
|
+
let current = node;
|
|
113
|
+
while (current) {
|
|
114
|
+
if (current.type === "ERROR") return true;
|
|
115
|
+
current = current.parent;
|
|
116
|
+
}
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Classify a syntax node into a semantic context
|
|
121
|
+
*/
|
|
122
|
+
function classifyNode(node, point, block) {
|
|
123
|
+
const { sourceMap } = block;
|
|
124
|
+
switch (node.type) {
|
|
125
|
+
case "link": return {
|
|
126
|
+
kind: "link",
|
|
127
|
+
linkId: extractLink(node).id,
|
|
128
|
+
node: extractLink(node),
|
|
129
|
+
sourceMap
|
|
130
|
+
};
|
|
131
|
+
case "tag": return {
|
|
132
|
+
kind: "tag",
|
|
133
|
+
tagName: extractTag(node).name,
|
|
134
|
+
node: extractTag(node),
|
|
135
|
+
sourceMap
|
|
136
|
+
};
|
|
137
|
+
case "timestamp": return {
|
|
138
|
+
kind: "timestamp",
|
|
139
|
+
value: extractTimestamp(node).value,
|
|
140
|
+
node: extractTimestamp(node),
|
|
141
|
+
sourceMap
|
|
142
|
+
};
|
|
143
|
+
case "timestamp_date":
|
|
144
|
+
case "timestamp_t":
|
|
145
|
+
case "timestamp_time":
|
|
146
|
+
case "timestamp_tz": {
|
|
147
|
+
const parent = node.parent;
|
|
148
|
+
if (parent && parent.type === "timestamp") return {
|
|
149
|
+
kind: "timestamp",
|
|
150
|
+
value: extractTimestamp(parent).value,
|
|
151
|
+
node: extractTimestamp(parent),
|
|
152
|
+
sourceMap
|
|
153
|
+
};
|
|
154
|
+
return { kind: "unknown" };
|
|
155
|
+
}
|
|
156
|
+
case "key": return classifyKeyNode(node, sourceMap);
|
|
157
|
+
case "primitive_type":
|
|
158
|
+
case "literal_type":
|
|
159
|
+
case "array_type":
|
|
160
|
+
case "union_type": {
|
|
161
|
+
const typeExpr = extractTypeExpression(node.parent ?? node);
|
|
162
|
+
if (typeExpr.type === "syntax_error") return { kind: "unknown" };
|
|
163
|
+
return {
|
|
164
|
+
kind: "type",
|
|
165
|
+
typeName: node.type === "primitive_type" ? node.text : node.type,
|
|
166
|
+
node: typeExpr,
|
|
167
|
+
sourceMap
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
case "field_name": return classifyFieldNameNode(node, sourceMap);
|
|
171
|
+
case "section_name": return classifySectionNameNode(node, sourceMap);
|
|
172
|
+
case "title": {
|
|
173
|
+
if (isInsideErrorNode(node)) return { kind: "unknown" };
|
|
174
|
+
const text = node.text;
|
|
175
|
+
return {
|
|
176
|
+
kind: "title",
|
|
177
|
+
title: text.endsWith("\"") && text.length > 1 ? text.slice(1, -1) : text.slice(1),
|
|
178
|
+
location: extractLocation(node),
|
|
179
|
+
sourceMap
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
case "identifier": return classifyIdentifierNode(node, sourceMap);
|
|
183
|
+
case "markdown_header": return classifyMarkdownHeader(node, sourceMap);
|
|
184
|
+
}
|
|
185
|
+
const directiveContext = checkForDirective(node, point, sourceMap);
|
|
186
|
+
if (directiveContext) return directiveContext;
|
|
187
|
+
let current = node;
|
|
188
|
+
while (current) {
|
|
189
|
+
if (current.type === "data_entry") {
|
|
190
|
+
const directive = current.childForFieldName("directive")?.text;
|
|
191
|
+
if (directive === "create" || directive === "update") {
|
|
192
|
+
const argumentNode = current.childForFieldName("argument");
|
|
193
|
+
if (argumentNode && argumentNode.type === "identifier" && isPositionInNode(point, argumentNode)) return {
|
|
194
|
+
kind: "entity",
|
|
195
|
+
entityName: argumentNode.text,
|
|
196
|
+
location: extractLocation(argumentNode),
|
|
197
|
+
sourceMap
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (current.type === "schema_entry") {
|
|
202
|
+
const argumentNode = current.childForFieldName("argument");
|
|
203
|
+
if (argumentNode && isPositionInNode(point, argumentNode)) return {
|
|
204
|
+
kind: "schema_entity",
|
|
205
|
+
entityName: argumentNode.text,
|
|
206
|
+
node: extractIdentifier(argumentNode),
|
|
207
|
+
sourceMap
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
current = current.parent;
|
|
211
|
+
}
|
|
212
|
+
const entityFallback = checkForUnrecognizedEntity(node, point, sourceMap, block);
|
|
213
|
+
if (entityFallback) return entityFallback;
|
|
214
|
+
const sectionFallback = checkForSectionHeader(node, point, sourceMap, block);
|
|
215
|
+
if (sectionFallback) return sectionFallback;
|
|
216
|
+
return { kind: "unknown" };
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Check if we're on text that looks like an entity name but wasn't recognized by parser.
|
|
220
|
+
* This handles the case of unknown/invalid entity names.
|
|
221
|
+
*/
|
|
222
|
+
function checkForUnrecognizedEntity(_node, point, sourceMap, block) {
|
|
223
|
+
const lineText = getLineTextFromBlock(block, point.row);
|
|
224
|
+
if (!lineText) return null;
|
|
225
|
+
const match = lineText.match(/^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?:Z|[+-]\d{2}:\d{2}))\s+(create|update)\s+([a-z][a-zA-Z0-9\-_]*)/);
|
|
226
|
+
if (!match) return null;
|
|
227
|
+
const [fullMatch, , , entityName] = match;
|
|
228
|
+
const entityStart = fullMatch.lastIndexOf(entityName);
|
|
229
|
+
const entityEnd = entityStart + entityName.length;
|
|
230
|
+
if (point.column >= entityStart && point.column <= entityEnd) return {
|
|
231
|
+
kind: "entity",
|
|
232
|
+
entityName,
|
|
233
|
+
location: {
|
|
234
|
+
startIndex: 0,
|
|
235
|
+
endIndex: 0,
|
|
236
|
+
startPosition: {
|
|
237
|
+
row: point.row,
|
|
238
|
+
column: entityStart
|
|
239
|
+
},
|
|
240
|
+
endPosition: {
|
|
241
|
+
row: point.row,
|
|
242
|
+
column: entityEnd
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
sourceMap
|
|
246
|
+
};
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Get line text from a parsed block
|
|
251
|
+
*/
|
|
252
|
+
function getLineTextFromBlock(block, lineNumber) {
|
|
253
|
+
const lines = block.source.split("\n");
|
|
254
|
+
if (lineNumber >= 0 && lineNumber < lines.length) return lines[lineNumber];
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Check if we're on a section header in content (# SectionName)
|
|
259
|
+
* This handles cases where the parser might not properly recognize content section headers
|
|
260
|
+
*/
|
|
261
|
+
function checkForSectionHeader(node, point, sourceMap, block) {
|
|
262
|
+
const lineText = getLineTextFromBlock(block, point.row);
|
|
263
|
+
if (!lineText) return null;
|
|
264
|
+
const match = lineText.match(/^(\s*)#\s*([A-Z][a-zA-Z0-9]*)/);
|
|
265
|
+
if (!match) return null;
|
|
266
|
+
const [fullMatch, indent, sectionName] = match;
|
|
267
|
+
const hashStart = indent.length;
|
|
268
|
+
const sectionEnd = lineText.indexOf(sectionName, hashStart) + sectionName.length;
|
|
269
|
+
if (point.column >= hashStart && point.column <= sectionEnd) {
|
|
270
|
+
const entry = findContainingEntry(node);
|
|
271
|
+
const entityContext = entry ? getEntityContextFromEntry(entry) : void 0;
|
|
272
|
+
return {
|
|
273
|
+
kind: "section_header",
|
|
274
|
+
sectionName,
|
|
275
|
+
location: {
|
|
276
|
+
startIndex: 0,
|
|
277
|
+
endIndex: 0,
|
|
278
|
+
startPosition: {
|
|
279
|
+
row: point.row,
|
|
280
|
+
column: hashStart
|
|
281
|
+
},
|
|
282
|
+
endPosition: {
|
|
283
|
+
row: point.row,
|
|
284
|
+
column: fullMatch.length
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
entityContext,
|
|
288
|
+
sourceMap
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
return null;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Classify a key node (metadata key)
|
|
295
|
+
*/
|
|
296
|
+
function classifyKeyNode(node, sourceMap) {
|
|
297
|
+
const entry = findContainingEntry(node);
|
|
298
|
+
const entityContext = entry ? getEntityContextFromEntry(entry) : void 0;
|
|
299
|
+
return {
|
|
300
|
+
kind: "metadata_key",
|
|
301
|
+
key: extractKey(node).value,
|
|
302
|
+
node: extractKey(node),
|
|
303
|
+
entityContext,
|
|
304
|
+
sourceMap
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Classify a field_name node in schema definitions
|
|
309
|
+
*/
|
|
310
|
+
function classifyFieldNameNode(node, sourceMap) {
|
|
311
|
+
const entry = findContainingEntry(node);
|
|
312
|
+
const entityContext = entry ? getEntityContextFromEntry(entry) : void 0;
|
|
313
|
+
return {
|
|
314
|
+
kind: "field_name",
|
|
315
|
+
fieldName: extractFieldName(node).value,
|
|
316
|
+
node: extractFieldName(node),
|
|
317
|
+
entityContext,
|
|
318
|
+
sourceMap
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Classify a section_name node in schema definitions
|
|
323
|
+
*/
|
|
324
|
+
function classifySectionNameNode(node, sourceMap) {
|
|
325
|
+
const entry = findContainingEntry(node);
|
|
326
|
+
const entityContext = entry ? getEntityContextFromEntry(entry) : void 0;
|
|
327
|
+
return {
|
|
328
|
+
kind: "section_name",
|
|
329
|
+
sectionName: extractSectionName(node).value,
|
|
330
|
+
node: extractSectionName(node),
|
|
331
|
+
entityContext,
|
|
332
|
+
sourceMap
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Classify an identifier node
|
|
337
|
+
*/
|
|
338
|
+
function classifyIdentifierNode(node, sourceMap) {
|
|
339
|
+
const parent = node.parent;
|
|
340
|
+
if (parent?.type === "data_entry") {
|
|
341
|
+
const directive = parent.childForFieldName("directive")?.text;
|
|
342
|
+
if (directive === "create" || directive === "update") {
|
|
343
|
+
const argumentNode = parent.childForFieldName("argument");
|
|
344
|
+
if (argumentNode && argumentNode.id === node.id) return {
|
|
345
|
+
kind: "entity",
|
|
346
|
+
entityName: node.text,
|
|
347
|
+
location: extractLocation(node),
|
|
348
|
+
sourceMap
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
if (parent?.type === "schema_entry") {
|
|
353
|
+
const argumentNode = parent.childForFieldName("argument");
|
|
354
|
+
if (argumentNode && argumentNode.id === node.id) return {
|
|
355
|
+
kind: "schema_entity",
|
|
356
|
+
entityName: node.text,
|
|
357
|
+
node: extractIdentifier(node),
|
|
358
|
+
sourceMap
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
return { kind: "unknown" };
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Classify a markdown_header node (section in content)
|
|
365
|
+
*/
|
|
366
|
+
function classifyMarkdownHeader(node, sourceMap) {
|
|
367
|
+
const entry = findContainingEntry(node);
|
|
368
|
+
const entityContext = entry ? getEntityContextFromEntry(entry) : void 0;
|
|
369
|
+
const text = node.text.trim();
|
|
370
|
+
const match = text.match(/^#\s*([A-Z][a-zA-Z0-9]*)/);
|
|
371
|
+
return {
|
|
372
|
+
kind: "section_header",
|
|
373
|
+
sectionName: match ? match[1] : text.replace(/^#\s*/, ""),
|
|
374
|
+
location: extractLocation(node),
|
|
375
|
+
entityContext,
|
|
376
|
+
sourceMap
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
//#endregion
|
|
381
|
+
export { findNodeAtPosition };
|
|
382
|
+
//# sourceMappingURL=node-at-position.js.map
|