github-weekly-reporter 0.1.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.
Files changed (147) hide show
  1. package/LICENSE +38 -0
  2. package/README.md +163 -0
  3. package/dist/cli/commands/deploy.d.ts +3 -0
  4. package/dist/cli/commands/deploy.d.ts.map +1 -0
  5. package/dist/cli/commands/deploy.js +55 -0
  6. package/dist/cli/commands/deploy.js.map +1 -0
  7. package/dist/cli/commands/generate.d.ts +3 -0
  8. package/dist/cli/commands/generate.d.ts.map +1 -0
  9. package/dist/cli/commands/generate.js +106 -0
  10. package/dist/cli/commands/generate.js.map +1 -0
  11. package/dist/cli/config.d.ts +11 -0
  12. package/dist/cli/config.d.ts.map +1 -0
  13. package/dist/cli/config.js +16 -0
  14. package/dist/cli/config.js.map +1 -0
  15. package/dist/cli/config.test.d.ts +2 -0
  16. package/dist/cli/config.test.d.ts.map +1 -0
  17. package/dist/cli/config.test.js +32 -0
  18. package/dist/cli/config.test.js.map +1 -0
  19. package/dist/cli/index.d.ts +3 -0
  20. package/dist/cli/index.d.ts.map +1 -0
  21. package/dist/cli/index.js +13 -0
  22. package/dist/cli/index.js.map +1 -0
  23. package/dist/collector/aggregate.d.ts +3 -0
  24. package/dist/collector/aggregate.d.ts.map +1 -0
  25. package/dist/collector/aggregate.js +34 -0
  26. package/dist/collector/aggregate.js.map +1 -0
  27. package/dist/collector/aggregate.test.d.ts +2 -0
  28. package/dist/collector/aggregate.test.d.ts.map +1 -0
  29. package/dist/collector/aggregate.test.js +88 -0
  30. package/dist/collector/aggregate.test.js.map +1 -0
  31. package/dist/collector/date-range.d.ts +7 -0
  32. package/dist/collector/date-range.d.ts.map +1 -0
  33. package/dist/collector/date-range.js +8 -0
  34. package/dist/collector/date-range.js.map +1 -0
  35. package/dist/collector/date-range.test.d.ts +2 -0
  36. package/dist/collector/date-range.test.d.ts.map +1 -0
  37. package/dist/collector/date-range.test.js +25 -0
  38. package/dist/collector/date-range.test.js.map +1 -0
  39. package/dist/collector/fetch-contributions.d.ts +12 -0
  40. package/dist/collector/fetch-contributions.d.ts.map +1 -0
  41. package/dist/collector/fetch-contributions.js +24 -0
  42. package/dist/collector/fetch-contributions.js.map +1 -0
  43. package/dist/collector/fetch-issues.d.ts +5 -0
  44. package/dist/collector/fetch-issues.d.ts.map +1 -0
  45. package/dist/collector/fetch-issues.js +31 -0
  46. package/dist/collector/fetch-issues.js.map +1 -0
  47. package/dist/collector/fetch-languages.d.ts +4 -0
  48. package/dist/collector/fetch-languages.d.ts.map +1 -0
  49. package/dist/collector/fetch-languages.js +42 -0
  50. package/dist/collector/fetch-languages.js.map +1 -0
  51. package/dist/collector/fetch-pull-requests.d.ts +5 -0
  52. package/dist/collector/fetch-pull-requests.d.ts.map +1 -0
  53. package/dist/collector/fetch-pull-requests.js +31 -0
  54. package/dist/collector/fetch-pull-requests.js.map +1 -0
  55. package/dist/collector/index.d.ts +3 -0
  56. package/dist/collector/index.d.ts.map +1 -0
  57. package/dist/collector/index.js +50 -0
  58. package/dist/collector/index.js.map +1 -0
  59. package/dist/collector/queries.d.ts +5 -0
  60. package/dist/collector/queries.d.ts.map +1 -0
  61. package/dist/collector/queries.js +81 -0
  62. package/dist/collector/queries.js.map +1 -0
  63. package/dist/deployer/index-page.d.ts +3 -0
  64. package/dist/deployer/index-page.d.ts.map +1 -0
  65. package/dist/deployer/index-page.js +51 -0
  66. package/dist/deployer/index-page.js.map +1 -0
  67. package/dist/deployer/index-page.test.d.ts +2 -0
  68. package/dist/deployer/index-page.test.d.ts.map +1 -0
  69. package/dist/deployer/index-page.test.js +29 -0
  70. package/dist/deployer/index-page.test.js.map +1 -0
  71. package/dist/deployer/index.d.ts +7 -0
  72. package/dist/deployer/index.d.ts.map +1 -0
  73. package/dist/deployer/index.js +16 -0
  74. package/dist/deployer/index.js.map +1 -0
  75. package/dist/deployer/week.d.ts +7 -0
  76. package/dist/deployer/week.d.ts.map +1 -0
  77. package/dist/deployer/week.js +14 -0
  78. package/dist/deployer/week.js.map +1 -0
  79. package/dist/deployer/week.test.d.ts +2 -0
  80. package/dist/deployer/week.test.d.ts.map +1 -0
  81. package/dist/deployer/week.test.js +21 -0
  82. package/dist/deployer/week.test.js.map +1 -0
  83. package/dist/index.d.ts +8 -0
  84. package/dist/index.d.ts.map +1 -0
  85. package/dist/index.js +5 -0
  86. package/dist/index.js.map +1 -0
  87. package/dist/llm/index.d.ts +4 -0
  88. package/dist/llm/index.d.ts.map +1 -0
  89. package/dist/llm/index.js +25 -0
  90. package/dist/llm/index.js.map +1 -0
  91. package/dist/llm/llm.test.d.ts +2 -0
  92. package/dist/llm/llm.test.d.ts.map +1 -0
  93. package/dist/llm/llm.test.js +24 -0
  94. package/dist/llm/llm.test.js.map +1 -0
  95. package/dist/llm/prompt.d.ts +3 -0
  96. package/dist/llm/prompt.d.ts.map +1 -0
  97. package/dist/llm/prompt.js +31 -0
  98. package/dist/llm/prompt.js.map +1 -0
  99. package/dist/llm/prompt.test.d.ts +2 -0
  100. package/dist/llm/prompt.test.d.ts.map +1 -0
  101. package/dist/llm/prompt.test.js +48 -0
  102. package/dist/llm/prompt.test.js.map +1 -0
  103. package/dist/llm/providers/anthropic.d.ts +3 -0
  104. package/dist/llm/providers/anthropic.d.ts.map +1 -0
  105. package/dist/llm/providers/anthropic.js +17 -0
  106. package/dist/llm/providers/anthropic.js.map +1 -0
  107. package/dist/llm/providers/gemini.d.ts +3 -0
  108. package/dist/llm/providers/gemini.d.ts.map +1 -0
  109. package/dist/llm/providers/gemini.js +13 -0
  110. package/dist/llm/providers/gemini.js.map +1 -0
  111. package/dist/llm/providers/openai.d.ts +3 -0
  112. package/dist/llm/providers/openai.d.ts.map +1 -0
  113. package/dist/llm/providers/openai.js +17 -0
  114. package/dist/llm/providers/openai.js.map +1 -0
  115. package/dist/llm/types.d.ts +11 -0
  116. package/dist/llm/types.d.ts.map +1 -0
  117. package/dist/llm/types.js +3 -0
  118. package/dist/llm/types.js.map +1 -0
  119. package/dist/renderer/helpers.d.ts +3 -0
  120. package/dist/renderer/helpers.d.ts.map +1 -0
  121. package/dist/renderer/helpers.js +22 -0
  122. package/dist/renderer/helpers.js.map +1 -0
  123. package/dist/renderer/index.d.ts +3 -0
  124. package/dist/renderer/index.d.ts.map +1 -0
  125. package/dist/renderer/index.js +45 -0
  126. package/dist/renderer/index.js.map +1 -0
  127. package/dist/renderer/renderer.test.d.ts +2 -0
  128. package/dist/renderer/renderer.test.d.ts.map +1 -0
  129. package/dist/renderer/renderer.test.js +111 -0
  130. package/dist/renderer/renderer.test.js.map +1 -0
  131. package/dist/renderer/themes.d.ts +18 -0
  132. package/dist/renderer/themes.d.ts.map +1 -0
  133. package/dist/renderer/themes.js +180 -0
  134. package/dist/renderer/themes.js.map +1 -0
  135. package/dist/types.d.ts +68 -0
  136. package/dist/types.d.ts.map +1 -0
  137. package/dist/types.js +3 -0
  138. package/dist/types.js.map +1 -0
  139. package/package.json +56 -0
  140. package/src/renderer/templates/partials/footer.hbs +3 -0
  141. package/src/renderer/templates/partials/header.hbs +7 -0
  142. package/src/renderer/templates/partials/heatmap.hbs +11 -0
  143. package/src/renderer/templates/partials/languages.hbs +19 -0
  144. package/src/renderer/templates/partials/narrative.hbs +10 -0
  145. package/src/renderer/templates/partials/repositories.hbs +25 -0
  146. package/src/renderer/templates/partials/stats.hbs +8 -0
  147. package/src/renderer/templates/report.hbs +27 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aggregate.test.js","sourceRoot":"","sources":["../../src/collector/aggregate.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAGvD,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,GAAG,GAAkB;YACzB;gBACE,KAAK,EAAE,SAAS;gBAChB,GAAG,EAAE,sCAAsC;gBAC3C,UAAU,EAAE,YAAY;gBACxB,KAAK,EAAE,QAAQ;gBACf,SAAS,EAAE,sBAAsB;gBACjC,QAAQ,EAAE,sBAAsB;aACjC;YACD;gBACE,KAAK,EAAE,aAAa;gBACpB,GAAG,EAAE,sCAAsC;gBAC3C,UAAU,EAAE,YAAY;gBACxB,KAAK,EAAE,MAAM;gBACb,SAAS,EAAE,sBAAsB;gBACjC,QAAQ,EAAE,IAAI;aACf;YACD;gBACE,KAAK,EAAE,aAAa;gBACpB,GAAG,EAAE,sCAAsC;gBAC3C,UAAU,EAAE,YAAY;gBACxB,KAAK,EAAE,QAAQ;gBACf,SAAS,EAAE,sBAAsB;gBACjC,QAAQ,EAAE,sBAAsB;aACjC;SACF,CAAC;QAEF,MAAM,MAAM,GAAY;YACtB;gBACE,KAAK,EAAE,YAAY;gBACnB,GAAG,EAAE,wCAAwC;gBAC7C,UAAU,EAAE,YAAY;gBACxB,KAAK,EAAE,QAAQ;gBACf,SAAS,EAAE,sBAAsB;gBACjC,QAAQ,EAAE,sBAAsB;aACjC;SACF,CAAC;QAEF,MAAM,MAAM,GAAG,qBAAqB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAElD,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAE/B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;QAC1D,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QAC5B,MAAM,CAAC,KAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjC,MAAM,CAAC,KAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjC,MAAM,CAAC,KAAM,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpC,MAAM,CAAC,KAAM,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAEpC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;QAC1D,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QAC5B,MAAM,CAAC,KAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjC,MAAM,CAAC,KAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,GAAG,GAAkB;YACzB;gBACE,KAAK,EAAE,KAAK;gBACZ,GAAG,EAAE,EAAE;gBACP,UAAU,EAAE,iBAAiB;gBAC7B,KAAK,EAAE,MAAM;gBACb,SAAS,EAAE,EAAE;gBACb,QAAQ,EAAE,IAAI;aACf;YACD;gBACE,KAAK,EAAE,KAAK;gBACZ,GAAG,EAAE,EAAE;gBACP,UAAU,EAAE,iBAAiB;gBAC7B,KAAK,EAAE,MAAM;gBACb,SAAS,EAAE,EAAE;gBACb,QAAQ,EAAE,IAAI;aACf;YACD;gBACE,KAAK,EAAE,KAAK;gBACZ,GAAG,EAAE,EAAE;gBACP,UAAU,EAAE,iBAAiB;gBAC7B,KAAK,EAAE,QAAQ;gBACf,SAAS,EAAE,EAAE;gBACb,QAAQ,EAAE,EAAE;aACb;SACF,CAAC;QAEF,MAAM,MAAM,GAAG,qBAAqB,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,CAAC,qBAAqB,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ export type DateRange = {
2
+ from: Date;
3
+ to: Date;
4
+ };
5
+ export declare const buildWeeklyRange: (now?: Date) => DateRange;
6
+ export declare const toISODate: (date: Date) => string;
7
+ //# sourceMappingURL=date-range.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-range.d.ts","sourceRoot":"","sources":["../../src/collector/date-range.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,IAAI,CAAC;IACX,EAAE,EAAE,IAAI,CAAC;CACV,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,MAAK,IAAiB,KAAG,SAoBzD,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,MAAM,IAAI,KAAG,MACL,CAAC"}
@@ -0,0 +1,8 @@
1
+ // Compute the date range for the past 7 days (UTC-based)
2
+ export const buildWeeklyRange = (now = new Date()) => {
3
+ const to = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), 23, 59, 59, 999));
4
+ const from = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() - 6, 0, 0, 0, 0));
5
+ return { from, to };
6
+ };
7
+ export const toISODate = (date) => date.toISOString().split("T")[0];
8
+ //# sourceMappingURL=date-range.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-range.js","sourceRoot":"","sources":["../../src/collector/date-range.ts"],"names":[],"mappings":"AAAA,yDAAyD;AAOzD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,MAAY,IAAI,IAAI,EAAE,EAAa,EAAE;IACpE,MAAM,EAAE,GAAG,IAAI,IAAI,CACjB,IAAI,CAAC,GAAG,CACN,GAAG,CAAC,cAAc,EAAE,EACpB,GAAG,CAAC,WAAW,EAAE,EACjB,GAAG,CAAC,UAAU,EAAE,EAChB,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAChB,CACF,CAAC;IAEF,MAAM,IAAI,GAAG,IAAI,IAAI,CACnB,IAAI,CAAC,GAAG,CACN,GAAG,CAAC,cAAc,EAAE,EACpB,GAAG,CAAC,WAAW,EAAE,EACjB,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,EACpB,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CACX,CACF,CAAC;IAEF,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AACtB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,IAAU,EAAU,EAAE,CAC9C,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=date-range.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-range.test.d.ts","sourceRoot":"","sources":["../../src/collector/date-range.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,25 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { buildWeeklyRange, toISODate } from "./date-range.js";
3
+ describe("buildWeeklyRange", () => {
4
+ it("returns a 7-day range ending on the given date", () => {
5
+ const now = new Date("2026-04-03T12:00:00Z");
6
+ const range = buildWeeklyRange(now);
7
+ expect(toISODate(range.from)).toBe("2026-03-28");
8
+ expect(toISODate(range.to)).toBe("2026-04-03");
9
+ });
10
+ it("sets from to midnight UTC and to to end of day UTC", () => {
11
+ const now = new Date("2026-04-03T15:30:00Z");
12
+ const range = buildWeeklyRange(now);
13
+ expect(range.from.getUTCHours()).toBe(0);
14
+ expect(range.from.getUTCMinutes()).toBe(0);
15
+ expect(range.to.getUTCHours()).toBe(23);
16
+ expect(range.to.getUTCMinutes()).toBe(59);
17
+ });
18
+ });
19
+ describe("toISODate", () => {
20
+ it("formats a date as YYYY-MM-DD", () => {
21
+ const date = new Date("2026-04-03T12:00:00Z");
22
+ expect(toISODate(date)).toBe("2026-04-03");
23
+ });
24
+ });
25
+ //# sourceMappingURL=date-range.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-range.test.js","sourceRoot":"","sources":["../../src/collector/date-range.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE9D,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;QAEpC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACjD,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;QAEpC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACzC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAC9C,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { graphql } from "@octokit/graphql";
2
+ import type { DateRange } from "./date-range.js";
3
+ import type { DailyCommitCount } from "../types.js";
4
+ export type ContributionsSummary = {
5
+ username: string;
6
+ avatarUrl: string;
7
+ totalCommits: number;
8
+ prsReviewed: number;
9
+ dailyCommits: DailyCommitCount[];
10
+ };
11
+ export declare const fetchContributions: (gql: typeof graphql, username: string, range: DateRange) => Promise<ContributionsSummary>;
12
+ //# sourceMappingURL=fetch-contributions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-contributions.d.ts","sourceRoot":"","sources":["../../src/collector/fetch-contributions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEhD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAqBpD,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,gBAAgB,EAAE,CAAC;CAClC,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,KAAK,OAAO,OAAO,EACnB,UAAU,MAAM,EAChB,OAAO,SAAS,KACf,OAAO,CAAC,oBAAoB,CAwB9B,CAAC"}
@@ -0,0 +1,24 @@
1
+ // Fetch user contribution data from GitHub GraphQL API
2
+ import { USER_CONTRIBUTIONS_QUERY } from "./queries.js";
3
+ import { toISODate } from "./date-range.js";
4
+ export const fetchContributions = async (gql, username, range) => {
5
+ const { user } = await gql(USER_CONTRIBUTIONS_QUERY, {
6
+ username,
7
+ from: range.from.toISOString(),
8
+ to: range.to.toISOString(),
9
+ });
10
+ const fromDate = toISODate(range.from);
11
+ const toDate = toISODate(range.to);
12
+ const dailyCommits = user.contributionsCollection.contributionCalendar.weeks
13
+ .flatMap((w) => w.contributionDays)
14
+ .filter((d) => d.date >= fromDate && d.date <= toDate)
15
+ .map((d) => ({ date: d.date, count: d.contributionCount }));
16
+ return {
17
+ username: user.login,
18
+ avatarUrl: user.avatarUrl,
19
+ totalCommits: user.contributionsCollection.totalCommitContributions,
20
+ prsReviewed: user.contributionsCollection.totalPullRequestReviewContributions,
21
+ dailyCommits,
22
+ };
23
+ };
24
+ //# sourceMappingURL=fetch-contributions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-contributions.js","sourceRoot":"","sources":["../../src/collector/fetch-contributions.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAGvD,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAExD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AA8B5C,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,EACrC,GAAmB,EACnB,QAAgB,EAChB,KAAgB,EACe,EAAE;IACjC,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,GAAG,CAAwB,wBAAwB,EAAE;QAC1E,QAAQ;QACR,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE;QAC9B,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE;KAC3B,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAEnC,MAAM,YAAY,GAAG,IAAI,CAAC,uBAAuB,CAAC,oBAAoB,CAAC,KAAK;SACzE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC;SAClC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,QAAQ,IAAI,CAAC,CAAC,IAAI,IAAI,MAAM,CAAC;SACrD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC;IAE9D,OAAO;QACL,QAAQ,EAAE,IAAI,CAAC,KAAK;QACpB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,YAAY,EACV,IAAI,CAAC,uBAAuB,CAAC,wBAAwB;QACvD,WAAW,EACT,IAAI,CAAC,uBAAuB,CAAC,mCAAmC;QAClE,YAAY;KACb,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { graphql } from "@octokit/graphql";
2
+ import type { DateRange } from "./date-range.js";
3
+ import type { Issue } from "../types.js";
4
+ export declare const fetchIssues: (gql: typeof graphql, username: string, range: DateRange) => Promise<Issue[]>;
5
+ //# sourceMappingURL=fetch-issues.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-issues.d.ts","sourceRoot":"","sources":["../../src/collector/fetch-issues.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEhD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AA0CzC,eAAO,MAAM,WAAW,GACtB,KAAK,OAAO,OAAO,EACnB,UAAU,MAAM,EAChB,OAAO,SAAS,KACf,OAAO,CAAC,KAAK,EAAE,CAejB,CAAC"}
@@ -0,0 +1,31 @@
1
+ // Fetch issues authored by the user in the date range
2
+ import { SEARCH_ISSUES_QUERY } from "./queries.js";
3
+ import { toISODate } from "./date-range.js";
4
+ const mapState = (state) => state.toLowerCase();
5
+ const searchAllPages = async (gql, query) => {
6
+ const nodes = [];
7
+ let cursor;
8
+ let hasNextPage = true;
9
+ while (hasNextPage) {
10
+ const response = await gql(SEARCH_ISSUES_QUERY, { query, cursor });
11
+ nodes.push(...response.search.nodes);
12
+ hasNextPage = response.search.pageInfo.hasNextPage;
13
+ cursor = response.search.pageInfo.endCursor ?? undefined;
14
+ }
15
+ return nodes;
16
+ };
17
+ export const fetchIssues = async (gql, username, range) => {
18
+ const from = toISODate(range.from);
19
+ const to = toISODate(range.to);
20
+ const query = `author:${username} is:issue created:${from}..${to}`;
21
+ const nodes = await searchAllPages(gql, query);
22
+ return nodes.map((issue) => ({
23
+ title: issue.title,
24
+ url: issue.url,
25
+ repository: issue.repository.nameWithOwner,
26
+ state: mapState(issue.state),
27
+ createdAt: issue.createdAt,
28
+ closedAt: issue.closedAt,
29
+ }));
30
+ };
31
+ //# sourceMappingURL=fetch-issues.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-issues.js","sourceRoot":"","sources":["../../src/collector/fetch-issues.ts"],"names":[],"mappings":"AAAA,sDAAsD;AAGtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAmB5C,MAAM,QAAQ,GAAG,CAAC,KAAyB,EAAkB,EAAE,CAC7D,KAAK,CAAC,WAAW,EAAoB,CAAC;AAExC,MAAM,cAAc,GAAG,KAAK,EAC1B,GAAmB,EACnB,KAAa,EACS,EAAE;IACxB,MAAM,KAAK,GAAgB,EAAE,CAAC;IAC9B,IAAI,MAA0B,CAAC;IAC/B,IAAI,WAAW,GAAG,IAAI,CAAC;IAEvB,OAAO,WAAW,EAAE,CAAC;QACnB,MAAM,QAAQ,GAAmB,MAAM,GAAG,CACxC,mBAAmB,EACnB,EAAE,KAAK,EAAE,MAAM,EAAE,CAClB,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACrC,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC;QACnD,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,IAAI,SAAS,CAAC;IAC3D,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAC9B,GAAmB,EACnB,QAAgB,EAChB,KAAgB,EACE,EAAE;IACpB,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC/B,MAAM,KAAK,GAAG,UAAU,QAAQ,qBAAqB,IAAI,KAAK,EAAE,EAAE,CAAC;IAEnE,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAE/C,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC3B,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,aAAa;QAC1C,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC;QAC5B,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,QAAQ,EAAE,KAAK,CAAC,QAAQ;KACzB,CAAC,CAAC,CAAC;AACN,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { graphql } from "@octokit/graphql";
2
+ import type { LanguageBreakdown } from "../types.js";
3
+ export declare const fetchLanguages: (gql: typeof graphql, repoNames: string[]) => Promise<LanguageBreakdown[]>;
4
+ //# sourceMappingURL=fetch-languages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-languages.d.ts","sourceRoot":"","sources":["../../src/collector/fetch-languages.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEhD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAoCrD,eAAO,MAAM,cAAc,GACzB,KAAK,OAAO,OAAO,EACnB,WAAW,MAAM,EAAE,KAClB,OAAO,CAAC,iBAAiB,EAAE,CA+B7B,CAAC"}
@@ -0,0 +1,42 @@
1
+ // Fetch language breakdown for active repositories
2
+ import { REPO_LANGUAGES_QUERY } from "./queries.js";
3
+ const fetchRepoLanguages = async (gql, repoFullName) => {
4
+ const [owner, name] = repoFullName.split("/");
5
+ try {
6
+ const { repository } = await gql(REPO_LANGUAGES_QUERY, {
7
+ owner,
8
+ name,
9
+ });
10
+ return repository.languages.edges.map((e) => ({
11
+ name: e.node.name,
12
+ bytes: e.size,
13
+ color: e.node.color ?? "#8b8b8b",
14
+ }));
15
+ }
16
+ catch {
17
+ // Repository may be inaccessible with the given token
18
+ return [];
19
+ }
20
+ };
21
+ export const fetchLanguages = async (gql, repoNames) => {
22
+ const uniqueRepos = [...new Set(repoNames)];
23
+ const allLanguages = await Promise.all(uniqueRepos.map((repo) => fetchRepoLanguages(gql, repo)));
24
+ const accumulated = allLanguages.flat().reduce((acc, lang) => {
25
+ const existing = acc.get(lang.name);
26
+ acc.set(lang.name, {
27
+ bytes: (existing?.bytes ?? 0) + lang.bytes,
28
+ color: existing?.color ?? lang.color,
29
+ });
30
+ return acc;
31
+ }, new Map());
32
+ const totalBytes = [...accumulated.values()].reduce((sum, l) => sum + l.bytes, 0);
33
+ return [...accumulated.entries()]
34
+ .map(([language, { bytes, color }]) => ({
35
+ language,
36
+ bytes,
37
+ percentage: totalBytes > 0 ? (bytes / totalBytes) * 100 : 0,
38
+ color,
39
+ }))
40
+ .sort((a, b) => b.bytes - a.bytes);
41
+ };
42
+ //# sourceMappingURL=fetch-languages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-languages.js","sourceRoot":"","sources":["../../src/collector/fetch-languages.ts"],"names":[],"mappings":"AAAA,mDAAmD;AAGnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAgBpD,MAAM,kBAAkB,GAAG,KAAK,EAC9B,GAAmB,EACnB,YAAoB,EACuC,EAAE;IAC7D,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9C,IAAI,CAAC;QACH,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,GAAG,CAAoB,oBAAoB,EAAE;YACxE,KAAK;YACL,IAAI;SACL,CAAC,CAAC;QACH,OAAO,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC5C,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI;YACjB,KAAK,EAAE,CAAC,CAAC,IAAI;YACb,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,SAAS;SACjC,CAAC,CAAC,CAAC;IACN,CAAC;IAAC,MAAM,CAAC;QACP,sDAAsD;QACtD,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EACjC,GAAmB,EACnB,SAAmB,EACW,EAAE;IAChC,MAAM,WAAW,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;IAC5C,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,CACpC,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CACzD,CAAC;IAEF,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC,MAAM,CAC5C,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;QACZ,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE;YACjB,KAAK,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK;YAC1C,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,IAAI,CAAC,KAAK;SACrC,CAAC,CAAC;QACH,OAAO,GAAG,CAAC;IACb,CAAC,EACD,IAAI,GAAG,EAAE,CACV,CAAC;IAEF,MAAM,UAAU,GAAG,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CACjD,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,EACzB,CAAC,CACF,CAAC;IAEF,OAAO,CAAC,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC;SAC9B,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACtC,QAAQ;QACR,KAAK;QACL,UAAU,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;QAC3D,KAAK;KACN,CAAC,CAAC;SACF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;AACvC,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { graphql } from "@octokit/graphql";
2
+ import type { DateRange } from "./date-range.js";
3
+ import type { PullRequest } from "../types.js";
4
+ export declare const fetchPullRequests: (gql: typeof graphql, username: string, range: DateRange) => Promise<PullRequest[]>;
5
+ //# sourceMappingURL=fetch-pull-requests.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-pull-requests.d.ts","sourceRoot":"","sources":["../../src/collector/fetch-pull-requests.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEhD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AA0C/C,eAAO,MAAM,iBAAiB,GAC5B,KAAK,OAAO,OAAO,EACnB,UAAU,MAAM,EAChB,OAAO,SAAS,KACf,OAAO,CAAC,WAAW,EAAE,CAevB,CAAC"}
@@ -0,0 +1,31 @@
1
+ // Fetch pull requests authored by the user in the date range
2
+ import { SEARCH_PRS_QUERY } from "./queries.js";
3
+ import { toISODate } from "./date-range.js";
4
+ const mapState = (state) => state.toLowerCase();
5
+ const searchAllPages = async (gql, query) => {
6
+ const nodes = [];
7
+ let cursor;
8
+ let hasNextPage = true;
9
+ while (hasNextPage) {
10
+ const response = await gql(SEARCH_PRS_QUERY, { query, cursor });
11
+ nodes.push(...response.search.nodes);
12
+ hasNextPage = response.search.pageInfo.hasNextPage;
13
+ cursor = response.search.pageInfo.endCursor ?? undefined;
14
+ }
15
+ return nodes;
16
+ };
17
+ export const fetchPullRequests = async (gql, username, range) => {
18
+ const from = toISODate(range.from);
19
+ const to = toISODate(range.to);
20
+ const query = `author:${username} is:pr created:${from}..${to}`;
21
+ const nodes = await searchAllPages(gql, query);
22
+ return nodes.map((pr) => ({
23
+ title: pr.title,
24
+ url: pr.url,
25
+ repository: pr.repository.nameWithOwner,
26
+ state: mapState(pr.state),
27
+ createdAt: pr.createdAt,
28
+ mergedAt: pr.mergedAt,
29
+ }));
30
+ };
31
+ //# sourceMappingURL=fetch-pull-requests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-pull-requests.js","sourceRoot":"","sources":["../../src/collector/fetch-pull-requests.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAG7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAmB5C,MAAM,QAAQ,GAAG,CAAC,KAAsB,EAAwB,EAAE,CAChE,KAAK,CAAC,WAAW,EAA0B,CAAC;AAE9C,MAAM,cAAc,GAAG,KAAK,EAC1B,GAAmB,EACnB,KAAa,EACM,EAAE;IACrB,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,MAA0B,CAAC;IAC/B,IAAI,WAAW,GAAG,IAAI,CAAC;IAEvB,OAAO,WAAW,EAAE,CAAC;QACnB,MAAM,QAAQ,GAAmB,MAAM,GAAG,CACxC,gBAAgB,EAChB,EAAE,KAAK,EAAE,MAAM,EAAE,CAClB,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACrC,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC;QACnD,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,IAAI,SAAS,CAAC;IAC3D,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EACpC,GAAmB,EACnB,QAAgB,EAChB,KAAgB,EACQ,EAAE;IAC1B,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC/B,MAAM,KAAK,GAAG,UAAU,QAAQ,kBAAkB,IAAI,KAAK,EAAE,EAAE,CAAC;IAEhE,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAE/C,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QACxB,KAAK,EAAE,EAAE,CAAC,KAAK;QACf,GAAG,EAAE,EAAE,CAAC,GAAG;QACX,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,aAAa;QACvC,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC;QACzB,SAAS,EAAE,EAAE,CAAC,SAAS;QACvB,QAAQ,EAAE,EAAE,CAAC,QAAQ;KACtB,CAAC,CAAC,CAAC;AACN,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { WeeklyReportData } from "../types.js";
2
+ export declare const collectWeeklyData: (token: string, username: string) => Promise<WeeklyReportData>;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/collector/index.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,eAAO,MAAM,iBAAiB,GAC5B,OAAO,MAAM,EACb,UAAU,MAAM,KACf,OAAO,CAAC,gBAAgB,CA6C1B,CAAC"}
@@ -0,0 +1,50 @@
1
+ // Main entry point for GitHub data collection
2
+ import { graphql } from "@octokit/graphql";
3
+ import { buildWeeklyRange, toISODate } from "./date-range.js";
4
+ import { fetchContributions } from "./fetch-contributions.js";
5
+ import { fetchPullRequests } from "./fetch-pull-requests.js";
6
+ import { fetchIssues } from "./fetch-issues.js";
7
+ import { fetchLanguages } from "./fetch-languages.js";
8
+ import { aggregateRepositories } from "./aggregate.js";
9
+ export const collectWeeklyData = async (token, username) => {
10
+ const gql = graphql.defaults({
11
+ headers: { authorization: `token ${token}` },
12
+ });
13
+ const range = buildWeeklyRange();
14
+ const [contributions, pullRequests, issues] = await Promise.all([
15
+ fetchContributions(gql, username, range),
16
+ fetchPullRequests(gql, username, range),
17
+ fetchIssues(gql, username, range),
18
+ ]);
19
+ const activeRepoNames = [
20
+ ...pullRequests.map((pr) => pr.repository),
21
+ ...issues.map((i) => i.repository),
22
+ ];
23
+ const [languages, repositories] = await Promise.all([
24
+ fetchLanguages(gql, activeRepoNames),
25
+ Promise.resolve(aggregateRepositories(pullRequests, issues)),
26
+ ]);
27
+ return {
28
+ username: contributions.username,
29
+ avatarUrl: contributions.avatarUrl,
30
+ dateRange: {
31
+ from: toISODate(range.from),
32
+ to: toISODate(range.to),
33
+ },
34
+ stats: {
35
+ totalCommits: contributions.totalCommits,
36
+ prsOpened: pullRequests.length,
37
+ prsMerged: pullRequests.filter((pr) => pr.state === "merged").length,
38
+ prsReviewed: contributions.prsReviewed,
39
+ issuesOpened: issues.length,
40
+ issuesClosed: issues.filter((i) => i.state === "closed").length,
41
+ },
42
+ dailyCommits: contributions.dailyCommits,
43
+ repositories,
44
+ languages,
45
+ pullRequests,
46
+ issues,
47
+ aiNarrative: null,
48
+ };
49
+ };
50
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/collector/index.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAE9C,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAGvD,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EACpC,KAAa,EACb,QAAgB,EACW,EAAE;IAC7B,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC;QAC3B,OAAO,EAAE,EAAE,aAAa,EAAE,SAAS,KAAK,EAAE,EAAE;KAC7C,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;IAEjC,MAAM,CAAC,aAAa,EAAE,YAAY,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC9D,kBAAkB,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC;QACxC,iBAAiB,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC;QACvC,WAAW,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC;KAClC,CAAC,CAAC;IAEH,MAAM,eAAe,GAAG;QACtB,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC;QAC1C,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC;KACnC,CAAC;IAEF,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAClD,cAAc,CAAC,GAAG,EAAE,eAAe,CAAC;QACpC,OAAO,CAAC,OAAO,CAAC,qBAAqB,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;KAC7D,CAAC,CAAC;IAEH,OAAO;QACL,QAAQ,EAAE,aAAa,CAAC,QAAQ;QAChC,SAAS,EAAE,aAAa,CAAC,SAAS;QAClC,SAAS,EAAE;YACT,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC;YAC3B,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;SACxB;QACD,KAAK,EAAE;YACL,YAAY,EAAE,aAAa,CAAC,YAAY;YACxC,SAAS,EAAE,YAAY,CAAC,MAAM;YAC9B,SAAS,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,MAAM;YACpE,WAAW,EAAE,aAAa,CAAC,WAAW;YACtC,YAAY,EAAE,MAAM,CAAC,MAAM;YAC3B,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,MAAM;SAChE;QACD,YAAY,EAAE,aAAa,CAAC,YAAY;QACxC,YAAY;QACZ,SAAS;QACT,YAAY;QACZ,MAAM;QACN,WAAW,EAAE,IAAI;KAClB,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare const USER_CONTRIBUTIONS_QUERY = "\n query($username: String!, $from: DateTime!, $to: DateTime!) {\n user(login: $username) {\n login\n avatarUrl\n contributionsCollection(from: $from, to: $to) {\n totalCommitContributions\n totalPullRequestReviewContributions\n contributionCalendar {\n weeks {\n contributionDays {\n date\n contributionCount\n }\n }\n }\n }\n }\n }\n";
2
+ export declare const SEARCH_PRS_QUERY = "\n query($query: String!, $cursor: String) {\n search(query: $query, type: ISSUE, first: 100, after: $cursor) {\n pageInfo {\n hasNextPage\n endCursor\n }\n nodes {\n ... on PullRequest {\n title\n url\n state\n createdAt\n mergedAt\n repository {\n nameWithOwner\n }\n }\n }\n }\n }\n";
3
+ export declare const SEARCH_ISSUES_QUERY = "\n query($query: String!, $cursor: String) {\n search(query: $query, type: ISSUE, first: 100, after: $cursor) {\n pageInfo {\n hasNextPage\n endCursor\n }\n nodes {\n ... on Issue {\n title\n url\n state\n createdAt\n closedAt\n repository {\n nameWithOwner\n }\n }\n }\n }\n }\n";
4
+ export declare const REPO_LANGUAGES_QUERY = "\n query($owner: String!, $name: String!) {\n repository(owner: $owner, name: $name) {\n languages(first: 20, orderBy: { field: SIZE, direction: DESC }) {\n edges {\n size\n node {\n name\n color\n }\n }\n }\n }\n }\n";
5
+ //# sourceMappingURL=queries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../src/collector/queries.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,wBAAwB,8cAmBpC,CAAC;AAEF,eAAO,MAAM,gBAAgB,oaAqB5B,CAAC;AAEF,eAAO,MAAM,mBAAmB,8ZAqB/B,CAAC;AAEF,eAAO,MAAM,oBAAoB,+SAchC,CAAC"}
@@ -0,0 +1,81 @@
1
+ // GraphQL queries for GitHub API data collection
2
+ export const USER_CONTRIBUTIONS_QUERY = `
3
+ query($username: String!, $from: DateTime!, $to: DateTime!) {
4
+ user(login: $username) {
5
+ login
6
+ avatarUrl
7
+ contributionsCollection(from: $from, to: $to) {
8
+ totalCommitContributions
9
+ totalPullRequestReviewContributions
10
+ contributionCalendar {
11
+ weeks {
12
+ contributionDays {
13
+ date
14
+ contributionCount
15
+ }
16
+ }
17
+ }
18
+ }
19
+ }
20
+ }
21
+ `;
22
+ export const SEARCH_PRS_QUERY = `
23
+ query($query: String!, $cursor: String) {
24
+ search(query: $query, type: ISSUE, first: 100, after: $cursor) {
25
+ pageInfo {
26
+ hasNextPage
27
+ endCursor
28
+ }
29
+ nodes {
30
+ ... on PullRequest {
31
+ title
32
+ url
33
+ state
34
+ createdAt
35
+ mergedAt
36
+ repository {
37
+ nameWithOwner
38
+ }
39
+ }
40
+ }
41
+ }
42
+ }
43
+ `;
44
+ export const SEARCH_ISSUES_QUERY = `
45
+ query($query: String!, $cursor: String) {
46
+ search(query: $query, type: ISSUE, first: 100, after: $cursor) {
47
+ pageInfo {
48
+ hasNextPage
49
+ endCursor
50
+ }
51
+ nodes {
52
+ ... on Issue {
53
+ title
54
+ url
55
+ state
56
+ createdAt
57
+ closedAt
58
+ repository {
59
+ nameWithOwner
60
+ }
61
+ }
62
+ }
63
+ }
64
+ }
65
+ `;
66
+ export const REPO_LANGUAGES_QUERY = `
67
+ query($owner: String!, $name: String!) {
68
+ repository(owner: $owner, name: $name) {
69
+ languages(first: 20, orderBy: { field: SIZE, direction: DESC }) {
70
+ edges {
71
+ size
72
+ node {
73
+ name
74
+ color
75
+ }
76
+ }
77
+ }
78
+ }
79
+ }
80
+ `;
81
+ //# sourceMappingURL=queries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queries.js","sourceRoot":"","sources":["../../src/collector/queries.ts"],"names":[],"mappings":"AAAA,iDAAiD;AAEjD,MAAM,CAAC,MAAM,wBAAwB,GAAG;;;;;;;;;;;;;;;;;;;CAmBvC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;CAqB/B,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;CAqBlC,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;CAcnC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Theme } from "../types.js";
2
+ export declare const renderIndexPage: (reportPaths: string[], theme?: Theme) => string;
3
+ //# sourceMappingURL=index-page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-page.d.ts","sourceRoot":"","sources":["../../src/deployer/index-page.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAgDzC,eAAO,MAAM,eAAe,GAAI,aAAa,MAAM,EAAE,EAAE,QAAO,KAAiB,KAAG,MAQjF,CAAC"}
@@ -0,0 +1,51 @@
1
+ // Generate the index.html that lists all archived reports
2
+ import Handlebars from "handlebars";
3
+ import { buildCSS } from "../renderer/themes.js";
4
+ const TEMPLATE = `<!DOCTYPE html>
5
+ <html lang="en">
6
+ <head>
7
+ <title>Weekly Reports</title>
8
+ <meta charset="utf-8" />
9
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
10
+ <meta name="description" content="Archive of weekly GitHub activity reports" />
11
+ <style>{{{css}}}</style>
12
+ </head>
13
+ <body>
14
+ <div class="container">
15
+ <header class="header">
16
+ <div class="header-text">
17
+ <h1>Weekly Reports</h1>
18
+ <p class="date-range">All generated reports</p>
19
+ </div>
20
+ </header>
21
+
22
+ <div class="section">
23
+ <h2>Reports</h2>
24
+ <table class="repo-table">
25
+ <thead><tr><th>Week</th><th>Link</th></tr></thead>
26
+ <tbody>
27
+ {{#each reports}}
28
+ <tr>
29
+ <td>{{this.label}}</td>
30
+ <td><a href="{{this.path}}/">View Report</a></td>
31
+ </tr>
32
+ {{/each}}
33
+ </tbody>
34
+ </table>
35
+ </div>
36
+
37
+ <footer class="footer">
38
+ <p>Generated by <a href="https://deariary.com?utm_source=github-weekly-reporter&utm_medium=footer">deariary</a></p>
39
+ </footer>
40
+ </div>
41
+ </body>
42
+ </html>`;
43
+ export const renderIndexPage = (reportPaths, theme = "default") => {
44
+ const reports = reportPaths
45
+ .sort()
46
+ .reverse()
47
+ .map((p) => ({ path: p, label: p.replace("/", " ") }));
48
+ const template = Handlebars.compile(TEMPLATE);
49
+ return template({ reports, css: buildCSS(theme) });
50
+ };
51
+ //# sourceMappingURL=index-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-page.js","sourceRoot":"","sources":["../../src/deployer/index-page.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAE1D,OAAO,UAAU,MAAM,YAAY,CAAC;AAEpC,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAOjD,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAsCT,CAAC;AAET,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,WAAqB,EAAE,QAAe,SAAS,EAAU,EAAE;IACzF,MAAM,OAAO,GAAkB,WAAW;SACvC,IAAI,EAAE;SACN,OAAO,EAAE;SACT,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAEzD,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC9C,OAAO,QAAQ,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AACrD,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index-page.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-page.test.d.ts","sourceRoot":"","sources":["../../src/deployer/index-page.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,29 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { renderIndexPage } from "./index-page.js";
3
+ describe("renderIndexPage", () => {
4
+ it("produces valid HTML with report links", () => {
5
+ const html = renderIndexPage(["2026/W13", "2026/W14"]);
6
+ expect(html).toContain("<!DOCTYPE html>");
7
+ expect(html).toContain("2026/W14/");
8
+ expect(html).toContain("2026/W13/");
9
+ });
10
+ it("lists reports in reverse chronological order", () => {
11
+ const html = renderIndexPage(["2026/W12", "2026/W14", "2026/W13"]);
12
+ const w14Pos = html.indexOf("2026/W14");
13
+ const w13Pos = html.indexOf("2026/W13");
14
+ const w12Pos = html.indexOf("2026/W12");
15
+ expect(w14Pos).toBeLessThan(w13Pos);
16
+ expect(w13Pos).toBeLessThan(w12Pos);
17
+ });
18
+ it("includes dofollow footer link", () => {
19
+ const html = renderIndexPage(["2026/W14"]);
20
+ expect(html).toContain("deariary.com?utm_source=github-weekly-reporter");
21
+ expect(html).not.toContain('rel="nofollow"');
22
+ });
23
+ it("handles empty report list", () => {
24
+ const html = renderIndexPage([]);
25
+ expect(html).toContain("<!DOCTYPE html>");
26
+ expect(html).toContain("Weekly Reports");
27
+ });
28
+ });
29
+ //# sourceMappingURL=index-page.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-page.test.js","sourceRoot":"","sources":["../../src/deployer/index-page.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,IAAI,GAAG,eAAe,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;QACvD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,IAAI,GAAG,eAAe,CAAC,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;QACnE,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,IAAI,GAAG,eAAe,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,gDAAgD,CAAC,CAAC;QACzE,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,IAAI,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;QACjC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ export type DeployOptions = {
2
+ repoUrl: string;
3
+ directory: string;
4
+ message?: string;
5
+ };
6
+ export declare const deploy: (options: DeployOptions) => Promise<void>;
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/deployer/index.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,eAAO,MAAM,MAAM,GAAU,SAAS,aAAa,KAAG,OAAO,CAAC,IAAI,CAUjE,CAAC"}
@@ -0,0 +1,16 @@
1
+ // Deploy a directory to gh-pages branch
2
+ import { execFile } from "node:child_process";
3
+ import { promisify } from "node:util";
4
+ const exec = promisify(execFile);
5
+ const git = (args, cwd) => exec("git", args, { cwd });
6
+ export const deploy = async (options) => {
7
+ const { repoUrl, directory, message = "deploy" } = options;
8
+ await git(["init"], directory);
9
+ await git(["checkout", "--orphan", "gh-pages"], directory);
10
+ await git(["add", "."], directory);
11
+ await git(["config", "user.name", "github-weekly-reporter"], directory);
12
+ await git(["config", "user.email", "github-weekly-reporter@users.noreply.github.com"], directory);
13
+ await git(["commit", "-m", message], directory);
14
+ await git(["push", repoUrl, "gh-pages", "--force"], directory);
15
+ };
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/deployer/index.ts"],"names":[],"mappings":"AAAA,wCAAwC;AAExC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAEjC,MAAM,GAAG,GAAG,CAAC,IAAc,EAAE,GAAW,EAAE,EAAE,CAC1C,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;AAQ7B,MAAM,CAAC,MAAM,MAAM,GAAG,KAAK,EAAE,OAAsB,EAAiB,EAAE;IACpE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,GAAG,QAAQ,EAAE,GAAG,OAAO,CAAC;IAE3D,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC;IAC/B,MAAM,GAAG,CAAC,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC,EAAE,SAAS,CAAC,CAAC;IAC3D,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC;IACnC,MAAM,GAAG,CAAC,CAAC,QAAQ,EAAE,WAAW,EAAE,wBAAwB,CAAC,EAAE,SAAS,CAAC,CAAC;IACxE,MAAM,GAAG,CAAC,CAAC,QAAQ,EAAE,YAAY,EAAE,iDAAiD,CAAC,EAAE,SAAS,CAAC,CAAC;IAClG,MAAM,GAAG,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,SAAS,CAAC,CAAC;IAChD,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE,SAAS,CAAC,CAAC;AACjE,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ export type WeekId = {
2
+ year: number;
3
+ week: number;
4
+ path: string;
5
+ };
6
+ export declare const getWeekId: (date?: Date) => WeekId;
7
+ //# sourceMappingURL=week.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"week.d.ts","sourceRoot":"","sources":["../../src/deployer/week.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,MAAM,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AASF,eAAO,MAAM,SAAS,GAAI,OAAM,IAAiB,KAAG,MAKnD,CAAC"}
@@ -0,0 +1,14 @@
1
+ // ISO week number calculation
2
+ const getISOWeekNumber = (date) => {
3
+ const d = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()));
4
+ d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay() || 7));
5
+ const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
6
+ return Math.ceil(((d.getTime() - yearStart.getTime()) / 86_400_000 + 1) / 7);
7
+ };
8
+ export const getWeekId = (date = new Date()) => {
9
+ const year = date.getUTCFullYear();
10
+ const week = getISOWeekNumber(date);
11
+ const padded = String(week).padStart(2, "0");
12
+ return { year, week, path: `${year}/W${padded}` };
13
+ };
14
+ //# sourceMappingURL=week.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"week.js","sourceRoot":"","sources":["../../src/deployer/week.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAQ9B,MAAM,gBAAgB,GAAG,CAAC,IAAU,EAAU,EAAE;IAC9C,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,IAAI,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IAC3F,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IACxD,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/D,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/E,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,OAAa,IAAI,IAAI,EAAE,EAAU,EAAE;IAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;IACnC,MAAM,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC7C,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,KAAK,MAAM,EAAE,EAAE,CAAC;AACpD,CAAC,CAAC"}