@yuji-min/google-docs-parser 1.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/README.md +242 -0
- package/dist/index.cjs +426 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +172 -0
- package/dist/index.d.ts +172 -0
- package/dist/index.js +424 -0
- package/dist/index.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/utils.ts","../src/tree.ts","../src/list.ts","../src/textBlock.ts","../src/section.ts","../src/cursor.ts","../src/auth.ts","../src/parser.ts"],"names":["GoogleAuth","google"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * A constant tuple of supported Google Docs named styles that represent headings or titles.\n * These are used to identify structural nodes and section boundaries within the document tree.\n */\nexport const VALID_NAMED_STYLES = [\n \"HEADING_1\",\n \"HEADING_2\",\n \"HEADING_3\",\n \"HEADING_4\",\n \"HEADING_5\",\n \"HEADING_6\",\n \"TITLE\",\n \"SUBTITLE\",\n] as const;\n\n/**\n * A union type representing any one of the valid named styles defined in `VALID_NAMED_STYLES`.\n */\nexport type ValidNamedStyle = (typeof VALID_NAMED_STYLES)[number];\n\n/**\n * A Set containing the valid named styles for efficient O(1) validation checks.\n * This is primarily used in type guards to verify if a style string is a valid heading.\n */\nexport const VALID_NAMED_STYLES_SET = new Set<string>(VALID_NAMED_STYLES);\n","import { docs_v1 } from \"googleapis\";\nimport { Schema, NamedStyleType } from \"./types\";\nimport { VALID_NAMED_STYLES_SET } from \"./constants\";\n\n/**\n * Extracts pure text content from a Google Docs Paragraph.\n *\n * - Joins content from all `textRun` elements.\n * - Trims leading and trailing whitespace.\n * - Normalizes newline characters (`\\n`) to spaces.\n *\n * @param paragraph - The Google Docs paragraph object.\n * @returns The extracted and cleaned text string. Returns an empty string if the paragraph is empty.\n */\nexport function extractParagraphText(\n paragraph: docs_v1.Schema$Paragraph\n): string {\n const elements = paragraph.elements ?? [];\n\n const text = elements\n .map((el: docs_v1.Schema$ParagraphElement) => el.textRun?.content || \"\")\n .join(\"\")\n .trim()\n .replace(/\\n/g, \" \");\n\n return text || \"\";\n}\n\n/**\n * Checks if a paragraph has a specific `namedStyleType` (e.g., HEADING_1).\n *\n * @param paragraph - The paragraph to check.\n * @param namedStyleType - The style type to compare against.\n * @returns `true` if the paragraph's style matches the provided type; otherwise `false`.\n */\nexport function hasNamedStyle(\n paragraph: docs_v1.Schema$Paragraph,\n namedStyleType?: NamedStyleType\n): boolean {\n if (!namedStyleType) return false;\n const style = paragraph.paragraphStyle?.namedStyleType;\n return style === namedStyleType;\n}\n\n/**\n * Retrieves the named style type of a paragraph, handling default behaviors and edge cases.\n *\n * Resolution Logic:\n * 1. Returns `undefined` if the paragraph has no style and no content (completely empty).\n * 2. Returns `\"NORMAL_TEXT\"` if the paragraph has content but no explicit style (Google Docs default).\n * 3. Returns `\"NORMAL_TEXT\"` if the style object exists but `namedStyleType` is missing.\n * 4. Returns the `namedStyleType` if it exists in the valid set (`VALID_NAMED_STYLES`).\n * 5. Returns `undefined` if the style is invalid or unknown.\n *\n * @param paragraph - The paragraph to analyze.\n * @returns The valid `NamedStyleType`, `\"NORMAL_TEXT\"`, or `undefined`.\n */\nexport function getParagraphNamedStyleType(\n paragraph: docs_v1.Schema$Paragraph\n): NamedStyleType | \"NORMAL_TEXT\" | undefined {\n if (!paragraph.paragraphStyle && !paragraph.elements?.length) {\n return undefined;\n }\n if (!paragraph.paragraphStyle) {\n return \"NORMAL_TEXT\";\n }\n\n const namedStyleType = paragraph.paragraphStyle.namedStyleType;\n\n if (!namedStyleType) {\n return \"NORMAL_TEXT\";\n }\n\n if (VALID_NAMED_STYLES_SET.has(namedStyleType)) {\n return namedStyleType as NamedStyleType;\n }\n\n return undefined;\n}\n\n/**\n * Type Guard to check if a style is a valid Heading style (HEADING_1~6, TITLE, SUBTITLE).\n *\n * - Returns `false` for `\"NORMAL_TEXT\"`.\n * - Returns `false` for undefined or invalid strings.\n *\n * @param style - The style string to check.\n * @returns `true` if the style is a valid `NamedStyleType`.\n */\nexport function isNamedStyleType(\n style: NamedStyleType | \"NORMAL_TEXT\" | undefined\n): style is NamedStyleType {\n if (typeof style !== \"string\") return false;\n if (style === \"NORMAL_TEXT\") return false;\n\n return VALID_NAMED_STYLES_SET.has(style);\n}\n\n/**\n * Splits a string by a delimiter and trims whitespace from each item.\n *\n * @param text - The string to split.\n * @param delimiter - The character to split by (e.g., \",\").\n * @param filterEmpty - If `true`, removes empty strings from the result. Defaults to `false`.\n * @returns An array of trimmed strings.\n */\nexport function splitAndTrim(\n text: string,\n delimiter: string,\n filterEmpty = false\n): string[] {\n if (text === \"\") {\n return [];\n }\n const items = text.split(delimiter).map((t) => t.trim());\n return filterEmpty ? items.filter((t) => t.length > 0) : items;\n}\n\n/**\n * Parses text into a Key-Value list structure.\n *\n * Format: \"Key: Value1, Value2\"\n *\n * @param text - The text to parse.\n * @param keyDelimiter - The separator between key and values (e.g., \":\").\n * @param listDelimiter - The separator between list items (e.g., \",\").\n * @returns An object `{ key, value[] }` if parsing succeeds, or the original text string if the key delimiter is missing.\n */\nexport function parseToKeyedList(\n text: string,\n keyDelimiter: string,\n listDelimiter: string\n): { key: string; value: string[] } | string {\n const delimiterIndex = text.indexOf(keyDelimiter);\n\n if (delimiterIndex <= 0) {\n return text;\n }\n\n const key = text.substring(0, delimiterIndex).trim();\n const valuePart = text.substring(delimiterIndex + keyDelimiter.length).trim();\n\n const value = valuePart ? splitAndTrim(valuePart, listDelimiter, true) : [];\n\n return { key, value };\n}\n\n/**\n * Maps delimited text values to a list of keys by position.\n *\n * Format: \"Value1 | Value2 | Value3\" -> { Key1: \"Value1\", Key2: \"Value2\", ... }\n *\n * @param text - The text to parse.\n * @param keys - The list of field names (keys) to map values to.\n * @param delimiter - The separator between values (e.g., \"|\").\n * @returns A record object mapping keys to values. Missing values are filled with empty strings.\n */\nexport function parseToFields(\n text: string,\n keys: readonly string[],\n delimiter: string\n): Record<string, unknown> {\n const values = splitAndTrim(text, delimiter, false);\n\n return keys.reduce((acc, key, index) => {\n const value = values[index];\n acc[key] = value !== undefined && value !== \"\" ? value : \"\";\n return acc;\n }, {} as Record<string, unknown>);\n}\n\n/**\n * Parses a simple delimited string into an array, filtering out empty items.\n *\n * Example: \"Apple, , Banana\" -> [\"Apple\", \"Banana\"]\n *\n * @param text - The text to parse.\n * @param delimiter - The separator (e.g., \",\").\n * @returns An array of non-empty strings.\n */\nexport function parseDelimitedList(text: string, delimiter: string): string[] {\n const values = text\n .split(delimiter)\n .map((v) => v.trim())\n .filter((v) => v.length > 0);\n return values;\n}\n\n/**\n * Parses a single line of text into structured data based on the provided Schema.\n *\n * **Parsing Priorities:**\n * 1. **Keyed List**: If `schema.keyDelimiter` is set. (e.g., \"Team: A, B\")\n * 2. **Fixed Fields**: If `schema.keys` is set. (e.g., \"Google | Engineer | 2023\")\n * 3. **Default List**: Fallback to simple delimited list. (e.g., \"A, B, C\")\n *\n * @param text - The text content to parse.\n * @param schema - The schema object defining the parsing rules.\n * @returns The parsed result as an object, array, or string depending on the schema.\n */\nexport function parseStructuredText(\n text: string,\n schema: Schema\n): Record<string, unknown> | string[] | string {\n const delimiter = schema.delimiter || \",\";\n\n if (schema.keyDelimiter) {\n return parseToKeyedList(text, schema.keyDelimiter, delimiter);\n }\n\n if (schema.keys && schema.keys.length > 0) {\n return parseToFields(text, schema.keys, delimiter);\n }\n\n return parseDelimitedList(text, delimiter);\n}\n","import { docs_v1 } from \"googleapis\";\nimport { NamedStyleType, Node, Section, Schema } from \"./types\";\nimport { ParagraphCursor } from \"./cursor\";\nimport { hasNamedStyle, parseStructuredText } from \"./utils\";\n\nconst CONTENT_KEY = \"content\";\n\n/**\n * Recursively collects all `NamedStyleType`s defined within a nested `Node` schema.\n *\n * This is used to build a set of allowed heading styles for the parser to recognize\n * valid tree nodes and detect boundaries.\n *\n * @param node - The current node schema to traverse.\n * @param set - The Set to populate with collected style types.\n */\nexport function collectNodeStylesRecursive(\n node: Node,\n set: Set<NamedStyleType>\n): void {\n if (node.title.namedStyleType) set.add(node.title.namedStyleType);\n if (node.content && node.content.kind === \"tree\") {\n collectNodeStylesRecursive(node.content.node, set);\n }\n}\n\n/**\n * Creates a normalized node object from a raw title string based on the provided schema.\n *\n * - If the schema defines parsing rules (delimiters/keys), the title is parsed into\n * structured data (Array or Object).\n * - If no parsing rules exist, the title is treated as a simple string.\n *\n * @param text - The raw text of the title/heading.\n * @param titleSchema - The schema defining how to parse the title.\n * @returns An object containing the parsed `title` and an empty `content` array.\n */\nexport function createNodeFromTitle(\n text: string,\n titleSchema: Schema\n): Record<\"title\" | \"content\", unknown> {\n const hasDelimiterSchema =\n !!titleSchema.keyDelimiter ||\n (!!titleSchema.keys && titleSchema.keys.length > 0) ||\n !!titleSchema.delimiter;\n\n if (hasDelimiterSchema) {\n const structuredText = parseStructuredText(text, titleSchema);\n if (Array.isArray(structuredText)) {\n return { title: structuredText, content: [] };\n } else if (typeof structuredText === \"object\" && structuredText !== null) {\n return { title: structuredText, content: [] };\n } else {\n return { title: text, content: [] };\n }\n } else {\n return { title: text, content: [] };\n }\n}\n\n/**\n * Represents the decision made by the parser for the current paragraph.\n */\nexport type TreeParsingAction =\n | { kind: \"exitSection\" }\n | { kind: \"createNode\" }\n | { kind: \"startChildNode\" }\n | { kind: \"finishCurrentNode\" }\n | { kind: \"appendDetail\" };\n\n/**\n * Determines the next action to take based on the current paragraph's style\n * and its relationship to the current node hierarchy.\n *\n * Decision Logic Priorities:\n * 1. New Section -> Exit.\n * 2. Matches Current Node Title -> Create Sibling Node.\n * 3. Matches Child Node Title -> Start Child Node (Recursion).\n * 4. Matches Ancestor/Same Level Heading -> Finish Current Node (Pop Stack).\n * 5. Heading outside this tree -> Exit.\n * 6. Otherwise -> Append as detail content.\n *\n * @param paragraph - The current paragraph being inspected.\n * @param cursor - The paragraph cursor.\n * @param nodeSchema - The schema for the current node level.\n * @param ancestorNodeList - The stack of ancestor nodes for context.\n * @returns The determining parsing action.\n */\nexport function determineTreeParsingAction(\n paragraph: docs_v1.Schema$Paragraph,\n cursor: ParagraphCursor,\n nodeSchema: Node,\n ancestorNodeList: Node[]\n): TreeParsingAction {\n const nodeTitleStyle = nodeSchema.title.namedStyleType;\n const childNode =\n nodeSchema.content?.kind === \"tree\" ? nodeSchema.content.node : undefined;\n\n const isCurrentNodeTitle = hasNamedStyle(paragraph, nodeTitleStyle);\n const isChildNodeTitle =\n !!childNode && hasNamedStyle(paragraph, childNode.title.namedStyleType);\n const isAncestorNodeTitle = ancestorNodeList.some((a) =>\n hasNamedStyle(paragraph, a.title.namedStyleType)\n );\n\n const isInThisTree =\n isCurrentNodeTitle || isChildNodeTitle || isAncestorNodeTitle;\n\n const isHeading = cursor.isAtParagraphHeading();\n const isAtNewSection = cursor.isAtNewSection();\n const isHeadingOutsideThisTree = isHeading && !isInThisTree;\n const isHigherLevelHeading = isHeading && isAncestorNodeTitle;\n const isSameLevelHeading = isHeading && isCurrentNodeTitle;\n\n if (isAtNewSection) return { kind: \"exitSection\" };\n if (isCurrentNodeTitle) return { kind: \"createNode\" };\n if (isChildNodeTitle) return { kind: \"startChildNode\" };\n if (isHigherLevelHeading || isSameLevelHeading)\n return { kind: \"finishCurrentNode\" };\n if (isHeadingOutsideThisTree) return { kind: \"exitSection\" };\n return { kind: \"appendDetail\" };\n}\n\n/**\n * The entry point for parsing a document section defined as a `Tree`.\n *\n * It searches for the first occurrence of the root node style to begin parsing.\n * Text preceding the first valid root node is ignored (orphan text).\n *\n * @param cursor - The cursor traversing the document paragraphs.\n * @param section - The section definition containing the tree schema.\n * @param allNodeTitleStyles - A set of all valid styles in this tree (for boundary detection).\n * @returns An array of parsed tree nodes.\n */\nexport function parseTreeSection(\n cursor: ParagraphCursor,\n section: Section,\n allNodeTitleStyles: Set<NamedStyleType>\n): unknown[] {\n const treeContent = section.content;\n const nodeSchema =\n treeContent?.kind === \"tree\" ? treeContent.node : undefined;\n if (!treeContent || !nodeSchema) return [];\n\n while (!cursor.isEndOfDocument()) {\n const info = cursor.getCurrentParagraph();\n if (!info) {\n cursor.getNextParagraph();\n continue;\n }\n\n const { paragraph, style } = info;\n\n if (cursor.isAtNewSection()) break;\n if (cursor.isAtParagraphHeading() && !allNodeTitleStyles.has(style)) break;\n\n if (hasNamedStyle(paragraph, nodeSchema.title.namedStyleType)) {\n return parseTreeNode(cursor, nodeSchema, [], allNodeTitleStyles);\n }\n\n cursor.getNextParagraph();\n }\n return [];\n}\n\n/**\n * Recursively parses a specific level of the tree structure.\n *\n * Handles creation of current nodes, delegating to child parsers for nested content,\n * and accumulating list details.\n *\n * @param cursor - The cursor traversing the document paragraphs.\n * @param nodeSchema - The schema for the current node level.\n * @param ancestorNodeList - Stack of ancestors to detect hierarchy boundaries.\n * @param allNodeTitleStyles - Set of all valid styles for boundary checks.\n * @returns An array of parsed nodes for this level.\n */\nexport function parseTreeNode(\n cursor: ParagraphCursor,\n nodeSchema: Node,\n ancestorNodeList: Node[],\n allNodeTitleStyles: Set<NamedStyleType>\n): unknown[] {\n const result: unknown[] = [];\n let currentNode: Record<string, unknown> | null = null;\n\n const childNodeSchema =\n nodeSchema.content?.kind === \"tree\" ? nodeSchema.content.node : undefined;\n\n while (!cursor.isEndOfDocument()) {\n const info = cursor.getCurrentParagraph();\n if (!info) {\n cursor.getNextParagraph();\n continue;\n }\n\n const { text, paragraph, style } = info;\n\n if (cursor.isAtNewSection()) {\n return result;\n }\n\n if (cursor.isAtParagraphHeading() && !allNodeTitleStyles.has(style)) {\n return result;\n }\n\n const decision = determineTreeParsingAction(\n paragraph,\n cursor,\n nodeSchema,\n ancestorNodeList\n );\n\n switch (decision.kind) {\n case \"exitSection\": {\n return result;\n }\n\n case \"createNode\": {\n currentNode = createNodeFromTitle(text, nodeSchema.title);\n result.push(currentNode);\n cursor.getNextParagraph();\n break;\n }\n\n case \"startChildNode\": {\n if (\n !currentNode ||\n !Array.isArray(currentNode[CONTENT_KEY]) ||\n !childNodeSchema\n ) {\n cursor.getNextParagraph();\n break;\n }\n const children = parseTreeNode(\n cursor,\n childNodeSchema,\n [nodeSchema, ...ancestorNodeList],\n allNodeTitleStyles\n );\n (currentNode[CONTENT_KEY] as unknown[]).push(...children);\n break;\n }\n\n case \"finishCurrentNode\": {\n if (currentNode) return result;\n cursor.getNextParagraph();\n break;\n }\n\n case \"appendDetail\": {\n if (nodeSchema.content?.kind === \"tree\") {\n cursor.getNextParagraph();\n break;\n }\n if (currentNode && Array.isArray(currentNode[CONTENT_KEY])) {\n (currentNode[CONTENT_KEY] as unknown[]).push(text.trim());\n }\n cursor.getNextParagraph();\n break;\n }\n }\n }\n\n return result;\n}\n","import { Section } from \"./types\";\nimport { ParagraphCursor } from \"./cursor\";\nimport { parseStructuredText } from \"./utils\";\n\n/**\n * Parses a section defined as a 'List'.\n *\n * This function iterates through paragraphs, parsing each line according to the\n * section's content schema (e.g., delimiters, keys). It supports both flat lists\n * and nested structures depending on the `isFlatten` configuration.\n *\n * @param cursor - The cursor traversing the document paragraphs.\n * @param section - The section definition containing the list schema.\n * @returns An array of parsed items (strings, objects, or arrays).\n */\nexport function parseListSection(\n cursor: ParagraphCursor,\n section: Section\n): unknown[] {\n const result: unknown[] = [];\n if (!section.content || section.content.kind !== \"list\") {\n return [];\n }\n const contentSchema = section.content;\n\n while (!cursor.isEndOfDocument()) {\n const info = cursor.getCurrentParagraph();\n if (!info) {\n cursor.getNextParagraph();\n continue;\n }\n\n if (cursor.isAtNewSection()) break;\n if (cursor.isAtParagraphHeading()) break;\n\n const parsed = parseStructuredText(info.text, contentSchema);\n\n if (contentSchema.isFlatten && Array.isArray(parsed)) {\n result.push(...parsed);\n } else {\n result.push(parsed);\n }\n cursor.getNextParagraph();\n }\n return result;\n}\n","import { ParagraphCursor } from \"./cursor\";\n\n/**\n * Parses a continuous block of text paragraphs into a single string.\n *\n * This function iterates through paragraphs starting from the current cursor position\n * and collects text until a boundary is encountered.\n *\n * **Stop Conditions:**\n * 1. **New Section:** The cursor reaches a paragraph that marks the start of a new section defined in the schema.\n * 2. **Heading:** The cursor reaches any paragraph with a named heading style (e.g., HEADING_1, HEADING_2).\n *\n * @param cursor - The cursor traversing the document paragraphs.\n * @returns The combined text content of the block, joined by spaces.\n */\nexport function parseTextBlockSection(cursor: ParagraphCursor): string {\n const textPartList: string[] = [];\n\n while (!cursor.isEndOfDocument()) {\n const paragraph = cursor.getCurrentParagraph();\n if (!paragraph) {\n cursor.getNextParagraph();\n continue;\n }\n\n if (cursor.isAtNewSection()) break;\n if (cursor.isAtParagraphHeading()) break;\n\n textPartList.push(paragraph.text);\n cursor.getNextParagraph();\n }\n return textPartList.join(\" \");\n}\n","import { docs_v1 } from \"googleapis\";\nimport { ParseSchema, Section, NamedStyleType } from \"./types\";\nimport { hasNamedStyle } from \"./utils\";\nimport { ParagraphCursor } from \"./cursor\";\nimport { parseTreeSection, collectNodeStylesRecursive } from \"./tree\";\nimport { parseListSection } from \"./list\";\nimport { parseTextBlockSection } from \"./textBlock\";\n\n/**\n * Identifies if a paragraph corresponds to a section title defined in the schema.\n *\n * Matching Logic:\n * 1. Matches the paragraph's named style (e.g., HEADING_2) with the section's style.\n * 2. Matches the text content (case-insensitive, trimmed).\n *\n * @param paragraph - The current paragraph being inspected.\n * @param text - The extracted text content of the paragraph.\n * @param parseSchema - The global parsing schema containing section definitions.\n * @returns The canonical name of the section if found, otherwise `null`.\n */\nexport function getSectionTitle(\n paragraph: docs_v1.Schema$Paragraph,\n text: string,\n parseSchema: ParseSchema\n): string | null {\n const normalized = text.trim().toLowerCase();\n const sectionList = parseSchema.sections ?? [];\n\n for (const section of sectionList) {\n const { name, namedStyleType } = section.title;\n if (name && namedStyleType) {\n const styleMatches = hasNamedStyle(paragraph, namedStyleType);\n const textMatches = normalized === name.trim().toLowerCase();\n if (styleMatches && textMatches) {\n return name;\n }\n }\n }\n return null;\n}\n\n/**\n * Dispatches the parsing logic to the appropriate handler based on the section's content type.\n *\n * - **Tree:** Delegates to `parseTreeSection` for hierarchical data.\n * - **List:** Delegates to `parseListSection` for flat lists.\n * - **TextBlock (Default):** Delegates to `parseTextBlockSection` if no content structure is defined.\n *\n * @param cursor - The paragraph cursor.\n * @param section - The section definition containing the content schema.\n * @returns The parsed result (String, Array, or Object depending on the type).\n */\nexport function parseSectionContent(\n cursor: ParagraphCursor,\n section: Section\n): unknown {\n const content = section.content;\n\n if (!content) {\n return parseTextBlockSection(cursor);\n }\n\n switch (content.kind) {\n case \"tree\": {\n if (!content.node) {\n return [];\n }\n const allNodeTitleStyles = new Set<NamedStyleType>();\n collectNodeStylesRecursive(content.node, allNodeTitleStyles);\n return parseTreeSection(cursor, section, allNodeTitleStyles);\n }\n case \"list\":\n return parseListSection(cursor, section);\n default:\n return parseTextBlockSection(cursor);\n }\n}\n","import { docs_v1 } from \"googleapis\";\nimport { ParseSchema, NamedStyleType } from \"./types\";\nimport {\n getParagraphNamedStyleType,\n isNamedStyleType,\n extractParagraphText,\n} from \"./utils\";\nimport { getSectionTitle } from \"./section\";\n\n/**\n * Represents a processed paragraph with extracted text and normalized style.\n */\nexport interface Paragraph {\n text: string;\n style: NamedStyleType | \"NORMAL_TEXT\" | undefined;\n paragraph: docs_v1.Schema$Paragraph;\n}\n\n/**\n * Extracts and normalizes data from a raw Google Docs paragraph.\n *\n * @param paragraph - The raw paragraph object from the API.\n * @returns A `Paragraph` object if text exists, otherwise `null` (e.g., empty lines).\n */\nexport function getParagraph(\n paragraph: docs_v1.Schema$Paragraph\n): Paragraph | null {\n const text = extractParagraphText(paragraph);\n if (!text) return null;\n const style = getParagraphNamedStyleType(paragraph);\n return { text, style, paragraph };\n}\n\n/**\n * A stateful cursor for traversing a list of Google Docs paragraphs.\n *\n * It manages the current position (index) and provides methods to inspect\n * the current paragraph's context (e.g., style, section boundaries)\n * without manually handling array indices.\n */\nexport class ParagraphCursor {\n private index = 0;\n\n constructor(\n private paragraphList: docs_v1.Schema$Paragraph[],\n private parseSchema: ParseSchema\n ) {}\n\n /**\n * Retrieves the paragraph at the current cursor position.\n *\n * @returns The current `Paragraph` object, or `null` if the cursor is at the end of the document or the line is empty.\n */\n getCurrentParagraph(): Paragraph | null {\n if (this.isEndOfDocument()) return null;\n const paragraph = this.paragraphList[this.index];\n if (!paragraph) return null;\n return getParagraph(paragraph);\n }\n\n /**\n * Advances the cursor to the next position and returns the new paragraph.\n *\n * @returns The next `Paragraph` object, or `null` if the end of the document is reached.\n */\n getNextParagraph(): Paragraph | null {\n if (this.isEndOfDocument()) return null;\n this.index++;\n return this.getCurrentParagraph();\n }\n\n /**\n * Checks if the cursor has reached the end of the paragraph list.\n */\n isEndOfDocument(): boolean {\n return this.index >= this.paragraphList.length;\n }\n\n /**\n * Determines if the current paragraph corresponds to a section title defined in the schema.\n *\n * @returns The section name if matched, otherwise `null`.\n */\n getCurrentSectionTitle(): string | null {\n const info = this.getCurrentParagraph();\n if (!info) return null;\n return getSectionTitle(info.paragraph, info.text, this.parseSchema);\n }\n\n /**\n * Checks if the current cursor position marks the start of a new section.\n */\n isAtNewSection(): boolean {\n return this.getCurrentSectionTitle() !== null;\n }\n\n /**\n * Checks if the current paragraph has a named heading style (e.g., HEADING_1).\n */\n isAtParagraphHeading(): boolean {\n const info = this.getCurrentParagraph();\n return !!info && isNamedStyleType(info.style);\n }\n}\n","import { google, docs_v1 } from \"googleapis\";\nimport { GoogleAuth } from \"google-auth-library\";\n\n/**\n * Creates and configures a Google Docs API client instance.\n *\n * This function handles authentication using `GoogleAuth` with the read-only scope\n * and initializes the `googleapis` Docs service with version 'v1'.\n *\n * @returns An initialized `docs_v1.Docs` client ready for API calls.\n * @throws {Error} If client initialization fails (e.g., missing credentials or configuration errors).\n */\nexport function createDocsClient(): docs_v1.Docs {\n try {\n const auth = new GoogleAuth({\n scopes: [\"https://www.googleapis.com/auth/documents.readonly\"],\n });\n\n return google.docs({\n version: \"v1\",\n auth,\n });\n } catch (error) {\n console.error(\"Error initializing Google Docs client:\", error);\n throw new Error(\n \"Failed to initialize Google Docs client. Check setup and credentials.\"\n );\n }\n}\n","import { docs_v1 } from \"googleapis\";\nimport { ParsedDocument, ParseSchema, GetParsedType } from \"./types\";\nimport { ParagraphCursor } from \"./cursor\";\nimport { parseSectionContent } from \"./section\";\nimport { createDocsClient } from \"./auth\";\n\n/**\n * Parses the raw Google Docs document content according to the provided schema.\n *\n * This function converts the document into a stream of valid paragraphs and\n * uses a cursor to navigate and parse sections based on the schema definition.\n *\n * @param doc - The raw Google Docs document object.\n * @param parseSchema - The schema defining the structure of sections to parse.\n * @returns An object representing the parsed document content.\n */\nfunction parseDocument(\n doc: docs_v1.Schema$Document,\n parseSchema: ParseSchema\n): ParsedDocument {\n const content = doc.body?.content || [];\n const result: ParsedDocument = {};\n\n const validParagraphList = content\n .map((element) => element.paragraph)\n .filter((paragraph): paragraph is docs_v1.Schema$Paragraph => !!paragraph);\n\n const cursor = new ParagraphCursor(validParagraphList, parseSchema);\n\n while (!cursor.isEndOfDocument()) {\n const currentSectionTitle = cursor.getCurrentSectionTitle();\n if (currentSectionTitle) {\n const section = parseSchema.sections.find(\n (s) => s.title.name === currentSectionTitle\n );\n if (section) {\n cursor.getNextParagraph();\n const parsedData = parseSectionContent(cursor, section);\n result[currentSectionTitle] = parsedData;\n continue;\n }\n }\n cursor.getNextParagraph();\n }\n\n return result;\n}\n\n/**\n * Public API: Fetches and parses a Google Doc by its ID.\n *\n * This function handles authentication, API communication, and error wrapping.\n * It returns a fully typed object based on the provided schema generic `T`.\n *\n * @template T - The type of the ParseSchema, allowing for type inference of the result.\n * @param documentId - The unique ID of the Google Doc to parse.\n * @param parseSchema - The schema definition used to guide the parsing process.\n * @returns A promise resolving to the parsed document data.\n * @throws Will throw a descriptive error if the API call fails or returns an empty response.\n */\nexport async function getParsedDocument<T extends ParseSchema>(\n documentId: string,\n parseSchema: T\n): Promise<GetParsedType<T>> {\n try {\n const docs = createDocsClient();\n const response = await docs.documents.get({ documentId });\n if (!response.data) {\n throw new Error(\"Empty document response from Google Docs API.\");\n }\n\n const parsedDocument = parseDocument(response.data, parseSchema);\n return parsedDocument as GetParsedType<T>;\n } catch (e) {\n throw new Error(\n `Google Docs API call failed. Check Doc ID and Service Account permissions. Original error: ${\n e instanceof Error ? e.message : String(e)\n }`\n );\n }\n}\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { docs_v1 } from 'googleapis';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Alias for the Google Docs API's named style type.
|
|
5
|
+
* Examples: "HEADING_1", "HEADING_2", "NORMAL_TEXT", "TITLE".
|
|
6
|
+
*/
|
|
7
|
+
type NamedStyleType = docs_v1.Schema$ParagraphStyle["namedStyleType"];
|
|
8
|
+
/**
|
|
9
|
+
* Base configuration interface for parsing text content.
|
|
10
|
+
* Defines how raw text strings are split, filtered, and mapped to data fields.
|
|
11
|
+
*/
|
|
12
|
+
interface Schema {
|
|
13
|
+
/**
|
|
14
|
+
* The delimiter used to split text into multiple values (e.g., "," or "|").
|
|
15
|
+
* @default ","
|
|
16
|
+
*/
|
|
17
|
+
delimiter?: string;
|
|
18
|
+
/**
|
|
19
|
+
* An array of keys used to map split values to specific field names.
|
|
20
|
+
* If provided, the text is parsed into an object (e.g., "A, B" -> { key1: "A", key2: "B" }).
|
|
21
|
+
*/
|
|
22
|
+
keys?: readonly string[];
|
|
23
|
+
/**
|
|
24
|
+
* The delimiter used to separate a key from its values (e.g., ":").
|
|
25
|
+
* Used for "Key: Value" parsing logic.
|
|
26
|
+
*/
|
|
27
|
+
keyDelimiter?: string;
|
|
28
|
+
/**
|
|
29
|
+
* If true, indicates that the result should be flattened in specific contexts.
|
|
30
|
+
*/
|
|
31
|
+
isFlatten?: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Configuration for a heading node (Title).
|
|
35
|
+
* Extends `Schema` to allow parsing structured data from the heading text itself.
|
|
36
|
+
*/
|
|
37
|
+
interface Title extends Schema {
|
|
38
|
+
/**
|
|
39
|
+
* The property name key for this section in the final output object.
|
|
40
|
+
* This matches the key in the `ParsedDocument`.
|
|
41
|
+
*/
|
|
42
|
+
name?: string;
|
|
43
|
+
/**
|
|
44
|
+
* The specific Google Docs style type that identifies this title (e.g., "HEADING_1").
|
|
45
|
+
*/
|
|
46
|
+
namedStyleType: NamedStyleType;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Configuration for parsing content as a flat list.
|
|
50
|
+
* Expects a sequence of items (usually bullet points or paragraphs) under a heading.
|
|
51
|
+
*/
|
|
52
|
+
interface List extends Schema {
|
|
53
|
+
kind: "list";
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Configuration for parsing content as a nested tree structure.
|
|
57
|
+
* Expects child nodes (sub-headings) under the current heading.
|
|
58
|
+
*/
|
|
59
|
+
interface Tree {
|
|
60
|
+
kind: "tree";
|
|
61
|
+
/**
|
|
62
|
+
* The definition of the child node structure.
|
|
63
|
+
*/
|
|
64
|
+
node: Node;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Union type representing the possible content structures:
|
|
68
|
+
* either a flat `List` or a hierarchical `Tree`.
|
|
69
|
+
*/
|
|
70
|
+
type Content = List | Tree;
|
|
71
|
+
/**
|
|
72
|
+
* Represents a single node in the document hierarchy.
|
|
73
|
+
* Consists of a title (the heading) and optional content (children or list).
|
|
74
|
+
*/
|
|
75
|
+
interface Node {
|
|
76
|
+
/** Configuration for the node's heading. */
|
|
77
|
+
title: Title;
|
|
78
|
+
/** Configuration for the node's body content (optional). */
|
|
79
|
+
content?: Content;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Represents a top-level section of the document.
|
|
83
|
+
* Similar to `Node` but used at the root level of the parsing schema.
|
|
84
|
+
*/
|
|
85
|
+
interface Section {
|
|
86
|
+
title: Title;
|
|
87
|
+
content?: Content;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* The root configuration object used to define the entire document parsing structure.
|
|
91
|
+
* Contains a list of top-level sections to parse.
|
|
92
|
+
*/
|
|
93
|
+
interface ParseSchema {
|
|
94
|
+
sections: readonly Section[];
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Helper Type: Infers the object shape for a single text item based on `keys`.
|
|
98
|
+
*
|
|
99
|
+
* - If `keys` are present (e.g., `["role", "name"]`), infers `{ role: unknown; name: unknown }`.
|
|
100
|
+
* - Otherwise, infers `unknown` (typically a string).
|
|
101
|
+
*/
|
|
102
|
+
type ItemField<T extends Schema> = T extends {
|
|
103
|
+
keys: readonly (infer K)[];
|
|
104
|
+
} ? {
|
|
105
|
+
[P in K & string]: unknown;
|
|
106
|
+
} : unknown;
|
|
107
|
+
/**
|
|
108
|
+
* Helper Type: Infers the result type for a `List` content.
|
|
109
|
+
*
|
|
110
|
+
* - If the schema has keys, returns an array of objects.
|
|
111
|
+
* - Otherwise, returns an array of raw values.
|
|
112
|
+
*/
|
|
113
|
+
type ContentListType<C extends List> = C extends {
|
|
114
|
+
keys: readonly any[];
|
|
115
|
+
} ? Array<ItemField<C>> : Array<unknown>;
|
|
116
|
+
/**
|
|
117
|
+
* Helper Type: Recursively infers the type of a Node's content.
|
|
118
|
+
*
|
|
119
|
+
* - If `kind: "tree"`, returns an array of `StructuredItem<N>` (recursive).
|
|
120
|
+
* - If `kind: "list"`, returns a list type via `ContentListType`.
|
|
121
|
+
*/
|
|
122
|
+
type NodeContentItems<C extends Content | undefined> = C extends {
|
|
123
|
+
kind: "tree";
|
|
124
|
+
node: infer N extends Node;
|
|
125
|
+
} ? Array<StructuredItem<N>> : C extends {
|
|
126
|
+
kind: "list";
|
|
127
|
+
} ? ContentListType<C> : unknown;
|
|
128
|
+
/**
|
|
129
|
+
* Helper Type: Represents the fully resolved type of a single Node.
|
|
130
|
+
*
|
|
131
|
+
* Merges:
|
|
132
|
+
* 1. The parsed fields from the Node's **Title** (if it has `keys`).
|
|
133
|
+
* 2. The parsed `content` property (children or list).
|
|
134
|
+
*/
|
|
135
|
+
type StructuredItem<N extends Node> = ItemField<N["title"]> & {
|
|
136
|
+
content: NodeContentItems<N["content"]>;
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* **Main Type Inference Utility**
|
|
140
|
+
*
|
|
141
|
+
* Converts a static `ParseSchema` configuration type into the actual runtime result type.
|
|
142
|
+
*
|
|
143
|
+
* - Iterates over all sections in `ParseSchema`.
|
|
144
|
+
* - Maps the section's `name` to its corresponding inferred content type.
|
|
145
|
+
* - Supports both Tree (recursive) and List structures.
|
|
146
|
+
*
|
|
147
|
+
* @template T - The ParseSchema type (must be defined `as const` to infer literal keys).
|
|
148
|
+
*/
|
|
149
|
+
type GetParsedType<T extends ParseSchema> = {
|
|
150
|
+
[S in T["sections"][number] as S["title"]["name"] & string]: S["content"] extends {
|
|
151
|
+
kind: "tree";
|
|
152
|
+
node: infer N extends Node;
|
|
153
|
+
} ? Array<StructuredItem<N>> : S["content"] extends {
|
|
154
|
+
kind: "list";
|
|
155
|
+
} ? ContentListType<S["content"]> : unknown;
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Public API: Fetches and parses a Google Doc by its ID.
|
|
160
|
+
*
|
|
161
|
+
* This function handles authentication, API communication, and error wrapping.
|
|
162
|
+
* It returns a fully typed object based on the provided schema generic `T`.
|
|
163
|
+
*
|
|
164
|
+
* @template T - The type of the ParseSchema, allowing for type inference of the result.
|
|
165
|
+
* @param documentId - The unique ID of the Google Doc to parse.
|
|
166
|
+
* @param parseSchema - The schema definition used to guide the parsing process.
|
|
167
|
+
* @returns A promise resolving to the parsed document data.
|
|
168
|
+
* @throws Will throw a descriptive error if the API call fails or returns an empty response.
|
|
169
|
+
*/
|
|
170
|
+
declare function getParsedDocument<T extends ParseSchema>(documentId: string, parseSchema: T): Promise<GetParsedType<T>>;
|
|
171
|
+
|
|
172
|
+
export { type GetParsedType, type ParseSchema, getParsedDocument };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { docs_v1 } from 'googleapis';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Alias for the Google Docs API's named style type.
|
|
5
|
+
* Examples: "HEADING_1", "HEADING_2", "NORMAL_TEXT", "TITLE".
|
|
6
|
+
*/
|
|
7
|
+
type NamedStyleType = docs_v1.Schema$ParagraphStyle["namedStyleType"];
|
|
8
|
+
/**
|
|
9
|
+
* Base configuration interface for parsing text content.
|
|
10
|
+
* Defines how raw text strings are split, filtered, and mapped to data fields.
|
|
11
|
+
*/
|
|
12
|
+
interface Schema {
|
|
13
|
+
/**
|
|
14
|
+
* The delimiter used to split text into multiple values (e.g., "," or "|").
|
|
15
|
+
* @default ","
|
|
16
|
+
*/
|
|
17
|
+
delimiter?: string;
|
|
18
|
+
/**
|
|
19
|
+
* An array of keys used to map split values to specific field names.
|
|
20
|
+
* If provided, the text is parsed into an object (e.g., "A, B" -> { key1: "A", key2: "B" }).
|
|
21
|
+
*/
|
|
22
|
+
keys?: readonly string[];
|
|
23
|
+
/**
|
|
24
|
+
* The delimiter used to separate a key from its values (e.g., ":").
|
|
25
|
+
* Used for "Key: Value" parsing logic.
|
|
26
|
+
*/
|
|
27
|
+
keyDelimiter?: string;
|
|
28
|
+
/**
|
|
29
|
+
* If true, indicates that the result should be flattened in specific contexts.
|
|
30
|
+
*/
|
|
31
|
+
isFlatten?: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Configuration for a heading node (Title).
|
|
35
|
+
* Extends `Schema` to allow parsing structured data from the heading text itself.
|
|
36
|
+
*/
|
|
37
|
+
interface Title extends Schema {
|
|
38
|
+
/**
|
|
39
|
+
* The property name key for this section in the final output object.
|
|
40
|
+
* This matches the key in the `ParsedDocument`.
|
|
41
|
+
*/
|
|
42
|
+
name?: string;
|
|
43
|
+
/**
|
|
44
|
+
* The specific Google Docs style type that identifies this title (e.g., "HEADING_1").
|
|
45
|
+
*/
|
|
46
|
+
namedStyleType: NamedStyleType;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Configuration for parsing content as a flat list.
|
|
50
|
+
* Expects a sequence of items (usually bullet points or paragraphs) under a heading.
|
|
51
|
+
*/
|
|
52
|
+
interface List extends Schema {
|
|
53
|
+
kind: "list";
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Configuration for parsing content as a nested tree structure.
|
|
57
|
+
* Expects child nodes (sub-headings) under the current heading.
|
|
58
|
+
*/
|
|
59
|
+
interface Tree {
|
|
60
|
+
kind: "tree";
|
|
61
|
+
/**
|
|
62
|
+
* The definition of the child node structure.
|
|
63
|
+
*/
|
|
64
|
+
node: Node;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Union type representing the possible content structures:
|
|
68
|
+
* either a flat `List` or a hierarchical `Tree`.
|
|
69
|
+
*/
|
|
70
|
+
type Content = List | Tree;
|
|
71
|
+
/**
|
|
72
|
+
* Represents a single node in the document hierarchy.
|
|
73
|
+
* Consists of a title (the heading) and optional content (children or list).
|
|
74
|
+
*/
|
|
75
|
+
interface Node {
|
|
76
|
+
/** Configuration for the node's heading. */
|
|
77
|
+
title: Title;
|
|
78
|
+
/** Configuration for the node's body content (optional). */
|
|
79
|
+
content?: Content;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Represents a top-level section of the document.
|
|
83
|
+
* Similar to `Node` but used at the root level of the parsing schema.
|
|
84
|
+
*/
|
|
85
|
+
interface Section {
|
|
86
|
+
title: Title;
|
|
87
|
+
content?: Content;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* The root configuration object used to define the entire document parsing structure.
|
|
91
|
+
* Contains a list of top-level sections to parse.
|
|
92
|
+
*/
|
|
93
|
+
interface ParseSchema {
|
|
94
|
+
sections: readonly Section[];
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Helper Type: Infers the object shape for a single text item based on `keys`.
|
|
98
|
+
*
|
|
99
|
+
* - If `keys` are present (e.g., `["role", "name"]`), infers `{ role: unknown; name: unknown }`.
|
|
100
|
+
* - Otherwise, infers `unknown` (typically a string).
|
|
101
|
+
*/
|
|
102
|
+
type ItemField<T extends Schema> = T extends {
|
|
103
|
+
keys: readonly (infer K)[];
|
|
104
|
+
} ? {
|
|
105
|
+
[P in K & string]: unknown;
|
|
106
|
+
} : unknown;
|
|
107
|
+
/**
|
|
108
|
+
* Helper Type: Infers the result type for a `List` content.
|
|
109
|
+
*
|
|
110
|
+
* - If the schema has keys, returns an array of objects.
|
|
111
|
+
* - Otherwise, returns an array of raw values.
|
|
112
|
+
*/
|
|
113
|
+
type ContentListType<C extends List> = C extends {
|
|
114
|
+
keys: readonly any[];
|
|
115
|
+
} ? Array<ItemField<C>> : Array<unknown>;
|
|
116
|
+
/**
|
|
117
|
+
* Helper Type: Recursively infers the type of a Node's content.
|
|
118
|
+
*
|
|
119
|
+
* - If `kind: "tree"`, returns an array of `StructuredItem<N>` (recursive).
|
|
120
|
+
* - If `kind: "list"`, returns a list type via `ContentListType`.
|
|
121
|
+
*/
|
|
122
|
+
type NodeContentItems<C extends Content | undefined> = C extends {
|
|
123
|
+
kind: "tree";
|
|
124
|
+
node: infer N extends Node;
|
|
125
|
+
} ? Array<StructuredItem<N>> : C extends {
|
|
126
|
+
kind: "list";
|
|
127
|
+
} ? ContentListType<C> : unknown;
|
|
128
|
+
/**
|
|
129
|
+
* Helper Type: Represents the fully resolved type of a single Node.
|
|
130
|
+
*
|
|
131
|
+
* Merges:
|
|
132
|
+
* 1. The parsed fields from the Node's **Title** (if it has `keys`).
|
|
133
|
+
* 2. The parsed `content` property (children or list).
|
|
134
|
+
*/
|
|
135
|
+
type StructuredItem<N extends Node> = ItemField<N["title"]> & {
|
|
136
|
+
content: NodeContentItems<N["content"]>;
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* **Main Type Inference Utility**
|
|
140
|
+
*
|
|
141
|
+
* Converts a static `ParseSchema` configuration type into the actual runtime result type.
|
|
142
|
+
*
|
|
143
|
+
* - Iterates over all sections in `ParseSchema`.
|
|
144
|
+
* - Maps the section's `name` to its corresponding inferred content type.
|
|
145
|
+
* - Supports both Tree (recursive) and List structures.
|
|
146
|
+
*
|
|
147
|
+
* @template T - The ParseSchema type (must be defined `as const` to infer literal keys).
|
|
148
|
+
*/
|
|
149
|
+
type GetParsedType<T extends ParseSchema> = {
|
|
150
|
+
[S in T["sections"][number] as S["title"]["name"] & string]: S["content"] extends {
|
|
151
|
+
kind: "tree";
|
|
152
|
+
node: infer N extends Node;
|
|
153
|
+
} ? Array<StructuredItem<N>> : S["content"] extends {
|
|
154
|
+
kind: "list";
|
|
155
|
+
} ? ContentListType<S["content"]> : unknown;
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Public API: Fetches and parses a Google Doc by its ID.
|
|
160
|
+
*
|
|
161
|
+
* This function handles authentication, API communication, and error wrapping.
|
|
162
|
+
* It returns a fully typed object based on the provided schema generic `T`.
|
|
163
|
+
*
|
|
164
|
+
* @template T - The type of the ParseSchema, allowing for type inference of the result.
|
|
165
|
+
* @param documentId - The unique ID of the Google Doc to parse.
|
|
166
|
+
* @param parseSchema - The schema definition used to guide the parsing process.
|
|
167
|
+
* @returns A promise resolving to the parsed document data.
|
|
168
|
+
* @throws Will throw a descriptive error if the API call fails or returns an empty response.
|
|
169
|
+
*/
|
|
170
|
+
declare function getParsedDocument<T extends ParseSchema>(documentId: string, parseSchema: T): Promise<GetParsedType<T>>;
|
|
171
|
+
|
|
172
|
+
export { type GetParsedType, type ParseSchema, getParsedDocument };
|