@knpkv/codecommit-core 0.5.0 → 0.6.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/dist/AwsClient/AwsClientGated.d.ts +27 -0
- package/dist/AwsClient/AwsClientGated.d.ts.map +1 -0
- package/dist/AwsClient/AwsClientGated.js +105 -0
- package/dist/AwsClient/AwsClientGated.js.map +1 -0
- package/dist/AwsClient/getDifferences.d.ts +16 -0
- package/dist/AwsClient/getDifferences.d.ts.map +1 -0
- package/dist/AwsClient/getDifferences.js +22 -0
- package/dist/AwsClient/getDifferences.js.map +1 -0
- package/dist/AwsClient/getPullRequest.d.ts.map +1 -1
- package/dist/AwsClient/getPullRequest.js +26 -5
- package/dist/AwsClient/getPullRequest.js.map +1 -1
- package/dist/AwsClient/getPullRequests.d.ts.map +1 -1
- package/dist/AwsClient/getPullRequests.js +29 -11
- package/dist/AwsClient/getPullRequests.js.map +1 -1
- package/dist/AwsClient/index.d.ts +21 -13
- package/dist/AwsClient/index.d.ts.map +1 -1
- package/dist/AwsClient/index.js +3 -1
- package/dist/AwsClient/index.js.map +1 -1
- package/dist/AwsClient/internal.d.ts +23 -0
- package/dist/AwsClient/internal.d.ts.map +1 -1
- package/dist/AwsClient/internal.js +4 -1
- package/dist/AwsClient/internal.js.map +1 -1
- package/dist/CacheService/Database.d.ts.map +1 -1
- package/dist/CacheService/Database.js +13 -1
- package/dist/CacheService/Database.js.map +1 -1
- package/dist/CacheService/EventsHub.d.ts +44 -4
- package/dist/CacheService/EventsHub.d.ts.map +1 -1
- package/dist/CacheService/EventsHub.js.map +1 -1
- package/dist/CacheService/index.d.ts +3 -2
- package/dist/CacheService/index.d.ts.map +1 -1
- package/dist/CacheService/index.js +2 -1
- package/dist/CacheService/index.js.map +1 -1
- package/dist/CacheService/migrations/0007_stats_columns.d.ts +5 -0
- package/dist/CacheService/migrations/0007_stats_columns.d.ts.map +1 -0
- package/dist/CacheService/migrations/0007_stats_columns.js +13 -0
- package/dist/CacheService/migrations/0007_stats_columns.js.map +1 -0
- package/dist/CacheService/migrations/0008_merged_by.d.ts +5 -0
- package/dist/CacheService/migrations/0008_merged_by.d.ts.map +1 -0
- package/dist/CacheService/migrations/0008_merged_by.js +4 -0
- package/dist/CacheService/migrations/0008_merged_by.js.map +1 -0
- package/dist/CacheService/migrations/0009_approved_by.d.ts +5 -0
- package/dist/CacheService/migrations/0009_approved_by.d.ts.map +1 -0
- package/dist/CacheService/migrations/0009_approved_by.js +4 -0
- package/dist/CacheService/migrations/0009_approved_by.js.map +1 -0
- package/dist/CacheService/migrations/0010_commented_by.d.ts +5 -0
- package/dist/CacheService/migrations/0010_commented_by.d.ts.map +1 -0
- package/dist/CacheService/migrations/0010_commented_by.js +4 -0
- package/dist/CacheService/migrations/0010_commented_by.js.map +1 -0
- package/dist/CacheService/migrations/0011_audit_log.d.ts +5 -0
- package/dist/CacheService/migrations/0011_audit_log.d.ts.map +1 -0
- package/dist/CacheService/migrations/0011_audit_log.js +19 -0
- package/dist/CacheService/migrations/0011_audit_log.js.map +1 -0
- package/dist/CacheService/migrations/0012_audit_log_indexes.d.ts +5 -0
- package/dist/CacheService/migrations/0012_audit_log_indexes.d.ts.map +1 -0
- package/dist/CacheService/migrations/0012_audit_log_indexes.js +7 -0
- package/dist/CacheService/migrations/0012_audit_log_indexes.js.map +1 -0
- package/dist/CacheService/repos/PullRequestRepo/index.d.ts +132 -0
- package/dist/CacheService/repos/PullRequestRepo/index.d.ts.map +1 -0
- package/dist/CacheService/repos/PullRequestRepo/index.js +35 -0
- package/dist/CacheService/repos/PullRequestRepo/index.js.map +1 -0
- package/dist/CacheService/repos/PullRequestRepo/internal.d.ts +72 -0
- package/dist/CacheService/repos/PullRequestRepo/internal.d.ts.map +1 -0
- package/dist/CacheService/repos/PullRequestRepo/internal.js +69 -0
- package/dist/CacheService/repos/PullRequestRepo/internal.js.map +1 -0
- package/dist/CacheService/repos/PullRequestRepo/mutations.d.ts +24 -0
- package/dist/CacheService/repos/PullRequestRepo/mutations.d.ts.map +1 -0
- package/dist/CacheService/repos/PullRequestRepo/mutations.js +94 -0
- package/dist/CacheService/repos/PullRequestRepo/mutations.js.map +1 -0
- package/dist/CacheService/repos/PullRequestRepo/queries.d.ts +113 -0
- package/dist/CacheService/repos/PullRequestRepo/queries.d.ts.map +1 -0
- package/dist/CacheService/repos/PullRequestRepo/queries.js +89 -0
- package/dist/CacheService/repos/PullRequestRepo/queries.js.map +1 -0
- package/dist/CacheService/repos/StatsRepo/index.d.ts +93 -0
- package/dist/CacheService/repos/StatsRepo/index.d.ts.map +1 -0
- package/dist/CacheService/repos/StatsRepo/index.js +41 -0
- package/dist/CacheService/repos/StatsRepo/index.js.map +1 -0
- package/dist/CacheService/repos/StatsRepo/internal.d.ts +120 -0
- package/dist/CacheService/repos/StatsRepo/internal.d.ts.map +1 -0
- package/dist/CacheService/repos/StatsRepo/internal.js +34 -0
- package/dist/CacheService/repos/StatsRepo/internal.js.map +1 -0
- package/dist/CacheService/repos/StatsRepo/queries.d.ts +42 -0
- package/dist/CacheService/repos/StatsRepo/queries.d.ts.map +1 -0
- package/dist/CacheService/repos/StatsRepo/queries.js +182 -0
- package/dist/CacheService/repos/StatsRepo/queries.js.map +1 -0
- package/dist/CacheService/repos/StatsRepo/reviewerData.d.ts +47 -0
- package/dist/CacheService/repos/StatsRepo/reviewerData.d.ts.map +1 -0
- package/dist/CacheService/repos/StatsRepo/reviewerData.js +172 -0
- package/dist/CacheService/repos/StatsRepo/reviewerData.js.map +1 -0
- package/dist/DateUtils.d.ts +28 -0
- package/dist/DateUtils.d.ts.map +1 -1
- package/dist/DateUtils.js +69 -1
- package/dist/DateUtils.js.map +1 -1
- package/dist/Domain.d.ts +13 -3
- package/dist/Domain.d.ts.map +1 -1
- package/dist/Domain.js +6 -5
- package/dist/Domain.js.map +1 -1
- package/dist/Errors.d.ts +14 -1
- package/dist/Errors.d.ts.map +1 -1
- package/dist/Errors.js +10 -0
- package/dist/Errors.js.map +1 -1
- package/dist/PRService/index.d.ts +3 -3
- package/dist/PRService/index.d.ts.map +1 -1
- package/dist/PRService/index.js +1 -1
- package/dist/PRService/index.js.map +1 -1
- package/dist/PRService/internal.d.ts +24 -2
- package/dist/PRService/internal.d.ts.map +1 -1
- package/dist/PRService/internal.js +23 -8
- package/dist/PRService/internal.js.map +1 -1
- package/dist/PRService/refresh.d.ts +1 -1
- package/dist/PRService/refresh.d.ts.map +1 -1
- package/dist/PRService/refresh.js +2 -0
- package/dist/PRService/refresh.js.map +1 -1
- package/dist/PRService/refreshDiffs.d.ts +16 -0
- package/dist/PRService/refreshDiffs.d.ts.map +1 -0
- package/dist/PRService/refreshDiffs.js +54 -0
- package/dist/PRService/refreshDiffs.js.map +1 -0
- package/dist/PRService/refreshEnrich.d.ts +1 -1
- package/dist/PRService/refreshEnrich.d.ts.map +1 -1
- package/dist/PRService/refreshEnrich.js +3 -1
- package/dist/PRService/refreshEnrich.js.map +1 -1
- package/dist/PRService/refreshFetch.d.ts +1 -1
- package/dist/PRService/refreshFetch.d.ts.map +1 -1
- package/dist/PRService/refreshFetch.js +12 -3
- package/dist/PRService/refreshFetch.js.map +1 -1
- package/dist/PRService/refreshHistory.d.ts +19 -0
- package/dist/PRService/refreshHistory.d.ts.map +1 -0
- package/dist/PRService/refreshHistory.js +110 -0
- package/dist/PRService/refreshHistory.js.map +1 -0
- package/dist/PRService/refreshResolve.d.ts +1 -1
- package/dist/PRService/refreshResolve.d.ts.map +1 -1
- package/dist/PRService/refreshResolve.js +1 -1
- package/dist/PRService/refreshResolve.js.map +1 -1
- package/dist/PRService/refreshScore.d.ts +1 -1
- package/dist/PRService/refreshScore.d.ts.map +1 -1
- package/dist/PRService/refreshScore.js +1 -1
- package/dist/PRService/refreshScore.js.map +1 -1
- package/dist/PRService/refreshSinglePR.d.ts +1 -1
- package/dist/PRService/refreshSinglePR.d.ts.map +1 -1
- package/dist/PRService/refreshSinglePR.js +4 -3
- package/dist/PRService/refreshSinglePR.js.map +1 -1
- package/dist/PermissionService/AuditLog.d.ts +62 -0
- package/dist/PermissionService/AuditLog.d.ts.map +1 -0
- package/dist/PermissionService/AuditLog.js +113 -0
- package/dist/PermissionService/AuditLog.js.map +1 -0
- package/dist/PermissionService/PermissionGate.d.ts +47 -0
- package/dist/PermissionService/PermissionGate.d.ts.map +1 -0
- package/dist/PermissionService/PermissionGate.js +14 -0
- package/dist/PermissionService/PermissionGate.js.map +1 -0
- package/dist/PermissionService/PermissionGateLive.d.ts +41 -0
- package/dist/PermissionService/PermissionGateLive.d.ts.map +1 -0
- package/dist/PermissionService/PermissionGateLive.js +83 -0
- package/dist/PermissionService/PermissionGateLive.js.map +1 -0
- package/dist/PermissionService/index.d.ts +39 -0
- package/dist/PermissionService/index.d.ts.map +1 -0
- package/dist/PermissionService/index.js +87 -0
- package/dist/PermissionService/index.js.map +1 -0
- package/dist/PermissionService/operations.d.ts +40 -0
- package/dist/PermissionService/operations.d.ts.map +1 -0
- package/dist/PermissionService/operations.js +38 -0
- package/dist/PermissionService/operations.js.map +1 -0
- package/dist/StatsService/WeeklyStats.d.ts +174 -0
- package/dist/StatsService/WeeklyStats.d.ts.map +1 -0
- package/dist/StatsService/WeeklyStats.js +110 -0
- package/dist/StatsService/WeeklyStats.js.map +1 -0
- package/dist/StatsService/index.d.ts +45 -0
- package/dist/StatsService/index.d.ts.map +1 -0
- package/dist/StatsService/index.js +145 -0
- package/dist/StatsService/index.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/CacheService/repos/PullRequestRepo.d.ts +0 -112
- package/dist/CacheService/repos/PullRequestRepo.d.ts.map +0 -1
- package/dist/CacheService/repos/PullRequestRepo.js +0 -146
- package/dist/CacheService/repos/PullRequestRepo.js.map +0 -1
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @title PermissionService — permission state management
|
|
3
|
+
*
|
|
4
|
+
* Ref<Config> backed by `~/.codecommit/permissions.json`.
|
|
5
|
+
*
|
|
6
|
+
* On construction (Layer build time), reads the file
|
|
7
|
+
* into a Ref. All subsequent `check()` calls are O(1) Ref lookups — no disk
|
|
8
|
+
* I/O. Only `set()` mutates the Ref AND writes to disk (atomic: tmp → rename).
|
|
9
|
+
*
|
|
10
|
+
* Key invariant: an operation missing from the file defaults to `"allow"`,
|
|
11
|
+
* which means "prompt the user". A fresh install with empty permissions.json
|
|
12
|
+
* prompts for every API call — zero-trust by default.
|
|
13
|
+
*
|
|
14
|
+
* @module
|
|
15
|
+
*/
|
|
16
|
+
import { FileSystem } from "@effect/platform";
|
|
17
|
+
import { Config, Effect, Ref, Schema } from "effect";
|
|
18
|
+
import { allOperations, getOperationMeta, registerOperation } from "./operations.js";
|
|
19
|
+
export { allOperations, getOperationMeta, registerOperation };
|
|
20
|
+
// On-disk format. Schema.decodeUnknownSync with defaults means
|
|
21
|
+
// corrupt or missing files gracefully degrade to empty state (everything prompts).
|
|
22
|
+
export const PermissionState = Schema.Literal("always_allow", "allow", "deny");
|
|
23
|
+
const AuditConfig = Schema.Struct({
|
|
24
|
+
enabled: Schema.Boolean.pipe(Schema.optionalWith({ default: () => true })),
|
|
25
|
+
retentionDays: Schema.Number.pipe(Schema.optionalWith({ default: () => 30 }))
|
|
26
|
+
});
|
|
27
|
+
const PermissionsConfig = Schema.Struct({
|
|
28
|
+
permissions: Schema.Record({ key: Schema.String, value: PermissionState }).pipe(Schema.optionalWith({ default: () => ({}) })),
|
|
29
|
+
audit: AuditConfig.pipe(Schema.optionalWith({ default: () => Schema.decodeSync(AuditConfig)({}) }))
|
|
30
|
+
});
|
|
31
|
+
const decodeConfig = Schema.decodeUnknownSync(PermissionsConfig);
|
|
32
|
+
// Uses @effect/platform FileSystem — works in Bun, Node, tests.
|
|
33
|
+
// Atomic write: write to .tmp, then rename. Prevents corruption on crash.
|
|
34
|
+
const resolvePermissionsPath = Config.string("HOME").pipe(Config.orElse(() => Config.string("USERPROFILE")), Config.map((h) => `${h}/.codecommit/permissions.json`));
|
|
35
|
+
const loadFromDisk = (fs, path) => fs.readFileString(path).pipe(Effect.map((content) => decodeConfig(JSON.parse(content))),
|
|
36
|
+
// Any failure → empty config → everything prompts
|
|
37
|
+
Effect.catchAll(() => Effect.succeed(decodeConfig({}))));
|
|
38
|
+
const saveToDisk = (fs, path, config) => Effect.gen(function* () {
|
|
39
|
+
const dir = path.replace(/\/[^/]+$/, "");
|
|
40
|
+
yield* fs.makeDirectory(dir, { recursive: true }).pipe(Effect.catchAll(() => Effect.void));
|
|
41
|
+
const tmpPath = `${path}.tmp`;
|
|
42
|
+
yield* fs.writeFileString(tmpPath, JSON.stringify(config, null, 2));
|
|
43
|
+
yield* fs.rename(tmpPath, path);
|
|
44
|
+
}).pipe(Effect.catchAll(() => Effect.void));
|
|
45
|
+
// Effect.Service (not Context.Tag) — auto-generates `.Default` layer.
|
|
46
|
+
// The effect block runs once at Layer construction: reads file, creates Ref.
|
|
47
|
+
// FileSystem comes from the providing layer (PlatformLive in Server.ts).
|
|
48
|
+
export class PermissionService extends Effect.Service()("PermissionService", {
|
|
49
|
+
effect: Effect.gen(function* () {
|
|
50
|
+
const fs = yield* FileSystem.FileSystem;
|
|
51
|
+
const permPath = yield* Effect.configProviderWith((p) => p.load(resolvePermissionsPath)).pipe(Effect.catchAll(() => Effect.succeed("/tmp/.codecommit/permissions.json")));
|
|
52
|
+
// In-memory state. All check() calls read from here.
|
|
53
|
+
// Only set() mutates it AND writes to disk.
|
|
54
|
+
const initial = yield* loadFromDisk(fs, permPath);
|
|
55
|
+
const configRef = yield* Ref.make(initial);
|
|
56
|
+
// O(1) — Ref.get + property lookup. The "allow" default is the key invariant:
|
|
57
|
+
// missing operation → prompt the user.
|
|
58
|
+
const check = (operation) => Ref.get(configRef).pipe(Effect.map((c) => c.permissions[operation] ?? "allow"));
|
|
59
|
+
const set = (operation, state) => Effect.gen(function* () {
|
|
60
|
+
yield* Ref.update(configRef, (c) => ({
|
|
61
|
+
...c,
|
|
62
|
+
permissions: { ...c.permissions, [operation]: state }
|
|
63
|
+
}));
|
|
64
|
+
yield* saveToDisk(fs, permPath, yield* Ref.get(configRef));
|
|
65
|
+
});
|
|
66
|
+
const getAll = () => Ref.get(configRef).pipe(Effect.map((c) => c.permissions));
|
|
67
|
+
const resetAll = () => Effect.gen(function* () {
|
|
68
|
+
yield* Ref.update(configRef, (c) => ({ ...c, permissions: {} }));
|
|
69
|
+
yield* saveToDisk(fs, permPath, yield* Ref.get(configRef));
|
|
70
|
+
});
|
|
71
|
+
const isAuditEnabled = () => Ref.get(configRef).pipe(Effect.map((c) => c.audit.enabled));
|
|
72
|
+
const getAuditRetention = () => Ref.get(configRef).pipe(Effect.map((c) => c.audit.retentionDays));
|
|
73
|
+
const setAudit = (opts) => Effect.gen(function* () {
|
|
74
|
+
yield* Ref.update(configRef, (c) => ({
|
|
75
|
+
...c,
|
|
76
|
+
audit: {
|
|
77
|
+
enabled: opts.enabled ?? c.audit.enabled,
|
|
78
|
+
retentionDays: opts.retentionDays ?? c.audit.retentionDays
|
|
79
|
+
}
|
|
80
|
+
}));
|
|
81
|
+
yield* saveToDisk(fs, permPath, yield* Ref.get(configRef));
|
|
82
|
+
});
|
|
83
|
+
return { check, set, getAll, resetAll, isAuditEnabled, getAuditRetention, setAudit };
|
|
84
|
+
})
|
|
85
|
+
}) {
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/PermissionService/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @title Operation registry — maps operation names to metadata
|
|
3
|
+
*
|
|
4
|
+
* Every AWS API call has a named operation with a category (read/write)
|
|
5
|
+
* and human-readable description. The gate uses the category for UI
|
|
6
|
+
* badge color; the description appears in the permission prompt modal.
|
|
7
|
+
*
|
|
8
|
+
* `OperationName` is a union of known builtin operations + `(string & {})`
|
|
9
|
+
* for runtime extensions. This gives autocomplete for known ops while
|
|
10
|
+
* allowing `registerOperation` to add new ones (e.g. approval rule CRUD).
|
|
11
|
+
*
|
|
12
|
+
* @internal
|
|
13
|
+
*/
|
|
14
|
+
export interface OperationMeta {
|
|
15
|
+
readonly category: "read" | "write";
|
|
16
|
+
readonly description: string;
|
|
17
|
+
}
|
|
18
|
+
declare const BuiltinOperations: {
|
|
19
|
+
readonly getCallerIdentity: OperationMeta;
|
|
20
|
+
readonly listRepositories: OperationMeta;
|
|
21
|
+
readonly listPullRequests: OperationMeta;
|
|
22
|
+
readonly getPullRequests: OperationMeta;
|
|
23
|
+
readonly getPullRequest: OperationMeta;
|
|
24
|
+
readonly evaluatePullRequestApprovalRules: OperationMeta;
|
|
25
|
+
readonly getPullRequestApprovalStates: OperationMeta;
|
|
26
|
+
readonly getMergeConflicts: OperationMeta;
|
|
27
|
+
readonly getCommentsForPullRequest: OperationMeta;
|
|
28
|
+
readonly listBranches: OperationMeta;
|
|
29
|
+
readonly getDifferences: OperationMeta;
|
|
30
|
+
readonly createPullRequest: OperationMeta;
|
|
31
|
+
readonly updatePullRequestTitle: OperationMeta;
|
|
32
|
+
readonly updatePullRequestDescription: OperationMeta;
|
|
33
|
+
};
|
|
34
|
+
export type BuiltinOperation = keyof typeof BuiltinOperations;
|
|
35
|
+
export type OperationName = BuiltinOperation | (string & {});
|
|
36
|
+
export declare const getOperationMeta: (name: OperationName) => OperationMeta;
|
|
37
|
+
export declare const allOperations: () => ReadonlyArray<readonly [string, OperationMeta]>;
|
|
38
|
+
export declare const registerOperation: (name: string, meta: OperationMeta) => void;
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=operations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operations.d.ts","sourceRoot":"","sources":["../../src/PermissionService/operations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAC7B;AAID,QAAA,MAAM,iBAAiB;;;;;;;;;;;;;;;CAe2B,CAAA;AAElD,MAAM,MAAM,gBAAgB,GAAG,MAAM,OAAO,iBAAiB,CAAA;AAG7D,MAAM,MAAM,aAAa,GAAG,gBAAgB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;AAM5D,eAAO,MAAM,gBAAgB,GAAI,MAAM,aAAa,KAAG,aAAuD,CAAA;AAE9G,eAAO,MAAM,aAAa,QAAO,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,aAAa,CAAC,CAA8B,CAAA;AAE7G,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,EAAE,MAAM,aAAa,KAAG,IAErE,CAAA"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @title Operation registry — maps operation names to metadata
|
|
3
|
+
*
|
|
4
|
+
* Every AWS API call has a named operation with a category (read/write)
|
|
5
|
+
* and human-readable description. The gate uses the category for UI
|
|
6
|
+
* badge color; the description appears in the permission prompt modal.
|
|
7
|
+
*
|
|
8
|
+
* `OperationName` is a union of known builtin operations + `(string & {})`
|
|
9
|
+
* for runtime extensions. This gives autocomplete for known ops while
|
|
10
|
+
* allowing `registerOperation` to add new ones (e.g. approval rule CRUD).
|
|
11
|
+
*
|
|
12
|
+
* @internal
|
|
13
|
+
*/
|
|
14
|
+
const op = (category, description) => ({ category, description });
|
|
15
|
+
const BuiltinOperations = {
|
|
16
|
+
getCallerIdentity: op("read", "Get current user identity"),
|
|
17
|
+
listRepositories: op("read", "List all repositories"),
|
|
18
|
+
listPullRequests: op("read", "List PR IDs for a repo"),
|
|
19
|
+
getPullRequests: op("read", "Fetch PR details"),
|
|
20
|
+
getPullRequest: op("read", "Single PR detail"),
|
|
21
|
+
evaluatePullRequestApprovalRules: op("read", "Check approval status"),
|
|
22
|
+
getPullRequestApprovalStates: op("read", "Get who approved"),
|
|
23
|
+
getMergeConflicts: op("read", "Check merge conflicts"),
|
|
24
|
+
getCommentsForPullRequest: op("read", "Fetch PR comments"),
|
|
25
|
+
listBranches: op("read", "List branches"),
|
|
26
|
+
getDifferences: op("read", "Diff stats"),
|
|
27
|
+
createPullRequest: op("write", "Create a pull request"),
|
|
28
|
+
updatePullRequestTitle: op("write", "Edit PR title"),
|
|
29
|
+
updatePullRequestDescription: op("write", "Edit PR description")
|
|
30
|
+
};
|
|
31
|
+
const operations = new Map(Object.entries(BuiltinOperations));
|
|
32
|
+
const fallback = (name) => ({ category: "read", description: name });
|
|
33
|
+
export const getOperationMeta = (name) => operations.get(name) ?? fallback(name);
|
|
34
|
+
export const allOperations = () => [...operations.entries()];
|
|
35
|
+
export const registerOperation = (name, meta) => {
|
|
36
|
+
operations.set(name, meta);
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=operations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operations.js","sourceRoot":"","sources":["../../src/PermissionService/operations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAOH,MAAM,EAAE,GAAG,CAAC,QAA0B,EAAE,WAAmB,EAAiB,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAA;AAE1G,MAAM,iBAAiB,GAAG;IACxB,iBAAiB,EAAE,EAAE,CAAC,MAAM,EAAE,2BAA2B,CAAC;IAC1D,gBAAgB,EAAE,EAAE,CAAC,MAAM,EAAE,uBAAuB,CAAC;IACrD,gBAAgB,EAAE,EAAE,CAAC,MAAM,EAAE,wBAAwB,CAAC;IACtD,eAAe,EAAE,EAAE,CAAC,MAAM,EAAE,kBAAkB,CAAC;IAC/C,cAAc,EAAE,EAAE,CAAC,MAAM,EAAE,kBAAkB,CAAC;IAC9C,gCAAgC,EAAE,EAAE,CAAC,MAAM,EAAE,uBAAuB,CAAC;IACrE,4BAA4B,EAAE,EAAE,CAAC,MAAM,EAAE,kBAAkB,CAAC;IAC5D,iBAAiB,EAAE,EAAE,CAAC,MAAM,EAAE,uBAAuB,CAAC;IACtD,yBAAyB,EAAE,EAAE,CAAC,MAAM,EAAE,mBAAmB,CAAC;IAC1D,YAAY,EAAE,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC;IACzC,cAAc,EAAE,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC;IACxC,iBAAiB,EAAE,EAAE,CAAC,OAAO,EAAE,uBAAuB,CAAC;IACvD,sBAAsB,EAAE,EAAE,CAAC,OAAO,EAAE,eAAe,CAAC;IACpD,4BAA4B,EAAE,EAAE,CAAC,OAAO,EAAE,qBAAqB,CAAC;CAChB,CAAA;AAOlD,MAAM,UAAU,GAAG,IAAI,GAAG,CAAwB,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAA;AAEpF,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAiB,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAA;AAE3F,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAmB,EAAiB,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAA;AAE9G,MAAM,CAAC,MAAM,aAAa,GAAG,GAAoD,EAAE,CAAC,CAAC,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,CAAA;AAE7G,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAE,IAAmB,EAAQ,EAAE;IAC3E,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;AAC5B,CAAC,CAAA"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module WeeklyStats
|
|
3
|
+
*
|
|
4
|
+
* Mental model: this is the **client-safe response schema** — the single
|
|
5
|
+
* contract between server-side stats computation and client-side rendering.
|
|
6
|
+
* It contains no server dependencies; only pure Schema definitions that both
|
|
7
|
+
* sides can import without pulling in AWS SDK or database code.
|
|
8
|
+
*
|
|
9
|
+
* - Pure `Schema.Struct` definition — serialisable to JSON automatically.
|
|
10
|
+
* - Sub-schemas are named consts; companion `declare namespace` exposes their
|
|
11
|
+
* types as `WeeklyStats.Contributor`, `WeeklyStats.ActivePR`, etc.
|
|
12
|
+
*
|
|
13
|
+
* @category Schema
|
|
14
|
+
*/
|
|
15
|
+
import { Schema } from "effect";
|
|
16
|
+
declare const Contributor: Schema.Struct<{
|
|
17
|
+
author: typeof Schema.String;
|
|
18
|
+
prCount: typeof Schema.Number;
|
|
19
|
+
}>;
|
|
20
|
+
declare const Reviewer: Schema.Struct<{
|
|
21
|
+
author: typeof Schema.String;
|
|
22
|
+
commentCount: typeof Schema.Number;
|
|
23
|
+
}>;
|
|
24
|
+
declare const Approver: Schema.Struct<{
|
|
25
|
+
author: typeof Schema.String;
|
|
26
|
+
approvalCount: typeof Schema.Number;
|
|
27
|
+
}>;
|
|
28
|
+
declare const ActivePR: Schema.Struct<{
|
|
29
|
+
id: typeof Schema.String;
|
|
30
|
+
title: typeof Schema.String;
|
|
31
|
+
author: typeof Schema.String;
|
|
32
|
+
repositoryName: typeof Schema.String;
|
|
33
|
+
commentCount: typeof Schema.Number;
|
|
34
|
+
awsAccountId: typeof Schema.String;
|
|
35
|
+
}>;
|
|
36
|
+
declare const SizeDistribution: Schema.Struct<{
|
|
37
|
+
small: typeof Schema.Number;
|
|
38
|
+
medium: typeof Schema.Number;
|
|
39
|
+
large: typeof Schema.Number;
|
|
40
|
+
extraLarge: typeof Schema.Number;
|
|
41
|
+
}>;
|
|
42
|
+
declare const DiffSize: Schema.Struct<{
|
|
43
|
+
filesAdded: typeof Schema.Number;
|
|
44
|
+
filesModified: typeof Schema.Number;
|
|
45
|
+
filesDeleted: typeof Schema.Number;
|
|
46
|
+
}>;
|
|
47
|
+
declare const DiffByContributor: Schema.Struct<{
|
|
48
|
+
author: typeof Schema.String;
|
|
49
|
+
avgFilesChanged: typeof Schema.Number;
|
|
50
|
+
prCount: typeof Schema.Number;
|
|
51
|
+
}>;
|
|
52
|
+
declare const StalePR: Schema.Struct<{
|
|
53
|
+
id: typeof Schema.String;
|
|
54
|
+
title: typeof Schema.String;
|
|
55
|
+
author: typeof Schema.String;
|
|
56
|
+
repositoryName: typeof Schema.String;
|
|
57
|
+
daysSinceActivity: typeof Schema.Number;
|
|
58
|
+
awsAccountId: typeof Schema.String;
|
|
59
|
+
}>;
|
|
60
|
+
declare const BusFactor: Schema.Struct<{
|
|
61
|
+
topContributorShare: typeof Schema.Number;
|
|
62
|
+
uniqueContributors: typeof Schema.Number;
|
|
63
|
+
}>;
|
|
64
|
+
export declare const WeeklyStats: Schema.Struct<{
|
|
65
|
+
week: typeof Schema.String;
|
|
66
|
+
weekStart: typeof Schema.String;
|
|
67
|
+
weekEnd: typeof Schema.String;
|
|
68
|
+
dataAvailableSince: Schema.NullOr<typeof Schema.String>;
|
|
69
|
+
prsCreated: typeof Schema.Number;
|
|
70
|
+
prsMerged: typeof Schema.Number;
|
|
71
|
+
prsClosed: typeof Schema.Number;
|
|
72
|
+
totalComments: typeof Schema.Number;
|
|
73
|
+
topContributors: Schema.Array$<Schema.Struct<{
|
|
74
|
+
author: typeof Schema.String;
|
|
75
|
+
prCount: typeof Schema.Number;
|
|
76
|
+
}>>;
|
|
77
|
+
topReviewers: Schema.Array$<Schema.Struct<{
|
|
78
|
+
author: typeof Schema.String;
|
|
79
|
+
commentCount: typeof Schema.Number;
|
|
80
|
+
}>>;
|
|
81
|
+
topApprovers: Schema.Array$<Schema.Struct<{
|
|
82
|
+
author: typeof Schema.String;
|
|
83
|
+
approvalCount: typeof Schema.Number;
|
|
84
|
+
}>>;
|
|
85
|
+
medianTimeToMerge: Schema.NullOr<typeof Schema.Number>;
|
|
86
|
+
medianTimeToFirstReview: Schema.NullOr<typeof Schema.Number>;
|
|
87
|
+
medianTimeToAddressFeedback: Schema.NullOr<typeof Schema.Number>;
|
|
88
|
+
mergeTimeDetails: Schema.Array$<Schema.Struct<{
|
|
89
|
+
prId: typeof Schema.String;
|
|
90
|
+
prTitle: typeof Schema.String;
|
|
91
|
+
author: typeof Schema.String;
|
|
92
|
+
repositoryName: typeof Schema.String;
|
|
93
|
+
awsAccountId: typeof Schema.String;
|
|
94
|
+
durationMs: typeof Schema.Number;
|
|
95
|
+
fromLabel: typeof Schema.String;
|
|
96
|
+
toLabel: typeof Schema.String;
|
|
97
|
+
}>>;
|
|
98
|
+
firstReviewDetails: Schema.Array$<Schema.Struct<{
|
|
99
|
+
prId: typeof Schema.String;
|
|
100
|
+
prTitle: typeof Schema.String;
|
|
101
|
+
author: typeof Schema.String;
|
|
102
|
+
repositoryName: typeof Schema.String;
|
|
103
|
+
awsAccountId: typeof Schema.String;
|
|
104
|
+
durationMs: typeof Schema.Number;
|
|
105
|
+
fromLabel: typeof Schema.String;
|
|
106
|
+
toLabel: typeof Schema.String;
|
|
107
|
+
}>>;
|
|
108
|
+
feedbackDetails: Schema.Array$<Schema.Struct<{
|
|
109
|
+
prId: typeof Schema.String;
|
|
110
|
+
prTitle: typeof Schema.String;
|
|
111
|
+
author: typeof Schema.String;
|
|
112
|
+
repositoryName: typeof Schema.String;
|
|
113
|
+
awsAccountId: typeof Schema.String;
|
|
114
|
+
durationMs: typeof Schema.Number;
|
|
115
|
+
fromLabel: typeof Schema.String;
|
|
116
|
+
toLabel: typeof Schema.String;
|
|
117
|
+
}>>;
|
|
118
|
+
mostActivePRs: Schema.Array$<Schema.Struct<{
|
|
119
|
+
id: typeof Schema.String;
|
|
120
|
+
title: typeof Schema.String;
|
|
121
|
+
author: typeof Schema.String;
|
|
122
|
+
repositoryName: typeof Schema.String;
|
|
123
|
+
commentCount: typeof Schema.Number;
|
|
124
|
+
awsAccountId: typeof Schema.String;
|
|
125
|
+
}>>;
|
|
126
|
+
prSizeDistribution: Schema.Struct<{
|
|
127
|
+
small: typeof Schema.Number;
|
|
128
|
+
medium: typeof Schema.Number;
|
|
129
|
+
large: typeof Schema.Number;
|
|
130
|
+
extraLarge: typeof Schema.Number;
|
|
131
|
+
}>;
|
|
132
|
+
avgDiffSize: Schema.NullOr<Schema.Struct<{
|
|
133
|
+
filesAdded: typeof Schema.Number;
|
|
134
|
+
filesModified: typeof Schema.Number;
|
|
135
|
+
filesDeleted: typeof Schema.Number;
|
|
136
|
+
}>>;
|
|
137
|
+
diffSizeByContributor: Schema.Array$<Schema.Struct<{
|
|
138
|
+
author: typeof Schema.String;
|
|
139
|
+
avgFilesChanged: typeof Schema.Number;
|
|
140
|
+
prCount: typeof Schema.Number;
|
|
141
|
+
}>>;
|
|
142
|
+
stalePRs: Schema.Array$<Schema.Struct<{
|
|
143
|
+
id: typeof Schema.String;
|
|
144
|
+
title: typeof Schema.String;
|
|
145
|
+
author: typeof Schema.String;
|
|
146
|
+
repositoryName: typeof Schema.String;
|
|
147
|
+
daysSinceActivity: typeof Schema.Number;
|
|
148
|
+
awsAccountId: typeof Schema.String;
|
|
149
|
+
}>>;
|
|
150
|
+
reviewCoverage: Schema.NullOr<typeof Schema.Number>;
|
|
151
|
+
approvalRate: Schema.NullOr<typeof Schema.Number>;
|
|
152
|
+
busFactor: Schema.NullOr<Schema.Struct<{
|
|
153
|
+
topContributorShare: typeof Schema.Number;
|
|
154
|
+
uniqueContributors: typeof Schema.Number;
|
|
155
|
+
}>>;
|
|
156
|
+
availableRepos: Schema.Array$<typeof Schema.String>;
|
|
157
|
+
availableAuthors: Schema.Array$<typeof Schema.String>;
|
|
158
|
+
availableAccounts: Schema.Array$<typeof Schema.String>;
|
|
159
|
+
}>;
|
|
160
|
+
export type WeeklyStats = typeof WeeklyStats.Type;
|
|
161
|
+
export declare namespace WeeklyStats {
|
|
162
|
+
/** @category models */
|
|
163
|
+
type Contributor = typeof Contributor.Type;
|
|
164
|
+
type Reviewer = typeof Reviewer.Type;
|
|
165
|
+
type Approver = typeof Approver.Type;
|
|
166
|
+
type ActivePR = typeof ActivePR.Type;
|
|
167
|
+
type SizeDistribution = typeof SizeDistribution.Type;
|
|
168
|
+
type DiffSize = typeof DiffSize.Type;
|
|
169
|
+
type DiffByContributor = typeof DiffByContributor.Type;
|
|
170
|
+
type StalePR = typeof StalePR.Type;
|
|
171
|
+
type BusFactor = typeof BusFactor.Type;
|
|
172
|
+
}
|
|
173
|
+
export {};
|
|
174
|
+
//# sourceMappingURL=WeeklyStats.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WeeklyStats.d.ts","sourceRoot":"","sources":["../../src/StatsService/WeeklyStats.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAM/B,QAAA,MAAM,WAAW;;;EAGf,CAAA;AAEF,QAAA,MAAM,QAAQ;;;EAGZ,CAAA;AAEF,QAAA,MAAM,QAAQ;;;EAGZ,CAAA;AAEF,QAAA,MAAM,QAAQ;;;;;;;EAOZ,CAAA;AAEF,QAAA,MAAM,gBAAgB;;;;;EAKpB,CAAA;AAEF,QAAA,MAAM,QAAQ;;;;EAIZ,CAAA;AAEF,QAAA,MAAM,iBAAiB;;;;EAIrB,CAAA;AAEF,QAAA,MAAM,OAAO;;;;;;;EAOX,CAAA;AAEF,QAAA,MAAM,SAAS;;;EAGb,CAAA;AAiBF,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoCtB,CAAA;AAEF,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAC,IAAI,CAAA;AAMjD,MAAM,CAAC,OAAO,WAAW,WAAW,CAAC;IACnC,uBAAuB;IACvB,KAAY,WAAW,GAAG,OAAO,WAAW,CAAC,IAAI,CAAA;IACjD,KAAY,QAAQ,GAAG,OAAO,QAAQ,CAAC,IAAI,CAAA;IAC3C,KAAY,QAAQ,GAAG,OAAO,QAAQ,CAAC,IAAI,CAAA;IAC3C,KAAY,QAAQ,GAAG,OAAO,QAAQ,CAAC,IAAI,CAAA;IAC3C,KAAY,gBAAgB,GAAG,OAAO,gBAAgB,CAAC,IAAI,CAAA;IAC3D,KAAY,QAAQ,GAAG,OAAO,QAAQ,CAAC,IAAI,CAAA;IAC3C,KAAY,iBAAiB,GAAG,OAAO,iBAAiB,CAAC,IAAI,CAAA;IAC7D,KAAY,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAA;IACzC,KAAY,SAAS,GAAG,OAAO,SAAS,CAAC,IAAI,CAAA;CAC9C"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module WeeklyStats
|
|
3
|
+
*
|
|
4
|
+
* Mental model: this is the **client-safe response schema** — the single
|
|
5
|
+
* contract between server-side stats computation and client-side rendering.
|
|
6
|
+
* It contains no server dependencies; only pure Schema definitions that both
|
|
7
|
+
* sides can import without pulling in AWS SDK or database code.
|
|
8
|
+
*
|
|
9
|
+
* - Pure `Schema.Struct` definition — serialisable to JSON automatically.
|
|
10
|
+
* - Sub-schemas are named consts; companion `declare namespace` exposes their
|
|
11
|
+
* types as `WeeklyStats.Contributor`, `WeeklyStats.ActivePR`, etc.
|
|
12
|
+
*
|
|
13
|
+
* @category Schema
|
|
14
|
+
*/
|
|
15
|
+
import { Schema } from "effect";
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Sub-schemas
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
const Contributor = Schema.Struct({
|
|
20
|
+
author: Schema.String,
|
|
21
|
+
prCount: Schema.Number
|
|
22
|
+
});
|
|
23
|
+
const Reviewer = Schema.Struct({
|
|
24
|
+
author: Schema.String,
|
|
25
|
+
commentCount: Schema.Number
|
|
26
|
+
});
|
|
27
|
+
const Approver = Schema.Struct({
|
|
28
|
+
author: Schema.String,
|
|
29
|
+
approvalCount: Schema.Number
|
|
30
|
+
});
|
|
31
|
+
const ActivePR = Schema.Struct({
|
|
32
|
+
id: Schema.String,
|
|
33
|
+
title: Schema.String,
|
|
34
|
+
author: Schema.String,
|
|
35
|
+
repositoryName: Schema.String,
|
|
36
|
+
commentCount: Schema.Number,
|
|
37
|
+
awsAccountId: Schema.String
|
|
38
|
+
});
|
|
39
|
+
const SizeDistribution = Schema.Struct({
|
|
40
|
+
small: Schema.Number,
|
|
41
|
+
medium: Schema.Number,
|
|
42
|
+
large: Schema.Number,
|
|
43
|
+
extraLarge: Schema.Number
|
|
44
|
+
});
|
|
45
|
+
const DiffSize = Schema.Struct({
|
|
46
|
+
filesAdded: Schema.Number,
|
|
47
|
+
filesModified: Schema.Number,
|
|
48
|
+
filesDeleted: Schema.Number
|
|
49
|
+
});
|
|
50
|
+
const DiffByContributor = Schema.Struct({
|
|
51
|
+
author: Schema.String,
|
|
52
|
+
avgFilesChanged: Schema.Number,
|
|
53
|
+
prCount: Schema.Number
|
|
54
|
+
});
|
|
55
|
+
const StalePR = Schema.Struct({
|
|
56
|
+
id: Schema.String,
|
|
57
|
+
title: Schema.String,
|
|
58
|
+
author: Schema.String,
|
|
59
|
+
repositoryName: Schema.String,
|
|
60
|
+
daysSinceActivity: Schema.Number,
|
|
61
|
+
awsAccountId: Schema.String
|
|
62
|
+
});
|
|
63
|
+
const BusFactor = Schema.Struct({
|
|
64
|
+
topContributorShare: Schema.Number,
|
|
65
|
+
uniqueContributors: Schema.Number
|
|
66
|
+
});
|
|
67
|
+
const LifecycleDetail = Schema.Struct({
|
|
68
|
+
prId: Schema.String,
|
|
69
|
+
prTitle: Schema.String,
|
|
70
|
+
author: Schema.String,
|
|
71
|
+
repositoryName: Schema.String,
|
|
72
|
+
awsAccountId: Schema.String,
|
|
73
|
+
durationMs: Schema.Number,
|
|
74
|
+
fromLabel: Schema.String,
|
|
75
|
+
toLabel: Schema.String
|
|
76
|
+
});
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
// Main schema
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
export const WeeklyStats = Schema.Struct({
|
|
81
|
+
week: Schema.String,
|
|
82
|
+
weekStart: Schema.String,
|
|
83
|
+
weekEnd: Schema.String,
|
|
84
|
+
dataAvailableSince: Schema.NullOr(Schema.String),
|
|
85
|
+
prsCreated: Schema.Number,
|
|
86
|
+
prsMerged: Schema.Number,
|
|
87
|
+
prsClosed: Schema.Number,
|
|
88
|
+
totalComments: Schema.Number,
|
|
89
|
+
topContributors: Schema.Array(Contributor),
|
|
90
|
+
topReviewers: Schema.Array(Reviewer),
|
|
91
|
+
topApprovers: Schema.Array(Approver),
|
|
92
|
+
medianTimeToMerge: Schema.NullOr(Schema.Number),
|
|
93
|
+
medianTimeToFirstReview: Schema.NullOr(Schema.Number),
|
|
94
|
+
medianTimeToAddressFeedback: Schema.NullOr(Schema.Number),
|
|
95
|
+
mergeTimeDetails: Schema.Array(LifecycleDetail),
|
|
96
|
+
firstReviewDetails: Schema.Array(LifecycleDetail),
|
|
97
|
+
feedbackDetails: Schema.Array(LifecycleDetail),
|
|
98
|
+
mostActivePRs: Schema.Array(ActivePR),
|
|
99
|
+
prSizeDistribution: SizeDistribution,
|
|
100
|
+
avgDiffSize: Schema.NullOr(DiffSize),
|
|
101
|
+
diffSizeByContributor: Schema.Array(DiffByContributor),
|
|
102
|
+
stalePRs: Schema.Array(StalePR),
|
|
103
|
+
reviewCoverage: Schema.NullOr(Schema.Number),
|
|
104
|
+
approvalRate: Schema.NullOr(Schema.Number),
|
|
105
|
+
busFactor: Schema.NullOr(BusFactor),
|
|
106
|
+
availableRepos: Schema.Array(Schema.String),
|
|
107
|
+
availableAuthors: Schema.Array(Schema.String),
|
|
108
|
+
availableAccounts: Schema.Array(Schema.String)
|
|
109
|
+
});
|
|
110
|
+
//# sourceMappingURL=WeeklyStats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WeeklyStats.js","sourceRoot":"","sources":["../../src/StatsService/WeeklyStats.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module StatsService
|
|
3
|
+
*
|
|
4
|
+
* Mental model: this is an **orchestration layer** — it doesn't own data,
|
|
5
|
+
* it assembles a `WeeklyStats` view-model by fanning out to StatsRepo
|
|
6
|
+
* queries and reviewer analysis in parallel, then shaping the results for
|
|
7
|
+
* the client.
|
|
8
|
+
*
|
|
9
|
+
* - All repo queries run with `{ concurrency: "unbounded" }` for max throughput.
|
|
10
|
+
* - `getWeeklyStats` is a read path; `syncWeek` is a write path that back-fills
|
|
11
|
+
* historical PR data into the cache.
|
|
12
|
+
* - A `catchAll` fallback returns an empty `WeeklyStats` so the UI always gets
|
|
13
|
+
* a valid response, even when the cache is cold.
|
|
14
|
+
*
|
|
15
|
+
* @category Service
|
|
16
|
+
*/
|
|
17
|
+
import { Effect, type SubscriptionRef } from "effect";
|
|
18
|
+
import { AwsClient } from "../AwsClient/index.js";
|
|
19
|
+
import { PullRequestRepo } from "../CacheService/repos/PullRequestRepo/index.js";
|
|
20
|
+
import { StatsRepo } from "../CacheService/repos/StatsRepo/index.js";
|
|
21
|
+
import { ConfigService } from "../ConfigService/index.js";
|
|
22
|
+
import type { AppState } from "../Domain.js";
|
|
23
|
+
import type { WeeklyStats as _WeeklyStats } from "./WeeklyStats.js";
|
|
24
|
+
export { WeeklyStats } from "./WeeklyStats.js";
|
|
25
|
+
type WeeklyStats = _WeeklyStats;
|
|
26
|
+
declare const StatsService_base: Effect.Service.Class<StatsService, "@knpkv/codecommit-core/StatsService", {
|
|
27
|
+
readonly effect: Effect.Effect<{
|
|
28
|
+
readonly getWeeklyStats: (week: string, filters: StatsRepo.Filters) => Effect.Effect<WeeklyStats>;
|
|
29
|
+
readonly syncWeek: (week: string, state: SubscriptionRef.SubscriptionRef<AppState>) => Effect.Effect<void>;
|
|
30
|
+
readonly currentWeek: () => string;
|
|
31
|
+
}, never, AwsClient | PullRequestRepo | StatsRepo | ConfigService>;
|
|
32
|
+
}>;
|
|
33
|
+
export declare class StatsService extends StatsService_base {
|
|
34
|
+
}
|
|
35
|
+
export declare namespace StatsService {
|
|
36
|
+
/**
|
|
37
|
+
* @category models
|
|
38
|
+
*/
|
|
39
|
+
interface Service {
|
|
40
|
+
readonly getWeeklyStats: (week: string, filters: StatsRepo.Filters) => Effect.Effect<WeeklyStats>;
|
|
41
|
+
readonly syncWeek: (week: string, state: SubscriptionRef.SubscriptionRef<AppState>) => Effect.Effect<void>;
|
|
42
|
+
readonly currentWeek: () => string;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/StatsService/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAQ,MAAM,EAAiB,KAAK,eAAe,EAAE,MAAM,QAAQ,CAAA;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,gDAAgD,CAAA;AAChF,OAAO,EAAE,SAAS,EAAE,MAAM,0CAA0C,CAAA;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAEzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAE5C,OAAO,KAAK,EAAE,WAAW,IAAI,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAEnE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,KAAK,WAAW,GAAG,YAAY,CAAA;;;wCA8GF,MAAM,WAAW,SAAS,CAAC,OAAO,KAAG,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC;kCAuCrE,MAAM,SAAS,eAAe,CAAC,eAAe,CAAC,QAAQ,CAAC,KAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;;;;AA3IrG,qBAAa,YAAa,SAAQ,iBAiJhC;CAAG;AAEL,MAAM,CAAC,OAAO,WAAW,YAAY,CAAC;IACpC;;OAEG;IACH,UAAiB,OAAO;QACtB,QAAQ,CAAC,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;QACjG,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,CAAC,eAAe,CAAC,QAAQ,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAC1G,QAAQ,CAAC,WAAW,EAAE,MAAM,MAAM,CAAA;KACnC;CACF"}
|