@cesarandreslopez/occ 0.3.1 → 0.4.1

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.
Files changed (150) hide show
  1. package/README.md +130 -4
  2. package/dist/src/cli-validation.d.ts +14 -0
  3. package/dist/src/cli-validation.js +58 -0
  4. package/dist/src/cli-validation.js.map +1 -0
  5. package/dist/src/cli.js +26 -8
  6. package/dist/src/cli.js.map +1 -1
  7. package/dist/src/code/build.d.ts +7 -5
  8. package/dist/src/code/build.js +68 -11
  9. package/dist/src/code/build.js.map +1 -1
  10. package/dist/src/code/command.js +26 -19
  11. package/dist/src/code/command.js.map +1 -1
  12. package/dist/src/code/discover.d.ts +6 -4
  13. package/dist/src/code/discover.js +5 -0
  14. package/dist/src/code/discover.js.map +1 -1
  15. package/dist/src/code/languages.d.ts +28 -7
  16. package/dist/src/code/languages.js +9 -0
  17. package/dist/src/code/languages.js.map +1 -1
  18. package/dist/src/code/output.js +12 -3
  19. package/dist/src/code/output.js.map +1 -1
  20. package/dist/src/code/parsers.js +75 -10
  21. package/dist/src/code/parsers.js.map +1 -1
  22. package/dist/src/code/query.js +82 -22
  23. package/dist/src/code/query.js.map +1 -1
  24. package/dist/src/code/types.d.ts +1201 -145
  25. package/dist/src/code/types.js +150 -1
  26. package/dist/src/code/types.js.map +1 -1
  27. package/dist/src/doc/command.d.ts +2 -0
  28. package/dist/src/doc/command.js +54 -0
  29. package/dist/src/doc/command.js.map +1 -0
  30. package/dist/src/doc/inspect-docx.d.ts +14 -0
  31. package/dist/src/doc/inspect-docx.js +188 -0
  32. package/dist/src/doc/inspect-docx.js.map +1 -0
  33. package/dist/src/doc/inspect-odt.d.ts +8 -0
  34. package/dist/src/doc/inspect-odt.js +92 -0
  35. package/dist/src/doc/inspect-odt.js.map +1 -0
  36. package/dist/src/doc/inspect-pdf.d.ts +8 -0
  37. package/dist/src/doc/inspect-pdf.js +88 -0
  38. package/dist/src/doc/inspect-pdf.js.map +1 -0
  39. package/dist/src/doc/inspect.d.ts +2 -0
  40. package/dist/src/doc/inspect.js +70 -0
  41. package/dist/src/doc/inspect.js.map +1 -0
  42. package/dist/src/doc/output.d.ts +3 -0
  43. package/dist/src/doc/output.js +82 -0
  44. package/dist/src/doc/output.js.map +1 -0
  45. package/dist/src/doc/types.d.ts +172 -0
  46. package/dist/src/doc/types.js +62 -0
  47. package/dist/src/doc/types.js.map +1 -0
  48. package/dist/src/inspect/shared.d.ts +20 -0
  49. package/dist/src/inspect/shared.js +29 -0
  50. package/dist/src/inspect/shared.js.map +1 -0
  51. package/dist/src/inspect/xlsx-cells.d.ts +4 -0
  52. package/dist/src/inspect/xlsx-cells.js +31 -0
  53. package/dist/src/inspect/xlsx-cells.js.map +1 -0
  54. package/dist/src/markdown/convert.js +6 -4
  55. package/dist/src/markdown/convert.js.map +1 -1
  56. package/dist/src/output/tabular.d.ts +6 -4
  57. package/dist/src/output/tabular.js +5 -0
  58. package/dist/src/output/tabular.js.map +1 -1
  59. package/dist/src/output/tree.d.ts +21 -9
  60. package/dist/src/output/tree.js +10 -0
  61. package/dist/src/output/tree.js.map +1 -1
  62. package/dist/src/parsers/docx.js +5 -1
  63. package/dist/src/parsers/docx.js.map +1 -1
  64. package/dist/src/parsers/odf.js +4 -3
  65. package/dist/src/parsers/odf.js.map +1 -1
  66. package/dist/src/parsers/pdf.js +6 -1
  67. package/dist/src/parsers/pdf.js.map +1 -1
  68. package/dist/src/parsers/pptx.js +2 -1
  69. package/dist/src/parsers/pptx.js.map +1 -1
  70. package/dist/src/parsers/xlsx.js +11 -4
  71. package/dist/src/parsers/xlsx.js.map +1 -1
  72. package/dist/src/progress.d.ts +7 -5
  73. package/dist/src/progress.js +6 -0
  74. package/dist/src/progress.js.map +1 -1
  75. package/dist/src/scc.d.ts +35 -26
  76. package/dist/src/scc.js +26 -1
  77. package/dist/src/scc.js.map +1 -1
  78. package/dist/src/sheet/command.d.ts +2 -0
  79. package/dist/src/sheet/command.js +61 -0
  80. package/dist/src/sheet/command.js.map +1 -0
  81. package/dist/src/sheet/inspect.d.ts +3 -0
  82. package/dist/src/sheet/inspect.js +426 -0
  83. package/dist/src/sheet/inspect.js.map +1 -0
  84. package/dist/src/sheet/output.d.ts +3 -0
  85. package/dist/src/sheet/output.js +158 -0
  86. package/dist/src/sheet/output.js.map +1 -0
  87. package/dist/src/sheet/types.d.ts +472 -0
  88. package/dist/src/sheet/types.js +119 -0
  89. package/dist/src/sheet/types.js.map +1 -0
  90. package/dist/src/slide/command.d.ts +2 -0
  91. package/dist/src/slide/command.js +54 -0
  92. package/dist/src/slide/command.js.map +1 -0
  93. package/dist/src/slide/inspect-odp.d.ts +7 -0
  94. package/dist/src/slide/inspect-odp.js +105 -0
  95. package/dist/src/slide/inspect-odp.js.map +1 -0
  96. package/dist/src/slide/inspect-pptx.d.ts +11 -0
  97. package/dist/src/slide/inspect-pptx.js +157 -0
  98. package/dist/src/slide/inspect-pptx.js.map +1 -0
  99. package/dist/src/slide/inspect.d.ts +2 -0
  100. package/dist/src/slide/inspect.js +76 -0
  101. package/dist/src/slide/inspect.js.map +1 -0
  102. package/dist/src/slide/output.d.ts +3 -0
  103. package/dist/src/slide/output.js +92 -0
  104. package/dist/src/slide/output.js.map +1 -0
  105. package/dist/src/slide/types.d.ts +167 -0
  106. package/dist/src/slide/types.js +61 -0
  107. package/dist/src/slide/types.js.map +1 -0
  108. package/dist/src/stats.d.ts +6 -4
  109. package/dist/src/stats.js +5 -0
  110. package/dist/src/stats.js.map +1 -1
  111. package/dist/src/structure/types.d.ts +19 -11
  112. package/dist/src/structure/types.js +26 -21
  113. package/dist/src/structure/types.js.map +1 -1
  114. package/dist/src/table/command.d.ts +2 -0
  115. package/dist/src/table/command.js +58 -0
  116. package/dist/src/table/command.js.map +1 -0
  117. package/dist/src/table/inspect-docx.d.ts +2 -0
  118. package/dist/src/table/inspect-docx.js +108 -0
  119. package/dist/src/table/inspect-docx.js.map +1 -0
  120. package/dist/src/table/inspect-odp.d.ts +2 -0
  121. package/dist/src/table/inspect-odp.js +106 -0
  122. package/dist/src/table/inspect-odp.js.map +1 -0
  123. package/dist/src/table/inspect-odt.d.ts +2 -0
  124. package/dist/src/table/inspect-odt.js +100 -0
  125. package/dist/src/table/inspect-odt.js.map +1 -0
  126. package/dist/src/table/inspect-pptx.d.ts +2 -0
  127. package/dist/src/table/inspect-pptx.js +112 -0
  128. package/dist/src/table/inspect-pptx.js.map +1 -0
  129. package/dist/src/table/inspect-xlsx.d.ts +2 -0
  130. package/dist/src/table/inspect-xlsx.js +161 -0
  131. package/dist/src/table/inspect-xlsx.js.map +1 -0
  132. package/dist/src/table/inspect.d.ts +2 -0
  133. package/dist/src/table/inspect.js +65 -0
  134. package/dist/src/table/inspect.js.map +1 -0
  135. package/dist/src/table/output.d.ts +3 -0
  136. package/dist/src/table/output.js +93 -0
  137. package/dist/src/table/output.js.map +1 -0
  138. package/dist/src/table/types.d.ts +104 -0
  139. package/dist/src/table/types.js +40 -0
  140. package/dist/src/table/types.js.map +1 -0
  141. package/dist/src/types.d.ts +25 -20
  142. package/dist/src/types.js +21 -1
  143. package/dist/src/types.js.map +1 -1
  144. package/dist/src/utils.d.ts +11 -1
  145. package/dist/src/utils.js +2 -0
  146. package/dist/src/utils.js.map +1 -1
  147. package/dist/src/walker.d.ts +21 -12
  148. package/dist/src/walker.js +13 -0
  149. package/dist/src/walker.js.map +1 -1
  150. package/package.json +3 -2
@@ -0,0 +1,105 @@
1
+ import JSZip from 'jszip';
2
+ import { countWords } from '../utils.js';
3
+ import { asOptionalString, formatDateLike } from '../inspect/shared.js';
4
+ function parseXmlText(xml, tag) {
5
+ const regex = new RegExp(`<${tag}[^>]*>([^<]*)</${tag}>`, 'i');
6
+ const match = xml.match(regex);
7
+ return match?.[1]?.trim() || undefined;
8
+ }
9
+ function extractTextFromElement(xml) {
10
+ const matches = xml.match(/<text:(?:p|span)[^>]*>([^<]*)<\/text:(?:p|span)>/g) || [];
11
+ const texts = [];
12
+ for (const m of matches) {
13
+ const text = m.replace(/<[^>]+>/g, '').trim();
14
+ if (text)
15
+ texts.push(text);
16
+ }
17
+ return texts.join(' ');
18
+ }
19
+ export async function inspectOdp(buffer) {
20
+ const zip = await JSZip.loadAsync(buffer);
21
+ // Parse metadata
22
+ const properties = {};
23
+ const metaXml = await zip.file('meta.xml')?.async('text');
24
+ if (metaXml) {
25
+ properties.title = asOptionalString(parseXmlText(metaXml, 'dc:title'));
26
+ properties.subject = asOptionalString(parseXmlText(metaXml, 'dc:subject'));
27
+ properties.author = asOptionalString(parseXmlText(metaXml, 'dc:creator') ?? parseXmlText(metaXml, 'meta:initial-creator'));
28
+ properties.keywords = asOptionalString(parseXmlText(metaXml, 'meta:keyword'));
29
+ properties.createdDate = formatDateLike(parseXmlText(metaXml, 'meta:creation-date'));
30
+ properties.modifiedDate = formatDateLike(parseXmlText(metaXml, 'dc:date'));
31
+ }
32
+ // Parse content.xml for slides
33
+ const contentXml = await zip.file('content.xml')?.async('text');
34
+ const slideProfiles = [];
35
+ const riskFlags = {
36
+ comments: false,
37
+ speakerNotes: false,
38
+ hyperlinks: false,
39
+ embeddedMedia: false,
40
+ animations: false,
41
+ macros: false,
42
+ charts: false,
43
+ tables: false,
44
+ };
45
+ if (contentXml) {
46
+ // Split by draw:page elements
47
+ const slideMatches = contentXml.match(/<draw:page\b[^>]*>[\s\S]*?<\/draw:page>/g) || [];
48
+ for (let i = 0; i < slideMatches.length; i++) {
49
+ const slideXml = slideMatches[i];
50
+ // Get title from draw:name attribute or first text frame
51
+ let title = null;
52
+ const nameMatch = slideXml.match(/draw:name="([^"]*)"/);
53
+ if (nameMatch && nameMatch[1]) {
54
+ title = nameMatch[1];
55
+ }
56
+ // Extract text
57
+ const text = extractTextFromElement(slideXml);
58
+ const words = countWords(text);
59
+ // Count tables and images
60
+ const tables = (slideXml.match(/<table:table\b/g) || []).length;
61
+ const images = (slideXml.match(/<draw:image\b/g) || []).length;
62
+ // Check for notes
63
+ let hasNotes = false;
64
+ let notePreview = null;
65
+ const notesMatch = slideXml.match(/<presentation:notes\b[^>]*>([\s\S]*?)<\/presentation:notes>/);
66
+ if (notesMatch) {
67
+ const notesText = extractTextFromElement(notesMatch[1]);
68
+ if (notesText.trim()) {
69
+ hasNotes = true;
70
+ notePreview = notesText.length > 200 ? notesText.slice(0, 200) + '...' : notesText;
71
+ }
72
+ }
73
+ slideProfiles.push({
74
+ index: i + 1,
75
+ title,
76
+ words,
77
+ hasNotes,
78
+ notePreview,
79
+ images,
80
+ tables,
81
+ charts: 0,
82
+ });
83
+ }
84
+ // Risk flags
85
+ if (/<office:annotation\b/.test(contentXml))
86
+ riskFlags.comments = true;
87
+ if (slideProfiles.some(p => p.hasNotes))
88
+ riskFlags.speakerNotes = true;
89
+ if (/<text:a\b[^>]*xlink:href=/.test(contentXml))
90
+ riskFlags.hyperlinks = true;
91
+ if (/<draw:image\b/.test(contentXml))
92
+ riskFlags.embeddedMedia = true;
93
+ if (/<presentation:transition\b/.test(contentXml) || /<anim:/.test(contentXml))
94
+ riskFlags.animations = true;
95
+ if (/<table:table\b/.test(contentXml))
96
+ riskFlags.tables = true;
97
+ if (/<draw:object\b/.test(contentXml))
98
+ riskFlags.charts = true;
99
+ }
100
+ // Check for macros
101
+ if (zip.file('Basic/') || zip.file('Scripts/'))
102
+ riskFlags.macros = true;
103
+ return { properties, riskFlags, slideProfiles };
104
+ }
105
+ //# sourceMappingURL=inspect-odp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect-odp.js","sourceRoot":"","sources":["../../../src/slide/inspect-odp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAIxE,SAAS,YAAY,CAAC,GAAW,EAAE,GAAW;IAC5C,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,IAAI,GAAG,kBAAkB,GAAG,GAAG,EAAE,GAAG,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC/B,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;AACzC,CAAC;AAED,SAAS,sBAAsB,CAAC,GAAW;IACzC,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,mDAAmD,CAAC,IAAI,EAAE,CAAC;IACrF,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9C,IAAI,IAAI;YAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,MAAc;IAMd,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAE1C,iBAAiB;IACjB,MAAM,UAAU,GAAuB,EAAE,CAAC;IAC1C,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC1D,IAAI,OAAO,EAAE,CAAC;QACZ,UAAU,CAAC,KAAK,GAAG,gBAAgB,CAAC,YAAY,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC;QACvE,UAAU,CAAC,OAAO,GAAG,gBAAgB,CAAC,YAAY,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;QAC3E,UAAU,CAAC,MAAM,GAAG,gBAAgB,CAAC,YAAY,CAAC,OAAO,EAAE,YAAY,CAAC,IAAI,YAAY,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC,CAAC;QAC3H,UAAU,CAAC,QAAQ,GAAG,gBAAgB,CAAC,YAAY,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC;QAC9E,UAAU,CAAC,WAAW,GAAG,cAAc,CAAC,YAAY,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC;QACrF,UAAU,CAAC,YAAY,GAAG,cAAc,CAAC,YAAY,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;IAC7E,CAAC;IAED,+BAA+B;IAC/B,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAChE,MAAM,aAAa,GAAmB,EAAE,CAAC;IAEzC,MAAM,SAAS,GAAmB;QAChC,QAAQ,EAAE,KAAK;QACf,YAAY,EAAE,KAAK;QACnB,UAAU,EAAE,KAAK;QACjB,aAAa,EAAE,KAAK;QACpB,UAAU,EAAE,KAAK;QACjB,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,KAAK;KACd,CAAC;IAEF,IAAI,UAAU,EAAE,CAAC;QACf,8BAA8B;QAC9B,MAAM,YAAY,GAAG,UAAU,CAAC,KAAK,CAAC,0CAA0C,CAAC,IAAI,EAAE,CAAC;QAExF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7C,MAAM,QAAQ,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;YAEjC,yDAAyD;YACzD,IAAI,KAAK,GAAkB,IAAI,CAAC;YAChC,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;YACxD,IAAI,SAAS,IAAI,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC9B,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YACvB,CAAC;YAED,eAAe;YACf,MAAM,IAAI,GAAG,sBAAsB,CAAC,QAAQ,CAAC,CAAC;YAC9C,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;YAE/B,0BAA0B;YAC1B,MAAM,MAAM,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;YAChE,MAAM,MAAM,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;YAE/D,kBAAkB;YAClB,IAAI,QAAQ,GAAG,KAAK,CAAC;YACrB,IAAI,WAAW,GAAkB,IAAI,CAAC;YACtC,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAC;YACjG,IAAI,UAAU,EAAE,CAAC;gBACf,MAAM,SAAS,GAAG,sBAAsB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;gBACxD,IAAI,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC;oBACrB,QAAQ,GAAG,IAAI,CAAC;oBAChB,WAAW,GAAG,SAAS,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;gBACrF,CAAC;YACH,CAAC;YAED,aAAa,CAAC,IAAI,CAAC;gBACjB,KAAK,EAAE,CAAC,GAAG,CAAC;gBACZ,KAAK;gBACL,KAAK;gBACL,QAAQ;gBACR,WAAW;gBACX,MAAM;gBACN,MAAM;gBACN,MAAM,EAAE,CAAC;aACV,CAAC,CAAC;QACL,CAAC;QAED,aAAa;QACb,IAAI,sBAAsB,CAAC,IAAI,CAAC,UAAU,CAAC;YAAE,SAAS,CAAC,QAAQ,GAAG,IAAI,CAAC;QACvE,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;YAAE,SAAS,CAAC,YAAY,GAAG,IAAI,CAAC;QACvE,IAAI,2BAA2B,CAAC,IAAI,CAAC,UAAU,CAAC;YAAE,SAAS,CAAC,UAAU,GAAG,IAAI,CAAC;QAC9E,IAAI,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC;YAAE,SAAS,CAAC,aAAa,GAAG,IAAI,CAAC;QACrE,IAAI,4BAA4B,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC;YAAE,SAAS,CAAC,UAAU,GAAG,IAAI,CAAC;QAC5G,IAAI,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC;YAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC;QAC/D,IAAI,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC;YAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC;IACjE,CAAC;IAED,mBAAmB;IACnB,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC;QAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC;IAExE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC;AAClD,CAAC"}
@@ -0,0 +1,11 @@
1
+ import JSZip from 'jszip';
2
+ import type { DocumentProperties } from '../inspect/shared.js';
3
+ import type { SlideRiskFlags, SlideProfile } from './types.js';
4
+ export declare function extractPptxProperties(zip: JSZip): Promise<DocumentProperties>;
5
+ export declare function extractPptxRiskFlags(zip: JSZip, slideProfiles: SlideProfile[]): Promise<SlideRiskFlags>;
6
+ export declare function extractPptxSlideProfiles(zip: JSZip): Promise<SlideProfile[]>;
7
+ export declare function inspectPptx(buffer: Buffer): Promise<{
8
+ properties: DocumentProperties;
9
+ riskFlags: SlideRiskFlags;
10
+ slideProfiles: SlideProfile[];
11
+ }>;
@@ -0,0 +1,157 @@
1
+ import JSZip from 'jszip';
2
+ import { countWords } from '../utils.js';
3
+ import { asOptionalString, formatDateLike } from '../inspect/shared.js';
4
+ function parseXmlText(xml, tag) {
5
+ const regex = new RegExp(`<${tag}[^>]*>([^<]*)</${tag}>`, 'i');
6
+ const match = xml.match(regex);
7
+ return match?.[1]?.trim() || undefined;
8
+ }
9
+ function extractAllText(xml) {
10
+ const matches = xml.match(/<a:t>([^<]*)<\/a:t>/g) || [];
11
+ return matches.map(m => {
12
+ const text = m.match(/<a:t>([^<]*)<\/a:t>/);
13
+ return text?.[1] || '';
14
+ }).join(' ').trim();
15
+ }
16
+ export async function extractPptxProperties(zip) {
17
+ const props = {};
18
+ const coreXml = await zip.file('docProps/core.xml')?.async('text');
19
+ if (coreXml) {
20
+ props.title = asOptionalString(parseXmlText(coreXml, 'dc:title'));
21
+ props.subject = asOptionalString(parseXmlText(coreXml, 'dc:subject'));
22
+ props.author = asOptionalString(parseXmlText(coreXml, 'dc:creator'));
23
+ props.keywords = asOptionalString(parseXmlText(coreXml, 'cp:keywords'));
24
+ props.lastModifiedBy = asOptionalString(parseXmlText(coreXml, 'cp:lastModifiedBy'));
25
+ props.createdDate = formatDateLike(parseXmlText(coreXml, 'dcterms:created'));
26
+ props.modifiedDate = formatDateLike(parseXmlText(coreXml, 'dcterms:modified'));
27
+ }
28
+ const appXml = await zip.file('docProps/app.xml')?.async('text');
29
+ if (appXml) {
30
+ props.company = asOptionalString(parseXmlText(appXml, 'Company'));
31
+ }
32
+ return props;
33
+ }
34
+ export async function extractPptxRiskFlags(zip, slideProfiles) {
35
+ const flags = {
36
+ comments: false,
37
+ speakerNotes: false,
38
+ hyperlinks: false,
39
+ embeddedMedia: false,
40
+ animations: false,
41
+ macros: false,
42
+ charts: false,
43
+ tables: false,
44
+ };
45
+ // Check for comments folder
46
+ const commentFiles = Object.keys(zip.files).filter(name => /^ppt\/comments\//.test(name));
47
+ if (commentFiles.length > 0)
48
+ flags.comments = true;
49
+ // Check for speaker notes
50
+ if (slideProfiles.some(p => p.hasNotes))
51
+ flags.speakerNotes = true;
52
+ // Check for media files
53
+ const mediaFiles = Object.keys(zip.files).filter(name => /^ppt\/media\//.test(name));
54
+ if (mediaFiles.length > 0)
55
+ flags.embeddedMedia = true;
56
+ // Check for macros
57
+ if (zip.file('ppt/vbaProject.bin'))
58
+ flags.macros = true;
59
+ // Check for charts
60
+ const chartFiles = Object.keys(zip.files).filter(name => /^ppt\/charts\//.test(name));
61
+ if (chartFiles.length > 0)
62
+ flags.charts = true;
63
+ // Aggregate from profiles
64
+ if (slideProfiles.some(p => p.tables > 0))
65
+ flags.tables = true;
66
+ // Check slides for animations and hyperlinks
67
+ const slideFiles = Object.keys(zip.files)
68
+ .filter(name => /^ppt\/slides\/slide\d+\.xml$/.test(name))
69
+ .sort((a, b) => {
70
+ const numA = parseInt(a.match(/slide(\d+)/)?.[1] || '0', 10);
71
+ const numB = parseInt(b.match(/slide(\d+)/)?.[1] || '0', 10);
72
+ return numA - numB;
73
+ });
74
+ for (const slideFile of slideFiles) {
75
+ const xml = await zip.file(slideFile)?.async('text');
76
+ if (!xml)
77
+ continue;
78
+ if (/<p:transition\b/.test(xml) || /<p:anim\b/.test(xml) || /<p:animMotion\b/.test(xml)) {
79
+ flags.animations = true;
80
+ }
81
+ if (/<a:hlinkClick\b/.test(xml) || /<a:hlinkMouseOver\b/.test(xml)) {
82
+ flags.hyperlinks = true;
83
+ }
84
+ if (flags.animations && flags.hyperlinks)
85
+ break;
86
+ }
87
+ return flags;
88
+ }
89
+ export async function extractPptxSlideProfiles(zip) {
90
+ const slideFiles = Object.keys(zip.files)
91
+ .filter(name => /^ppt\/slides\/slide\d+\.xml$/.test(name))
92
+ .sort((a, b) => {
93
+ const numA = parseInt(a.match(/slide(\d+)/)?.[1] || '0', 10);
94
+ const numB = parseInt(b.match(/slide(\d+)/)?.[1] || '0', 10);
95
+ return numA - numB;
96
+ });
97
+ const profiles = [];
98
+ for (let i = 0; i < slideFiles.length; i++) {
99
+ const slideXml = await zip.file(slideFiles[i])?.async('text');
100
+ if (!slideXml)
101
+ continue;
102
+ // Extract title
103
+ let title = null;
104
+ // Look for title placeholder
105
+ const titleMatch = slideXml.match(/<p:sp>[\s\S]*?<p:ph[^>]*type="(?:title|ctrTitle)"[^>]*\/>[\s\S]*?<\/p:sp>/i);
106
+ if (titleMatch) {
107
+ const titleText = extractAllText(titleMatch[0]);
108
+ if (titleText)
109
+ title = titleText;
110
+ }
111
+ // Extract all text for word count
112
+ const allText = extractAllText(slideXml);
113
+ const words = countWords(allText);
114
+ // Count tables
115
+ const tables = (slideXml.match(/<a:tbl\b/g) || []).length;
116
+ // Count images
117
+ const images = (slideXml.match(/<p:pic\b/g) || []).length + (slideXml.match(/<a:blip\b/g) || []).length;
118
+ // Count charts (from relationships)
119
+ const slideNum = parseInt(slideFiles[i].match(/slide(\d+)/)?.[1] || '0', 10);
120
+ const relsFile = `ppt/slides/_rels/slide${slideNum}.xml.rels`;
121
+ const relsXml = await zip.file(relsFile)?.async('text');
122
+ const charts = relsXml ? (relsXml.match(/chart/gi) || []).length : 0;
123
+ // Check for speaker notes
124
+ const notesFile = `ppt/notesSlides/notesSlide${slideNum}.xml`;
125
+ const notesXml = await zip.file(notesFile)?.async('text');
126
+ let hasNotes = false;
127
+ let notePreview = null;
128
+ if (notesXml) {
129
+ const notesText = extractAllText(notesXml);
130
+ // Filter out slide number placeholder text
131
+ const cleanNotes = notesText.replace(/\d+/g, '').trim();
132
+ if (cleanNotes.length > 0) {
133
+ hasNotes = true;
134
+ notePreview = notesText.length > 200 ? notesText.slice(0, 200) + '...' : notesText;
135
+ }
136
+ }
137
+ profiles.push({
138
+ index: i + 1,
139
+ title,
140
+ words,
141
+ hasNotes,
142
+ notePreview,
143
+ images,
144
+ tables,
145
+ charts,
146
+ });
147
+ }
148
+ return profiles;
149
+ }
150
+ export async function inspectPptx(buffer) {
151
+ const zip = await JSZip.loadAsync(buffer);
152
+ const properties = await extractPptxProperties(zip);
153
+ const slideProfiles = await extractPptxSlideProfiles(zip);
154
+ const riskFlags = await extractPptxRiskFlags(zip, slideProfiles);
155
+ return { properties, riskFlags, slideProfiles };
156
+ }
157
+ //# sourceMappingURL=inspect-pptx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect-pptx.js","sourceRoot":"","sources":["../../../src/slide/inspect-pptx.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { PresentationInspection, InspectSlideOptions } from './types.js';
2
+ export declare function inspectPresentation(filePath: string, options: InspectSlideOptions): Promise<PresentationInspection>;
@@ -0,0 +1,76 @@
1
+ import path from 'node:path';
2
+ import { readFile } from 'node:fs/promises';
3
+ import { getExtension } from '../utils.js';
4
+ import { estimateTokens } from '../inspect/shared.js';
5
+ import { inspectPptx } from './inspect-pptx.js';
6
+ import { inspectOdp } from './inspect-odp.js';
7
+ const SUPPORTED_EXTENSIONS = new Set(['pptx', 'odp']);
8
+ export async function inspectPresentation(filePath, options) {
9
+ const resolvedPath = path.resolve(filePath);
10
+ const ext = getExtension(resolvedPath);
11
+ if (!SUPPORTED_EXTENSIONS.has(ext)) {
12
+ throw new Error(`Unsupported presentation format: .${ext || '(none)'} (expected .pptx or .odp)`);
13
+ }
14
+ const buffer = await readFile(resolvedPath);
15
+ const format = ext;
16
+ let result;
17
+ switch (format) {
18
+ case 'pptx':
19
+ result = await inspectPptx(buffer);
20
+ break;
21
+ case 'odp':
22
+ result = await inspectOdp(buffer);
23
+ break;
24
+ }
25
+ // Filter to specific slide if requested
26
+ let slideProfiles = result.slideProfiles;
27
+ if (options.slide) {
28
+ const slideIndex = options.slide;
29
+ if (slideIndex < 1 || slideIndex > slideProfiles.length) {
30
+ throw new Error(`Slide ${slideIndex} out of range (1-${slideProfiles.length})`);
31
+ }
32
+ slideProfiles = [slideProfiles[slideIndex - 1]];
33
+ }
34
+ // Compute content stats
35
+ const contentStats = {
36
+ slides: result.slideProfiles.length,
37
+ words: result.slideProfiles.reduce((sum, p) => sum + p.words, 0),
38
+ slidesWithNotes: result.slideProfiles.filter(p => p.hasNotes).length,
39
+ totalImages: result.slideProfiles.reduce((sum, p) => sum + p.images, 0),
40
+ totalTables: result.slideProfiles.reduce((sum, p) => sum + p.tables, 0),
41
+ totalCharts: result.slideProfiles.reduce((sum, p) => sum + p.charts, 0),
42
+ };
43
+ // Build slide preview
44
+ const previewSlides = slideProfiles.slice(0, options.sampleSlides);
45
+ const slidePreview = {
46
+ truncated: slideProfiles.length > options.sampleSlides,
47
+ slides: previewSlides.map(p => ({
48
+ index: p.index,
49
+ title: p.title,
50
+ textPreview: p.notePreview ? `[Notes] ${p.notePreview}` : '',
51
+ hasNotes: p.hasNotes,
52
+ })),
53
+ };
54
+ // Token estimates
55
+ const allText = result.slideProfiles.map(p => {
56
+ let text = p.title || '';
57
+ if (p.notePreview)
58
+ text += ' ' + p.notePreview;
59
+ return text;
60
+ }).join(' ');
61
+ const fullTokenEstimate = estimateTokens(allText.length + contentStats.words * 5);
62
+ const previewTokenEstimate = estimateTokens(slidePreview.slides.reduce((sum, s) => sum + (s.title?.length || 0) + s.textPreview.length, 0));
63
+ return {
64
+ file: resolvedPath,
65
+ format,
66
+ size: buffer.length,
67
+ properties: result.properties,
68
+ riskFlags: result.riskFlags,
69
+ contentStats,
70
+ slideInventory: slideProfiles,
71
+ slidePreview,
72
+ fullTokenEstimate,
73
+ previewTokenEstimate,
74
+ };
75
+ }
76
+ //# sourceMappingURL=inspect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect.js","sourceRoot":"","sources":["../../../src/slide/inspect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { PresentationInspection, SlideInspectPayload } from './types.js';
2
+ export declare function formatSlidePayloadJson(payload: SlideInspectPayload): string;
3
+ export declare function formatSlideInspection(result: PresentationInspection, ci?: boolean): string;
@@ -0,0 +1,92 @@
1
+ import Table from 'cli-table3';
2
+ import chalk from 'chalk';
3
+ import { formatBytes, formatNumber } from '../utils.js';
4
+ import { sectionHeader, stripAnsi, tableChars } from '../output/tabular.js';
5
+ const colors = {
6
+ header: (value) => chalk.bold(value),
7
+ key: (value) => chalk.cyan(value),
8
+ value: (value) => value,
9
+ dim: (value) => chalk.dim(value),
10
+ ok: (value) => chalk.green(value),
11
+ warn: (value) => chalk.yellow(value),
12
+ };
13
+ const noColor = Object.fromEntries(Object.keys(colors).map(key => [key, (value) => value]));
14
+ function palette(ci = false) {
15
+ return ci ? noColor : colors;
16
+ }
17
+ export function formatSlidePayloadJson(payload) {
18
+ return JSON.stringify(payload, null, 2);
19
+ }
20
+ export function formatSlideInspection(result, ci = false) {
21
+ const c = palette(ci);
22
+ const sections = [];
23
+ // Overview
24
+ const overviewLines = [
25
+ `${c.key('File')}: ${c.value(result.file)}`,
26
+ `${c.key('Format')}: ${c.value(result.format.toUpperCase())}`,
27
+ `${c.key('Size')}: ${c.value(formatBytes(result.size))}`,
28
+ ];
29
+ const propEntries = Object.entries(result.properties).filter(([, value]) => value);
30
+ if (propEntries.length > 0) {
31
+ overviewLines.push(`${c.key('Properties')}: ${propEntries.map(([key, value]) => `${key}=${value}`).join(' | ')}`);
32
+ }
33
+ const riskFlags = Object.entries(result.riskFlags).filter(([, enabled]) => enabled).map(([key]) => key);
34
+ overviewLines.push(`${c.key('Risk Flags')}: ${riskFlags.length > 0 ? c.warn(riskFlags.join(', ')) : c.ok('none')}`);
35
+ sections.push(overviewLines.join('\n'));
36
+ // Content Stats
37
+ const statsLines = [
38
+ ` ${c.key('Slides')}: ${formatNumber(result.contentStats.slides)} ${c.key('Words')}: ${formatNumber(result.contentStats.words)}`,
39
+ ` ${c.key('Slides with Notes')}: ${formatNumber(result.contentStats.slidesWithNotes)}`,
40
+ ` ${c.key('Images')}: ${formatNumber(result.contentStats.totalImages)} ${c.key('Tables')}: ${formatNumber(result.contentStats.totalTables)} ${c.key('Charts')}: ${formatNumber(result.contentStats.totalCharts)}`,
41
+ ` ${c.key('Token Estimate')}: preview=${formatNumber(result.previewTokenEstimate)} | full=${formatNumber(result.fullTokenEstimate)}`,
42
+ ];
43
+ const statsWidth = Math.max(...statsLines.map(line => stripAnsi(line).length), 56);
44
+ sections.push(`${c.header(sectionHeader('Content Stats', statsWidth, ci))}\n${statsLines.join('\n')}`);
45
+ // Slide Inventory
46
+ if (result.slideInventory.length > 0) {
47
+ const table = new Table({
48
+ head: [
49
+ c.key('#'),
50
+ c.key('Title'),
51
+ c.key('Words'),
52
+ c.key('Notes'),
53
+ c.key('Images'),
54
+ c.key('Tables'),
55
+ ],
56
+ chars: tableChars(ci),
57
+ style: { head: [], border: [] },
58
+ colAligns: ['right', 'left', 'right', 'left', 'right', 'right'],
59
+ });
60
+ for (const slide of result.slideInventory) {
61
+ table.push([
62
+ String(slide.index),
63
+ slide.title || c.dim('(untitled)'),
64
+ formatNumber(slide.words),
65
+ slide.hasNotes ? 'yes' : '',
66
+ formatNumber(slide.images),
67
+ formatNumber(slide.tables),
68
+ ]);
69
+ }
70
+ const rendered = table.toString();
71
+ const width = stripAnsi(rendered.split('\n')[0] ?? '').length;
72
+ sections.push(`${c.header(sectionHeader('Slide Inventory', width, ci))}\n${rendered}`);
73
+ }
74
+ // Slide Preview
75
+ if (result.slidePreview.slides.length > 0) {
76
+ const previewLines = [];
77
+ for (const slide of result.slidePreview.slides) {
78
+ previewLines.push(` ${c.key(`--- Slide ${slide.index}: ${slide.title || '(untitled)'} ---`)}`);
79
+ if (slide.textPreview) {
80
+ previewLines.push(` ${slide.textPreview.length > 300 ? slide.textPreview.slice(0, 300) + '...' : slide.textPreview}`);
81
+ }
82
+ }
83
+ if (result.slidePreview.truncated) {
84
+ const remaining = result.contentStats.slides - result.slidePreview.slides.length;
85
+ previewLines.push(c.dim(` (${remaining} more slides)`));
86
+ }
87
+ const previewWidth = Math.max(...previewLines.map(line => stripAnsi(line).length), 56);
88
+ sections.push(`${c.header(sectionHeader('Slide Preview', previewWidth, ci))}\n${previewLines.join('\n')}`);
89
+ }
90
+ return sections.join('\n\n') + '\n';
91
+ }
92
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../../src/slide/output.ts"],"names":[],"mappings":"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"}