@knpkv/codecommit-core 0.5.1 → 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.
Files changed (47) hide show
  1. package/dist/AwsClient/AwsClientGated.d.ts +27 -0
  2. package/dist/AwsClient/AwsClientGated.d.ts.map +1 -0
  3. package/dist/AwsClient/AwsClientGated.js +105 -0
  4. package/dist/AwsClient/AwsClientGated.js.map +1 -0
  5. package/dist/CacheService/Database.d.ts.map +1 -1
  6. package/dist/CacheService/Database.js +5 -1
  7. package/dist/CacheService/Database.js.map +1 -1
  8. package/dist/CacheService/EventsHub.d.ts +44 -4
  9. package/dist/CacheService/EventsHub.d.ts.map +1 -1
  10. package/dist/CacheService/EventsHub.js.map +1 -1
  11. package/dist/CacheService/migrations/0011_audit_log.d.ts +5 -0
  12. package/dist/CacheService/migrations/0011_audit_log.d.ts.map +1 -0
  13. package/dist/CacheService/migrations/0011_audit_log.js +19 -0
  14. package/dist/CacheService/migrations/0011_audit_log.js.map +1 -0
  15. package/dist/CacheService/migrations/0012_audit_log_indexes.d.ts +5 -0
  16. package/dist/CacheService/migrations/0012_audit_log_indexes.d.ts.map +1 -0
  17. package/dist/CacheService/migrations/0012_audit_log_indexes.js +7 -0
  18. package/dist/CacheService/migrations/0012_audit_log_indexes.js.map +1 -0
  19. package/dist/Errors.d.ts +14 -1
  20. package/dist/Errors.d.ts.map +1 -1
  21. package/dist/Errors.js +10 -0
  22. package/dist/Errors.js.map +1 -1
  23. package/dist/PermissionService/AuditLog.d.ts +62 -0
  24. package/dist/PermissionService/AuditLog.d.ts.map +1 -0
  25. package/dist/PermissionService/AuditLog.js +113 -0
  26. package/dist/PermissionService/AuditLog.js.map +1 -0
  27. package/dist/PermissionService/PermissionGate.d.ts +47 -0
  28. package/dist/PermissionService/PermissionGate.d.ts.map +1 -0
  29. package/dist/PermissionService/PermissionGate.js +14 -0
  30. package/dist/PermissionService/PermissionGate.js.map +1 -0
  31. package/dist/PermissionService/PermissionGateLive.d.ts +41 -0
  32. package/dist/PermissionService/PermissionGateLive.d.ts.map +1 -0
  33. package/dist/PermissionService/PermissionGateLive.js +83 -0
  34. package/dist/PermissionService/PermissionGateLive.js.map +1 -0
  35. package/dist/PermissionService/index.d.ts +39 -0
  36. package/dist/PermissionService/index.d.ts.map +1 -0
  37. package/dist/PermissionService/index.js +87 -0
  38. package/dist/PermissionService/index.js.map +1 -0
  39. package/dist/PermissionService/operations.d.ts +40 -0
  40. package/dist/PermissionService/operations.d.ts.map +1 -0
  41. package/dist/PermissionService/operations.js +38 -0
  42. package/dist/PermissionService/operations.js.map +1 -0
  43. package/dist/index.d.ts +1 -0
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js +1 -0
  46. package/dist/index.js.map +1 -1
  47. package/package.json +1 -1
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @title AwsClientGated — transparent permission proxy
3
+ *
4
+ * Wraps every AwsClient method with permission check + audit logging.
5
+ * Returns the same `AwsClient.Service` type — callers don't know it exists.
6
+ *
7
+ * Two patterns:
8
+ * 1. InnerAwsClient tag — holds the real implementation, avoids circular dep
9
+ * 2. Service capture at Layer construction — all services yielded once,
10
+ * closed over in gate/wrapEffect/wrapStream, no R leakage
11
+ *
12
+ * PermissionDeniedError → AwsApiError at the boundary for type transparency.
13
+ * The actual PermissionDeniedError is preserved as the AwsApiError's `cause`.
14
+ *
15
+ * @module
16
+ */
17
+ import { Context, Layer } from "effect";
18
+ import { AuditLogRepo } from "../PermissionService/AuditLog.js";
19
+ import { PermissionService } from "../PermissionService/index.js";
20
+ import { PermissionGate } from "../PermissionService/PermissionGate.js";
21
+ import { AwsClient } from "./index.js";
22
+ declare const InnerAwsClient_base: Context.TagClass<InnerAwsClient, "@knpkv/codecommit-core/InnerAwsClient", AwsClient.Service>;
23
+ export declare class InnerAwsClient extends InnerAwsClient_base {
24
+ }
25
+ export declare const AwsClientGatedLive: Layer.Layer<AwsClient, never, InnerAwsClient | PermissionService | PermissionGate | AuditLogRepo>;
26
+ export {};
27
+ //# sourceMappingURL=AwsClientGated.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AwsClientGated.d.ts","sourceRoot":"","sources":["../../src/AwsClient/AwsClientGated.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,OAAO,EAAU,KAAK,EAAiB,MAAM,QAAQ,CAAA;AAG9D,OAAO,EAAE,YAAY,EAAyB,MAAM,kCAAkC,CAAA;AACtF,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAA;AAEjE,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAA;AACvE,OAAO,EAAE,SAAS,EAAuB,MAAM,YAAY,CAAA;;AAG3D,qBAAa,cAAe,SAAQ,mBAGjC;CAAG;AAiBN,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,KAAK,CAC1C,SAAS,EACT,KAAK,EACL,cAAc,GAAG,iBAAiB,GAAG,cAAc,GAAG,YAAY,CAmKnE,CAAA"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * @title AwsClientGated — transparent permission proxy
3
+ *
4
+ * Wraps every AwsClient method with permission check + audit logging.
5
+ * Returns the same `AwsClient.Service` type — callers don't know it exists.
6
+ *
7
+ * Two patterns:
8
+ * 1. InnerAwsClient tag — holds the real implementation, avoids circular dep
9
+ * 2. Service capture at Layer construction — all services yielded once,
10
+ * closed over in gate/wrapEffect/wrapStream, no R leakage
11
+ *
12
+ * PermissionDeniedError → AwsApiError at the boundary for type transparency.
13
+ * The actual PermissionDeniedError is preserved as the AwsApiError's `cause`.
14
+ *
15
+ * @module
16
+ */
17
+ import { Context, Effect, Layer, Match, Stream } from "effect";
18
+ import { AwsApiError, PermissionDeniedError } from "../Errors.js";
19
+ import { AuditLogRepo } from "../PermissionService/AuditLog.js";
20
+ import { PermissionService } from "../PermissionService/index.js";
21
+ import { getOperationMeta } from "../PermissionService/operations.js";
22
+ import { PermissionGate } from "../PermissionService/PermissionGate.js";
23
+ import { AwsClient } from "./index.js";
24
+ // Layer composition: AwsClientLive → InnerAwsClient (rename) → AwsClientGated → AwsClient
25
+ export class InnerAwsClient extends Context.Tag("@knpkv/codecommit-core/InnerAwsClient")() {
26
+ }
27
+ const toDeniedError = (p, reason) => new AwsApiError({
28
+ operation: p.operation,
29
+ profile: p.accountProfile,
30
+ region: p.region,
31
+ cause: new PermissionDeniedError({ operation: p.operation, reason })
32
+ });
33
+ export const AwsClientGatedLive = Layer.effect(AwsClient, Effect.gen(function* () {
34
+ const inner = yield* InnerAwsClient;
35
+ const permService = yield* PermissionService;
36
+ const gateService = yield* PermissionGate;
37
+ const auditLog = yield* AuditLogRepo;
38
+ // --- Core gate logic (captured services, no R leakage) ---
39
+ // Reads auditEnabled dynamically from Ref on each call —
40
+ // toggling audit in settings takes effect without restart
41
+ const logAudit = (params, permissionState, durationMs) => permService.isAuditEnabled().pipe(Effect.flatMap((enabled) => enabled
42
+ ? auditLog.log({
43
+ timestamp: new Date().toISOString(),
44
+ operation: params.operation,
45
+ accountProfile: params.accountProfile,
46
+ region: params.region,
47
+ permissionState,
48
+ context: params.context,
49
+ durationMs
50
+ })
51
+ : Effect.void), Effect.catchAll(() => Effect.void));
52
+ const promptUser = (params) => Effect.gen(function* () {
53
+ const meta = getOperationMeta(params.operation);
54
+ const response = yield* gateService.request({
55
+ id: globalThis.crypto.randomUUID(),
56
+ operation: params.operation,
57
+ category: meta.category,
58
+ context: params.context
59
+ }).pipe(Effect.mapError(() => toDeniedError(params, "timeout")));
60
+ return yield* Match.value(response).pipe(Match.when("always_allow", () => permService.set(params.operation, "always_allow").pipe(Effect.as("always_allowed"))), Match.when("deny", () => Effect.gen(function* () {
61
+ yield* permService.set(params.operation, "deny");
62
+ yield* logAudit(params, "denied", null);
63
+ return yield* toDeniedError(params, "denied");
64
+ })), Match.when("allow_once", () => Effect.succeed("allowed")), Match.exhaustive);
65
+ });
66
+ const checkPermission = (params) => Effect.gen(function* () {
67
+ const state = yield* permService.check(params.operation);
68
+ return yield* Match.value(state).pipe(Match.when("always_allow", () => Effect.succeed("always_allowed")), Match.when("deny", () => logAudit(params, "denied", null).pipe(Effect.zipRight(toDeniedError(params, "denied")))), Match.when("allow", () => promptUser(params)), Match.exhaustive);
69
+ });
70
+ // --- Declarative wrapping: gated(op, ctx, acct, method) → wrapped method ---
71
+ // P inferred from `method` (last arg) — `acct` and `ctx` just extract strings
72
+ const gated = (op, ctx, acct, method) => (params) => {
73
+ const a = acct(params);
74
+ const g = { operation: op, context: ctx(params), accountProfile: a.profile, region: a.region };
75
+ return Effect.gen(function* () {
76
+ const ps = yield* checkPermission(g);
77
+ const start = Date.now();
78
+ const result = yield* method(params);
79
+ yield* logAudit(g, ps, Date.now() - start);
80
+ return result;
81
+ });
82
+ };
83
+ const gatedStream = (op, ctx, acct, method) => (params) => {
84
+ const a = acct(params);
85
+ const g = { operation: op, context: ctx(params), accountProfile: a.profile, region: a.region };
86
+ return Stream.unwrap(checkPermission(g).pipe(Effect.map((ps) => {
87
+ const start = Date.now();
88
+ return method(params).pipe(Stream.onDone(() => logAudit(g, ps, Date.now() - start)));
89
+ })));
90
+ };
91
+ const self = (a) => a;
92
+ const nested = (p) => p.account;
93
+ return {
94
+ getPullRequests: gatedStream("getPullRequests", (a) => `List PRs for ${a.profile}`, self, (a) => inner.getPullRequests(a)),
95
+ getCallerIdentity: gated("getCallerIdentity", (a) => `Get identity for ${a.profile}`, self, inner.getCallerIdentity),
96
+ createPullRequest: gated("createPullRequest", (p) => `Create PR on ${p.repositoryName}`, nested, inner.createPullRequest),
97
+ listBranches: gated("listBranches", (p) => `List branches in ${p.repositoryName}`, nested, inner.listBranches),
98
+ getCommentsForPullRequest: gated("getCommentsForPullRequest", (p) => `Comments for PR #${p.pullRequestId}`, nested, inner.getCommentsForPullRequest),
99
+ updatePullRequestTitle: gated("updatePullRequestTitle", (p) => `Edit title of PR #${p.pullRequestId}`, nested, inner.updatePullRequestTitle),
100
+ updatePullRequestDescription: gated("updatePullRequestDescription", (p) => `Edit desc of PR #${p.pullRequestId}`, nested, inner.updatePullRequestDescription),
101
+ getPullRequest: gated("getPullRequest", (p) => `Fetch PR #${p.pullRequestId}`, nested, inner.getPullRequest),
102
+ getDifferences: gated("getDifferences", (p) => `Diff for ${p.repositoryName}`, nested, inner.getDifferences)
103
+ };
104
+ }));
105
+ //# sourceMappingURL=AwsClientGated.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AwsClientGated.js","sourceRoot":"","sources":["../../src/AwsClient/AwsClientGated.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Database.d.ts","sourceRoot":"","sources":["../../src/CacheService/Database.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,KAAK,YAAY,MAAM,iCAAiC,CAAA;AAC/D,OAAO,KAAK,cAAc,MAAM,mCAAmC,CAAA;AACnE,OAAO,EAAkB,KAAK,EAAE,MAAM,QAAQ,CAAA;AA4B9C,eAAO,MAAM,UAAU,qJAMW,CAAA;AAElC,eAAO,MAAM,cAAc,wIAazB,CAAA;AAEF,eAAO,MAAM,YAAY,+NAAsD,CAAA"}
1
+ {"version":3,"file":"Database.d.ts","sourceRoot":"","sources":["../../src/CacheService/Database.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,KAAK,YAAY,MAAM,iCAAiC,CAAA;AAC/D,OAAO,KAAK,cAAc,MAAM,mCAAmC,CAAA;AACnE,OAAO,EAAkB,KAAK,EAAE,MAAM,QAAQ,CAAA;AA8B9C,eAAO,MAAM,UAAU,qJAMW,CAAA;AAElC,eAAO,MAAM,cAAc,wIAezB,CAAA;AAEF,eAAO,MAAM,YAAY,+NAAsD,CAAA"}
@@ -17,6 +17,8 @@ import migration0007 from "./migrations/0007_stats_columns.js";
17
17
  import migration0008 from "./migrations/0008_merged_by.js";
18
18
  import migration0009 from "./migrations/0009_approved_by.js";
19
19
  import migration0010 from "./migrations/0010_commented_by.js";
20
+ import migration0011 from "./migrations/0011_audit_log.js";
21
+ import migration0012 from "./migrations/0012_audit_log_indexes.js";
20
22
  const homeDir = Config.string("HOME").pipe(Config.orElse(() => Config.string("USERPROFILE")));
21
23
  const dbUrl = homeDir.pipe(Config.map((h) => `file:${h}/.codecommit/cache.db`));
22
24
  const EnsureDbDir = Layer.effectDiscard(Effect.gen(function* () {
@@ -39,7 +41,9 @@ export const MigrationsLive = LibsqlMigrator.layer({
39
41
  "0007_stats_columns": migration0007,
40
42
  "0008_merged_by": migration0008,
41
43
  "0009_approved_by": migration0009,
42
- "0010_commented_by": migration0010
44
+ "0010_commented_by": migration0010,
45
+ "0011_audit_log": migration0011,
46
+ "0012_audit_log_indexes": migration0012
43
47
  })
44
48
  });
45
49
  export const DatabaseLive = MigrationsLive.pipe(Layer.provideMerge(LibsqlLive));
@@ -1 +1 @@
1
- {"version":3,"file":"Database.js","sourceRoot":"","sources":["../../src/CacheService/Database.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,KAAK,YAAY,MAAM,iCAAiC,CAAA;AAC/D,OAAO,KAAK,cAAc,MAAM,mCAAmC,CAAA;AACnE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC9C,OAAO,aAAa,MAAM,8BAA8B,CAAA;AACxD,OAAO,aAAa,MAAM,8BAA8B,CAAA;AACxD,OAAO,aAAa,MAAM,uCAAuC,CAAA;AACjE,OAAO,aAAa,MAAM,0CAA0C,CAAA;AACpE,OAAO,aAAa,MAAM,oCAAoC,CAAA;AAC9D,OAAO,aAAa,MAAM,mCAAmC,CAAA;AAC7D,OAAO,aAAa,MAAM,oCAAoC,CAAA;AAC9D,OAAO,aAAa,MAAM,gCAAgC,CAAA;AAC1D,OAAO,aAAa,MAAM,kCAAkC,CAAA;AAC5D,OAAO,aAAa,MAAM,mCAAmC,CAAA;AAE7D,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CACxC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAClD,CAAA;AAED,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC,CAAC,CAAA;AAE/E,MAAM,WAAW,GAAG,KAAK,CAAC,aAAa,CACrC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,UAAU,CAAA;IACvC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,OAAO,CAAA;IACxB,KAAK,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACnE,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CACnC,CAAA;AACH,CAAC,CAAC,CACH,CAAA;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,CAAC,YAAY,CAC1C,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE,CACxB,YAAY,CAAC,KAAK,CAAC;IACjB,GAAG;IACH,oBAAoB,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;CAC/F,CAAC,CAAC,CACN,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAA;AAElC,MAAM,CAAC,MAAM,cAAc,GAAG,cAAc,CAAC,KAAK,CAAC;IACjD,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC;QAChC,cAAc,EAAE,aAAa;QAC7B,cAAc,EAAE,aAAa;QAC7B,uBAAuB,EAAE,aAAa;QACtC,0BAA0B,EAAE,aAAa;QACzC,oBAAoB,EAAE,aAAa;QACnC,mBAAmB,EAAE,aAAa;QAClC,oBAAoB,EAAE,aAAa;QACnC,gBAAgB,EAAE,aAAa;QAC/B,kBAAkB,EAAE,aAAa;QACjC,mBAAmB,EAAE,aAAa;KACnC,CAAC;CACH,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"Database.js","sourceRoot":"","sources":["../../src/CacheService/Database.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,8 @@ export type RepoChange = Data.TaggedEnum<{
8
8
  AppState: {};
9
9
  SystemNotifications: {};
10
10
  Sandboxes: {};
11
+ PermissionRequired: {};
12
+ PermissionResolved: {};
11
13
  }>;
12
14
  export declare const RepoChange: {
13
15
  readonly Comments: Data.Case.Constructor<{
@@ -34,7 +36,13 @@ export declare const RepoChange: {
34
36
  readonly Sandboxes: Data.Case.Constructor<{
35
37
  readonly _tag: "Sandboxes";
36
38
  }, "_tag">;
37
- readonly $is: <Tag extends "Comments" | "PullRequests" | "Notifications" | "Subscriptions" | "Config" | "AppState" | "SystemNotifications" | "Sandboxes">(tag: Tag) => (u: unknown) => u is Extract<{
39
+ readonly PermissionRequired: Data.Case.Constructor<{
40
+ readonly _tag: "PermissionRequired";
41
+ }, "_tag">;
42
+ readonly PermissionResolved: Data.Case.Constructor<{
43
+ readonly _tag: "PermissionResolved";
44
+ }, "_tag">;
45
+ readonly $is: <Tag extends "Comments" | "PullRequests" | "Notifications" | "Subscriptions" | "Config" | "AppState" | "SystemNotifications" | "Sandboxes" | "PermissionRequired" | "PermissionResolved">(tag: Tag) => (u: unknown) => u is Extract<{
38
46
  readonly _tag: "Comments";
39
47
  }, {
40
48
  readonly _tag: Tag;
@@ -66,6 +74,14 @@ export declare const RepoChange: {
66
74
  readonly _tag: "Sandboxes";
67
75
  }, {
68
76
  readonly _tag: Tag;
77
+ }> | Extract<{
78
+ readonly _tag: "PermissionRequired";
79
+ }, {
80
+ readonly _tag: Tag;
81
+ }> | Extract<{
82
+ readonly _tag: "PermissionResolved";
83
+ }, {
84
+ readonly _tag: Tag;
69
85
  }>;
70
86
  readonly $match: {
71
87
  <const Cases extends {
@@ -93,7 +109,13 @@ export declare const RepoChange: {
93
109
  readonly Sandboxes: (args: {
94
110
  readonly _tag: "Sandboxes";
95
111
  }) => any;
96
- }>(cases: Cases & { [K in Exclude<keyof Cases, "Comments" | "PullRequests" | "Notifications" | "Subscriptions" | "Config" | "AppState" | "SystemNotifications" | "Sandboxes">]: never; }): (value: {
112
+ readonly PermissionRequired: (args: {
113
+ readonly _tag: "PermissionRequired";
114
+ }) => any;
115
+ readonly PermissionResolved: (args: {
116
+ readonly _tag: "PermissionResolved";
117
+ }) => any;
118
+ }>(cases: Cases & { [K in Exclude<keyof Cases, "Comments" | "PullRequests" | "Notifications" | "Subscriptions" | "Config" | "AppState" | "SystemNotifications" | "Sandboxes" | "PermissionRequired" | "PermissionResolved">]: never; }): (value: {
97
119
  readonly _tag: "Comments";
98
120
  } | {
99
121
  readonly _tag: "PullRequests";
@@ -109,7 +131,11 @@ export declare const RepoChange: {
109
131
  readonly _tag: "SystemNotifications";
110
132
  } | {
111
133
  readonly _tag: "Sandboxes";
112
- }) => import("effect/Unify").Unify<ReturnType<Cases["Comments" | "PullRequests" | "Notifications" | "Subscriptions" | "Config" | "AppState" | "SystemNotifications" | "Sandboxes"]>>;
134
+ } | {
135
+ readonly _tag: "PermissionRequired";
136
+ } | {
137
+ readonly _tag: "PermissionResolved";
138
+ }) => import("effect/Unify").Unify<ReturnType<Cases["Comments" | "PullRequests" | "Notifications" | "Subscriptions" | "Config" | "AppState" | "SystemNotifications" | "Sandboxes" | "PermissionRequired" | "PermissionResolved"]>>;
113
139
  <const Cases extends {
114
140
  readonly Comments: (args: {
115
141
  readonly _tag: "Comments";
@@ -135,6 +161,12 @@ export declare const RepoChange: {
135
161
  readonly Sandboxes: (args: {
136
162
  readonly _tag: "Sandboxes";
137
163
  }) => any;
164
+ readonly PermissionRequired: (args: {
165
+ readonly _tag: "PermissionRequired";
166
+ }) => any;
167
+ readonly PermissionResolved: (args: {
168
+ readonly _tag: "PermissionResolved";
169
+ }) => any;
138
170
  }>(value: {
139
171
  readonly _tag: "Comments";
140
172
  } | {
@@ -151,7 +183,11 @@ export declare const RepoChange: {
151
183
  readonly _tag: "SystemNotifications";
152
184
  } | {
153
185
  readonly _tag: "Sandboxes";
154
- }, cases: Cases & { [K in Exclude<keyof Cases, "Comments" | "PullRequests" | "Notifications" | "Subscriptions" | "Config" | "AppState" | "SystemNotifications" | "Sandboxes">]: never; }): import("effect/Unify").Unify<ReturnType<Cases["Comments" | "PullRequests" | "Notifications" | "Subscriptions" | "Config" | "AppState" | "SystemNotifications" | "Sandboxes"]>>;
186
+ } | {
187
+ readonly _tag: "PermissionRequired";
188
+ } | {
189
+ readonly _tag: "PermissionResolved";
190
+ }, cases: Cases & { [K in Exclude<keyof Cases, "Comments" | "PullRequests" | "Notifications" | "Subscriptions" | "Config" | "AppState" | "SystemNotifications" | "Sandboxes" | "PermissionRequired" | "PermissionResolved">]: never; }): import("effect/Unify").Unify<ReturnType<Cases["Comments" | "PullRequests" | "Notifications" | "Subscriptions" | "Config" | "AppState" | "SystemNotifications" | "Sandboxes" | "PermissionRequired" | "PermissionResolved"]>>;
155
191
  };
156
192
  };
157
193
  declare const EventsHub_base: Effect.Service.Class<EventsHub, "EventsHub", {
@@ -174,6 +210,10 @@ declare const EventsHub_base: Effect.Service.Class<EventsHub, "EventsHub", {
174
210
  readonly _tag: "SystemNotifications";
175
211
  } | {
176
212
  readonly _tag: "Sandboxes";
213
+ } | {
214
+ readonly _tag: "PermissionRequired";
215
+ } | {
216
+ readonly _tag: "PermissionResolved";
177
217
  }, never, never>;
178
218
  }, never, never>;
179
219
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"EventsHub.d.ts","sourceRoot":"","sources":["../../src/CacheService/EventsHub.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAe,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE1D,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;IACvC,YAAY,EAAE,EAAE,CAAA;IAChB,aAAa,EAAE,EAAE,CAAA;IACjB,aAAa,EAAE,EAAE,CAAA;IACjB,QAAQ,EAAE,EAAE,CAAA;IACZ,MAAM,EAAE,EAAE,CAAA;IACV,QAAQ,EAAE,EAAE,CAAA;IACZ,mBAAmB,EAAE,EAAE,CAAA;IACvB,SAAS,EAAE,EAAE,CAAA;CACd,CAAC,CAAA;AAEF,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAgC,CAAA;;;0BAS1B,UAAU,KAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;gBAS1C,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;AAhBnF,qBAAa,SAAU,SAAQ,cAyC7B;CAAG"}
1
+ {"version":3,"file":"EventsHub.d.ts","sourceRoot":"","sources":["../../src/CacheService/EventsHub.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAe,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE1D,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;IACvC,YAAY,EAAE,EAAE,CAAA;IAChB,aAAa,EAAE,EAAE,CAAA;IACjB,aAAa,EAAE,EAAE,CAAA;IACjB,QAAQ,EAAE,EAAE,CAAA;IACZ,MAAM,EAAE,EAAE,CAAA;IACV,QAAQ,EAAE,EAAE,CAAA;IACZ,mBAAmB,EAAE,EAAE,CAAA;IACvB,SAAS,EAAE,EAAE,CAAA;IACb,kBAAkB,EAAE,EAAE,CAAA;IACtB,kBAAkB,EAAE,EAAE,CAAA;CACvB,CAAC,CAAA;AAEF,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAgC,CAAA;;;0BAS1B,UAAU,KAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;gBAS1C,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;AAhBnF,qBAAa,SAAU,SAAQ,cAyC7B;CAAG"}
@@ -1 +1 @@
1
- {"version":3,"file":"EventsHub.js","sourceRoot":"","sources":["../../src/CacheService/EventsHub.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAa1D,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAc,CAAA;AAEvD,MAAM,OAAO,SAAU,SAAQ,MAAM,CAAC,OAAO,EAAa,CAAC,WAAW,EAAE;IACtE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC1B,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,SAAS,EAAc,CAAA;QACpD,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAC1C,MAAM,cAAc,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,EAAsB,CAAC,CAAA;QACrE,MAAM,cAAc,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAA;QAErD,MAAM,OAAO,GAAG,CAAC,MAAkB,EAAuB,EAAE,CAC1D,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CACvB,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC1B,QAAQ;YACN,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAChE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CACvD,CACF,CAAA;QAEH,MAAM,KAAK,GAAG,CAAU,MAA8B,EAA0B,EAAE,CAChF,cAAc,CAAC,WAAW,CAAC,CAAC,CAAC,CAC3B,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,IAAI,CAC7B,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,GAAG,EAAsB,CAAC,CAAC,EACvE,MAAM,CAAC,QAAQ,CACb,MAAM,CAAC,QAAQ,CACb,MAAM,EACN,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;YAC3C,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;YAClC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CACnB,CAAC,GAAG,IAAI,CAAC,EACT,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,EAClD,EAAE,OAAO,EAAE,IAAI,EAAE,CAClB,CAAA;QACH,CAAC,CAAC,CACH,CACF,CACF,CACF,CAAA;QAEH,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;QAE3C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAA;IACtC,CAAC,CAAC;CACH,CAAC;CAAG"}
1
+ {"version":3,"file":"EventsHub.js","sourceRoot":"","sources":["../../src/CacheService/EventsHub.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAe1D,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAc,CAAA;AAEvD,MAAM,OAAO,SAAU,SAAQ,MAAM,CAAC,OAAO,EAAa,CAAC,WAAW,EAAE;IACtE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC1B,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,SAAS,EAAc,CAAA;QACpD,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAC1C,MAAM,cAAc,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,EAAsB,CAAC,CAAA;QACrE,MAAM,cAAc,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAA;QAErD,MAAM,OAAO,GAAG,CAAC,MAAkB,EAAuB,EAAE,CAC1D,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CACvB,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC1B,QAAQ;YACN,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAChE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CACvD,CACF,CAAA;QAEH,MAAM,KAAK,GAAG,CAAU,MAA8B,EAA0B,EAAE,CAChF,cAAc,CAAC,WAAW,CAAC,CAAC,CAAC,CAC3B,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,IAAI,CAC7B,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,GAAG,EAAsB,CAAC,CAAC,EACvE,MAAM,CAAC,QAAQ,CACb,MAAM,CAAC,QAAQ,CACb,MAAM,EACN,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;YAC3C,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;YAClC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CACnB,CAAC,GAAG,IAAI,CAAC,EACT,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,EAClD,EAAE,OAAO,EAAE,IAAI,EAAE,CAClB,CAAA;QACH,CAAC,CAAC,CACH,CACF,CACF,CACF,CAAA;QAEH,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;QAE3C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAA;IACtC,CAAC,CAAC;CACH,CAAC;CAAG"}
@@ -0,0 +1,5 @@
1
+ import * as SqlClient from "@effect/sql/SqlClient";
2
+ import * as Effect from "effect/Effect";
3
+ declare const _default: Effect.Effect<void, never, SqlClient.SqlClient>;
4
+ export default _default;
5
+ //# sourceMappingURL=0011_audit_log.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"0011_audit_log.d.ts","sourceRoot":"","sources":["../../../src/CacheService/migrations/0011_audit_log.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,uBAAuB,CAAA;AAClD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;;AAEvC,wBAmBC"}
@@ -0,0 +1,19 @@
1
+ import * as SqlClient from "@effect/sql/SqlClient";
2
+ import * as Effect from "effect/Effect";
3
+ export default Effect.flatMap(SqlClient.SqlClient, (sql) => Effect.all([
4
+ sql `CREATE TABLE IF NOT EXISTS audit_log (
5
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
6
+ timestamp TEXT NOT NULL DEFAULT (datetime('now')),
7
+ operation TEXT NOT NULL,
8
+ account_profile TEXT NOT NULL DEFAULT '',
9
+ region TEXT NOT NULL DEFAULT '',
10
+ permission_state TEXT NOT NULL,
11
+ context TEXT NOT NULL DEFAULT '',
12
+ duration_ms INTEGER
13
+ )`,
14
+ sql `CREATE INDEX IF NOT EXISTS idx_audit_log_timestamp ON audit_log(timestamp)`,
15
+ sql `CREATE INDEX IF NOT EXISTS idx_audit_log_operation ON audit_log(operation)`,
16
+ sql `CREATE INDEX IF NOT EXISTS idx_audit_log_permission_state ON audit_log(permission_state)`,
17
+ sql `CREATE INDEX IF NOT EXISTS idx_audit_log_account_profile ON audit_log(account_profile)`
18
+ ]).pipe(Effect.asVoid, Effect.catchAll(() => Effect.void)));
19
+ //# sourceMappingURL=0011_audit_log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"0011_audit_log.js","sourceRoot":"","sources":["../../../src/CacheService/migrations/0011_audit_log.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,uBAAuB,CAAA;AAClD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,eAAe,MAAM,CAAC,OAAO,CAC3B,SAAS,CAAC,SAAS,EACnB,CAAC,GAAG,EAAE,EAAE,CACN,MAAM,CAAC,GAAG,CAAC;IACT,GAAG,CAAA;;;;;;;;;QASD;IACF,GAAG,CAAA,4EAA4E;IAC/E,GAAG,CAAA,4EAA4E;IAC/E,GAAG,CAAA,0FAA0F;IAC7F,GAAG,CAAA,wFAAwF;CAC5F,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAC7D,CAAA"}
@@ -0,0 +1,5 @@
1
+ import * as SqlClient from "@effect/sql/SqlClient";
2
+ import * as Effect from "effect/Effect";
3
+ declare const _default: Effect.Effect<void, never, SqlClient.SqlClient>;
4
+ export default _default;
5
+ //# sourceMappingURL=0012_audit_log_indexes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"0012_audit_log_indexes.d.ts","sourceRoot":"","sources":["../../../src/CacheService/migrations/0012_audit_log_indexes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,uBAAuB,CAAA;AAClD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;;AAEvC,wBAOC"}
@@ -0,0 +1,7 @@
1
+ import * as SqlClient from "@effect/sql/SqlClient";
2
+ import * as Effect from "effect/Effect";
3
+ export default Effect.flatMap(SqlClient.SqlClient, (sql) => Effect.all([
4
+ sql `CREATE INDEX IF NOT EXISTS idx_audit_log_permission_state ON audit_log(permission_state)`,
5
+ sql `CREATE INDEX IF NOT EXISTS idx_audit_log_account_profile ON audit_log(account_profile)`
6
+ ]).pipe(Effect.asVoid, Effect.catchAll(() => Effect.void)));
7
+ //# sourceMappingURL=0012_audit_log_indexes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"0012_audit_log_indexes.js","sourceRoot":"","sources":["../../../src/CacheService/migrations/0012_audit_log_indexes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,uBAAuB,CAAA;AAClD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,eAAe,MAAM,CAAC,OAAO,CAC3B,SAAS,CAAC,SAAS,EACnB,CAAC,GAAG,EAAE,EAAE,CACN,MAAM,CAAC,GAAG,CAAC;IACT,GAAG,CAAA,0FAA0F;IAC7F,GAAG,CAAA,wFAAwF;CAC5F,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAC7D,CAAA"}
package/dist/Errors.d.ts CHANGED
@@ -146,6 +146,19 @@ declare const SandboxError_base: Schema.TaggedErrorClass<SandboxError, "SandboxE
146
146
  */
147
147
  export declare class SandboxError extends SandboxError_base {
148
148
  }
149
+ declare const PermissionDeniedError_base: Schema.TaggedErrorClass<PermissionDeniedError, "PermissionDeniedError", {
150
+ readonly _tag: Schema.tag<"PermissionDeniedError">;
151
+ } & {
152
+ operation: typeof Schema.String;
153
+ reason: Schema.Literal<["denied", "timeout"]>;
154
+ }>;
155
+ /**
156
+ * API call blocked by permission gate.
157
+ *
158
+ * @category Errors
159
+ */
160
+ export declare class PermissionDeniedError extends PermissionDeniedError_base {
161
+ }
149
162
  /**
150
163
  * Union of errors from AwsClient methods.
151
164
  *
@@ -157,6 +170,6 @@ export type AwsClientError = AwsCredentialError | AwsThrottleError | AwsApiError
157
170
  *
158
171
  * @category Errors
159
172
  */
160
- export type CodeCommitError = AwsCredentialError | AwsThrottleError | AwsApiError | ConfigError | ConfigParseError | ProfileDetectionError | RefreshError | DockerError | SandboxError;
173
+ export type CodeCommitError = AwsCredentialError | AwsThrottleError | AwsApiError | ConfigError | ConfigParseError | ProfileDetectionError | RefreshError | DockerError | SandboxError | PermissionDeniedError;
161
174
  export {};
162
175
  //# sourceMappingURL=Errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Errors.d.ts","sourceRoot":"","sources":["../src/Errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;;;;;;;;AAG/B;;;;GAIG;AACH,qBAAa,kBAAmB,SAAQ,uBAOvC;CAAG;;;;;;;;AAEJ;;;;GAIG;AACH,qBAAa,gBAAiB,SAAQ,qBAOrC;CAAG;;;;;;;;;AAEJ;;;;GAIG;AACH,qBAAa,WAAY,SAAQ,gBAQhC;CAAG;;;;;;;AAEJ;;;;GAIG;AACH,qBAAa,WAAY,SAAQ,gBAMhC;CAAG;;;;;;;AAEJ;;;;GAIG;AACH,qBAAa,gBAAiB,SAAQ,qBAMrC;CAAG;;;;;;;AAEJ;;;;GAIG;AACH,qBAAa,qBAAsB,SAAQ,0BAM1C;CAAG;;;;;;;AAEJ;;;;GAIG;AACH,qBAAa,YAAa,SAAQ,iBAMjC;CAAG;;;;;;;AAEJ;;;;GAIG;AACH,qBAAa,WAAY,SAAQ,gBAMhC;CAAG;;;;;;;;AAEJ;;;;GAIG;AACH,qBAAa,YAAa,SAAQ,iBAOjC;CAAG;AAEJ;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,kBAAkB,GAAG,gBAAgB,GAAG,WAAW,CAAA;AAEhF;;;;GAIG;AACH,MAAM,MAAM,eAAe,GACvB,kBAAkB,GAClB,gBAAgB,GAChB,WAAW,GACX,WAAW,GACX,gBAAgB,GAChB,qBAAqB,GACrB,YAAY,GACZ,WAAW,GACX,YAAY,CAAA"}
1
+ {"version":3,"file":"Errors.d.ts","sourceRoot":"","sources":["../src/Errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;;;;;;;;AAG/B;;;;GAIG;AACH,qBAAa,kBAAmB,SAAQ,uBAOvC;CAAG;;;;;;;;AAEJ;;;;GAIG;AACH,qBAAa,gBAAiB,SAAQ,qBAOrC;CAAG;;;;;;;;;AAEJ;;;;GAIG;AACH,qBAAa,WAAY,SAAQ,gBAQhC;CAAG;;;;;;;AAEJ;;;;GAIG;AACH,qBAAa,WAAY,SAAQ,gBAMhC;CAAG;;;;;;;AAEJ;;;;GAIG;AACH,qBAAa,gBAAiB,SAAQ,qBAMrC;CAAG;;;;;;;AAEJ;;;;GAIG;AACH,qBAAa,qBAAsB,SAAQ,0BAM1C;CAAG;;;;;;;AAEJ;;;;GAIG;AACH,qBAAa,YAAa,SAAQ,iBAMjC;CAAG;;;;;;;AAEJ;;;;GAIG;AACH,qBAAa,WAAY,SAAQ,gBAMhC;CAAG;;;;;;;;AAEJ;;;;GAIG;AACH,qBAAa,YAAa,SAAQ,iBAOjC;CAAG;;;;;;;AAEJ;;;;GAIG;AACH,qBAAa,qBAAsB,SAAQ,0BAM1C;CAAG;AAEJ;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,kBAAkB,GAAG,gBAAgB,GAAG,WAAW,CAAA;AAEhF;;;;GAIG;AACH,MAAM,MAAM,eAAe,GACvB,kBAAkB,GAClB,gBAAgB,GAChB,WAAW,GACX,WAAW,GACX,gBAAgB,GAChB,qBAAqB,GACrB,YAAY,GACZ,WAAW,GACX,YAAY,GACZ,qBAAqB,CAAA"}
package/dist/Errors.js CHANGED
@@ -120,4 +120,14 @@ export class SandboxError extends Schema.TaggedError()("SandboxError", {
120
120
  cause: Schema.optional(Schema.Defect)
121
121
  }) {
122
122
  }
123
+ /**
124
+ * API call blocked by permission gate.
125
+ *
126
+ * @category Errors
127
+ */
128
+ export class PermissionDeniedError extends Schema.TaggedError()("PermissionDeniedError", {
129
+ operation: Schema.String,
130
+ reason: Schema.Literal("denied", "timeout")
131
+ }) {
132
+ }
123
133
  //# sourceMappingURL=Errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Errors.js","sourceRoot":"","sources":["../src/Errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/B,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAElE;;;;GAIG;AACH,MAAM,OAAO,kBAAmB,SAAQ,MAAM,CAAC,WAAW,EAAsB,CAC9E,oBAAoB,EACpB;IACE,OAAO,EAAE,cAAc;IACvB,MAAM,EAAE,SAAS;IACjB,KAAK,EAAE,MAAM,CAAC,MAAM;CACrB,CACF;CAAG;AAEJ;;;;GAIG;AACH,MAAM,OAAO,gBAAiB,SAAQ,MAAM,CAAC,WAAW,EAAoB,CAC1E,kBAAkB,EAClB;IACE,SAAS,EAAE,MAAM,CAAC,MAAM;IACxB,UAAU,EAAE,MAAM,CAAC,MAAM;IACzB,KAAK,EAAE,MAAM,CAAC,MAAM;CACrB,CACF;CAAG;AAEJ;;;;GAIG;AACH,MAAM,OAAO,WAAY,SAAQ,MAAM,CAAC,WAAW,EAAe,CAChE,aAAa,EACb;IACE,SAAS,EAAE,MAAM,CAAC,MAAM;IACxB,OAAO,EAAE,cAAc;IACvB,MAAM,EAAE,SAAS;IACjB,KAAK,EAAE,MAAM,CAAC,MAAM;CACrB,CACF;CAAG;AAEJ;;;;GAIG;AACH,MAAM,OAAO,WAAY,SAAQ,MAAM,CAAC,WAAW,EAAe,CAChE,aAAa,EACb;IACE,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;CACtC,CACF;CAAG;AAEJ;;;;GAIG;AACH,MAAM,OAAO,gBAAiB,SAAQ,MAAM,CAAC,WAAW,EAAoB,CAC1E,kBAAkB,EAClB;IACE,IAAI,EAAE,MAAM,CAAC,MAAM;IACnB,KAAK,EAAE,MAAM,CAAC,MAAM;CACrB,CACF;CAAG;AAEJ;;;;GAIG;AACH,MAAM,OAAO,qBAAsB,SAAQ,MAAM,CAAC,WAAW,EAAyB,CACpF,uBAAuB,EACvB;IACE,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;CACtC,CACF;CAAG;AAEJ;;;;GAIG;AACH,MAAM,OAAO,YAAa,SAAQ,MAAM,CAAC,WAAW,EAAgB,CAClE,cAAc,EACd;IACE,cAAc,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;IAC3C,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;CACtC,CACF;CAAG;AAEJ;;;;GAIG;AACH,MAAM,OAAO,WAAY,SAAQ,MAAM,CAAC,WAAW,EAAe,CAChE,aAAa,EACb;IACE,SAAS,EAAE,MAAM,CAAC,MAAM;IACxB,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;CACtC,CACF;CAAG;AAEJ;;;;GAIG;AACH,MAAM,OAAO,YAAa,SAAQ,MAAM,CAAC,WAAW,EAAgB,CAClE,cAAc,EACd;IACE,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC;IACrC,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;CACtC,CACF;CAAG"}
1
+ {"version":3,"file":"Errors.js","sourceRoot":"","sources":["../src/Errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/B,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAElE;;;;GAIG;AACH,MAAM,OAAO,kBAAmB,SAAQ,MAAM,CAAC,WAAW,EAAsB,CAC9E,oBAAoB,EACpB;IACE,OAAO,EAAE,cAAc;IACvB,MAAM,EAAE,SAAS;IACjB,KAAK,EAAE,MAAM,CAAC,MAAM;CACrB,CACF;CAAG;AAEJ;;;;GAIG;AACH,MAAM,OAAO,gBAAiB,SAAQ,MAAM,CAAC,WAAW,EAAoB,CAC1E,kBAAkB,EAClB;IACE,SAAS,EAAE,MAAM,CAAC,MAAM;IACxB,UAAU,EAAE,MAAM,CAAC,MAAM;IACzB,KAAK,EAAE,MAAM,CAAC,MAAM;CACrB,CACF;CAAG;AAEJ;;;;GAIG;AACH,MAAM,OAAO,WAAY,SAAQ,MAAM,CAAC,WAAW,EAAe,CAChE,aAAa,EACb;IACE,SAAS,EAAE,MAAM,CAAC,MAAM;IACxB,OAAO,EAAE,cAAc;IACvB,MAAM,EAAE,SAAS;IACjB,KAAK,EAAE,MAAM,CAAC,MAAM;CACrB,CACF;CAAG;AAEJ;;;;GAIG;AACH,MAAM,OAAO,WAAY,SAAQ,MAAM,CAAC,WAAW,EAAe,CAChE,aAAa,EACb;IACE,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;CACtC,CACF;CAAG;AAEJ;;;;GAIG;AACH,MAAM,OAAO,gBAAiB,SAAQ,MAAM,CAAC,WAAW,EAAoB,CAC1E,kBAAkB,EAClB;IACE,IAAI,EAAE,MAAM,CAAC,MAAM;IACnB,KAAK,EAAE,MAAM,CAAC,MAAM;CACrB,CACF;CAAG;AAEJ;;;;GAIG;AACH,MAAM,OAAO,qBAAsB,SAAQ,MAAM,CAAC,WAAW,EAAyB,CACpF,uBAAuB,EACvB;IACE,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;CACtC,CACF;CAAG;AAEJ;;;;GAIG;AACH,MAAM,OAAO,YAAa,SAAQ,MAAM,CAAC,WAAW,EAAgB,CAClE,cAAc,EACd;IACE,cAAc,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;IAC3C,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;CACtC,CACF;CAAG;AAEJ;;;;GAIG;AACH,MAAM,OAAO,WAAY,SAAQ,MAAM,CAAC,WAAW,EAAe,CAChE,aAAa,EACb;IACE,SAAS,EAAE,MAAM,CAAC,MAAM;IACxB,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;CACtC,CACF;CAAG;AAEJ;;;;GAIG;AACH,MAAM,OAAO,YAAa,SAAQ,MAAM,CAAC,WAAW,EAAgB,CAClE,cAAc,EACd;IACE,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC;IACrC,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;CACtC,CACF;CAAG;AAEJ;;;;GAIG;AACH,MAAM,OAAO,qBAAsB,SAAQ,MAAM,CAAC,WAAW,EAAyB,CACpF,uBAAuB,EACvB;IACE,SAAS,EAAE,MAAM,CAAC,MAAM;IACxB,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,SAAS,CAAC;CAC5C,CACF;CAAG"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * @title AuditLogRepo — records every AWS API call
3
+ *
4
+ * Every call through the permission gate gets recorded — allowed, denied,
5
+ * or timed out.
6
+ *
7
+ * Design constraints:
8
+ * - MUST never block API calls (catchAll on write failures at call site)
9
+ * - MUST handle high volume (~17 ops per refresh × every 5min)
10
+ * - MUST auto-prune (150k entries/month without pruning)
11
+ * - MUST support filtered queries (for the audit log UI page)
12
+ *
13
+ * `durationMs` is null when the API call was denied/timed out (never ran).
14
+ * When present, it reflects actual AWS API latency — not permission prompt wait.
15
+ *
16
+ * @module
17
+ */
18
+ import * as SqlClient from "@effect/sql/SqlClient";
19
+ import { Effect, Schema } from "effect";
20
+ import { CacheError } from "../CacheService/CacheError.js";
21
+ export declare const AuditLogEntry: Schema.Struct<{
22
+ id: typeof Schema.Number;
23
+ timestamp: typeof Schema.String;
24
+ operation: typeof Schema.String;
25
+ accountProfile: typeof Schema.String;
26
+ region: typeof Schema.String;
27
+ permissionState: Schema.Literal<["allowed", "always_allowed", "denied", "timed_out"]>;
28
+ context: typeof Schema.String;
29
+ durationMs: Schema.NullOr<typeof Schema.Number>;
30
+ }>;
31
+ export type AuditLogEntry = typeof AuditLogEntry.Type;
32
+ export type NewAuditLogEntry = Omit<AuditLogEntry, "id">;
33
+ export interface PaginatedAuditLog {
34
+ readonly items: ReadonlyArray<AuditLogEntry>;
35
+ readonly total: number;
36
+ readonly nextCursor?: number;
37
+ }
38
+ declare const AuditLogRepo_base: Effect.Service.Class<AuditLogRepo, "AuditLogRepo", {
39
+ readonly dependencies: readonly [import("effect/Layer").Layer<SqlClient.SqlClient | import("@effect/sql-libsql/LibsqlClient").LibsqlClient, import("@effect/sql/SqlError").SqlError | import("effect/ConfigError").ConfigError | import("@effect/sql/Migrator").MigrationError, import("@effect/platform/FileSystem").FileSystem>];
40
+ readonly effect: Effect.Effect<{
41
+ log: (entry: NewAuditLogEntry) => Effect.Effect<void, CacheError, never>;
42
+ findAll: (opts?: {
43
+ readonly limit?: number | undefined;
44
+ readonly offset?: number | undefined;
45
+ readonly operation?: string | undefined;
46
+ readonly accountProfile?: string | undefined;
47
+ readonly permissionState?: string | undefined;
48
+ readonly from?: string | undefined;
49
+ readonly to?: string | undefined;
50
+ readonly search?: string | undefined;
51
+ }) => Effect.Effect<PaginatedAuditLog, CacheError>;
52
+ prune: (retentionDays: number) => Effect.Effect<number, CacheError>;
53
+ exportAll: (opts?: {
54
+ readonly from?: string | undefined;
55
+ readonly to?: string | undefined;
56
+ }) => Effect.Effect<ReadonlyArray<AuditLogEntry>, CacheError>;
57
+ }, never, SqlClient.SqlClient>;
58
+ }>;
59
+ export declare class AuditLogRepo extends AuditLogRepo_base {
60
+ }
61
+ export {};
62
+ //# sourceMappingURL=AuditLog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuditLog.d.ts","sourceRoot":"","sources":["../../src/PermissionService/AuditLog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,SAAS,MAAM,uBAAuB,CAAA;AAElD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAA;AAG1D,eAAO,MAAM,aAAa;;;;;;;;;EASxB,CAAA;AAEF,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC,IAAI,CAAA;AAErD,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAA;AAExD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,aAAa,CAAC,CAAA;IAC5C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAC7B;;;;qBA6BkB,gBAAgB;yBAQZ;YACf,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;YACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;YACpC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;YACvC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;YAC5C,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;YAC7C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;YAClC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;YAChC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;SACrC,KAAG,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,UAAU,CAAC;+BAuDzB,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC;2BAY9C;YACjB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;YAClC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;SACjC,KAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,aAAa,CAAC,EAAE,UAAU,CAAC;;;AA5GjE,qBAAa,YAAa,SAAQ,iBA8HhC;CAAG"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * @title AuditLogRepo — records every AWS API call
3
+ *
4
+ * Every call through the permission gate gets recorded — allowed, denied,
5
+ * or timed out.
6
+ *
7
+ * Design constraints:
8
+ * - MUST never block API calls (catchAll on write failures at call site)
9
+ * - MUST handle high volume (~17 ops per refresh × every 5min)
10
+ * - MUST auto-prune (150k entries/month without pruning)
11
+ * - MUST support filtered queries (for the audit log UI page)
12
+ *
13
+ * `durationMs` is null when the API call was denied/timed out (never ran).
14
+ * When present, it reflects actual AWS API latency — not permission prompt wait.
15
+ *
16
+ * @module
17
+ */
18
+ import * as SqlClient from "@effect/sql/SqlClient";
19
+ import * as SqlSchema from "@effect/sql/SqlSchema";
20
+ import { Effect, Schema } from "effect";
21
+ import { CacheError } from "../CacheService/CacheError.js";
22
+ import { DatabaseLive } from "../CacheService/Database.js";
23
+ export const AuditLogEntry = Schema.Struct({
24
+ id: Schema.Number,
25
+ timestamp: Schema.String,
26
+ operation: Schema.String,
27
+ accountProfile: Schema.String,
28
+ region: Schema.String,
29
+ permissionState: Schema.Literal("allowed", "always_allowed", "denied", "timed_out"),
30
+ context: Schema.String,
31
+ durationMs: Schema.NullOr(Schema.Number)
32
+ });
33
+ const cacheError = (op) => (effect) => effect.pipe(Effect.mapError((cause) => new CacheError({ operation: `AuditLogRepo.${op}`, cause })), Effect.withSpan(`AuditLogRepo.${op}`, { captureStackTrace: false }));
34
+ export class AuditLogRepo extends Effect.Service()("AuditLogRepo", {
35
+ dependencies: [DatabaseLive],
36
+ effect: Effect.gen(function* () {
37
+ const sql = yield* SqlClient.SqlClient;
38
+ const findAll_ = SqlSchema.findAll({
39
+ Result: AuditLogEntry,
40
+ Request: Schema.Struct({
41
+ limit: Schema.Number,
42
+ offset: Schema.Number
43
+ }),
44
+ execute: (req) => sql `SELECT * FROM audit_log ORDER BY id DESC LIMIT ${req.limit} OFFSET ${req.offset}`
45
+ });
46
+ const countAll = SqlSchema.single({
47
+ Result: Schema.Struct({ count: Schema.Number }),
48
+ Request: Schema.Void,
49
+ execute: () => sql `SELECT count(*) as count FROM audit_log`
50
+ });
51
+ return {
52
+ log: (entry) => sql `INSERT INTO audit_log (timestamp, operation, account_profile, region, permission_state, context, duration_ms)
53
+ VALUES (${entry.timestamp}, ${entry.operation}, ${entry.accountProfile}, ${entry.region}, ${entry.permissionState}, ${entry.context}, ${entry.durationMs})`
54
+ .pipe(Effect.asVoid, cacheError("log")),
55
+ findAll: (opts) => {
56
+ // Clamp numeric params to prevent injection via malformed input
57
+ const limit = Math.max(1, Math.min(200, Math.floor(opts?.limit ?? 50)));
58
+ const offset = Math.max(0, Math.floor(opts?.offset ?? 0));
59
+ // For filtered queries, build dynamic SQL
60
+ if (opts?.operation || opts?.accountProfile || opts?.permissionState || opts?.from || opts?.to || opts?.search) {
61
+ const conditions = [];
62
+ if (opts?.operation)
63
+ conditions.push(`operation = '${opts.operation.replace(/'/g, "''")}'`);
64
+ if (opts?.accountProfile) {
65
+ conditions.push(`account_profile = '${opts.accountProfile.replace(/'/g, "''")}'`);
66
+ }
67
+ if (opts?.permissionState) {
68
+ conditions.push(`permission_state = '${opts.permissionState.replace(/'/g, "''")}'`);
69
+ }
70
+ if (opts?.from)
71
+ conditions.push(`timestamp >= '${opts.from.replace(/'/g, "''")}'`);
72
+ if (opts?.to)
73
+ conditions.push(`timestamp <= '${opts.to.replace(/'/g, "''")}'`);
74
+ if (opts?.search) {
75
+ const escaped = opts.search.replace(/'/g, "''");
76
+ conditions.push(`(operation LIKE '%${escaped}%' OR context LIKE '%${escaped}%')`);
77
+ }
78
+ const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
79
+ return Effect.all([
80
+ sql.unsafe(`SELECT * FROM audit_log ${where} ORDER BY id DESC LIMIT ${limit} OFFSET ${offset}`).pipe(Effect.map((rows) => rows.map((r) => r))),
81
+ sql.unsafe(`SELECT count(*) as count FROM audit_log ${where}`).pipe(Effect.map((rows) => rows[0]?.count ?? 0))
82
+ ]).pipe(Effect.map(([items, total]) => ({
83
+ items,
84
+ total,
85
+ ...(items.length === limit ? { nextCursor: offset + limit } : {})
86
+ })), cacheError("findAll"));
87
+ }
88
+ return Effect.all([
89
+ findAll_({ limit, offset }),
90
+ countAll(undefined)
91
+ ]).pipe(Effect.map(([items, { count }]) => ({
92
+ items,
93
+ total: count,
94
+ ...(items.length === limit ? { nextCursor: offset + limit } : {})
95
+ })), cacheError("findAll"));
96
+ },
97
+ prune: (retentionDays) => {
98
+ const days = Math.max(1, Math.floor(retentionDays));
99
+ return sql.unsafe(`DELETE FROM audit_log WHERE timestamp < datetime('now', '-${days} days')`).pipe(
100
+ // DELETE returns no rows — use changes() to get actual deleted count
101
+ Effect.flatMap(() => sql `SELECT changes() as n`), Effect.map((rows) => rows[0]?.n ?? 0), cacheError("prune"));
102
+ },
103
+ exportAll: (opts) => {
104
+ if (opts?.from && opts?.to) {
105
+ return sql.unsafe(`SELECT * FROM audit_log WHERE timestamp >= '${opts.from.replace(/'/g, "''")}' AND timestamp <= '${opts.to.replace(/'/g, "''")}' ORDER BY id DESC`).pipe(Effect.map((rows) => rows.map((r) => r)), cacheError("exportAll"));
106
+ }
107
+ return sql.unsafe("SELECT * FROM audit_log ORDER BY id DESC").pipe(Effect.map((rows) => rows.map((r) => r)), cacheError("exportAll"));
108
+ }
109
+ };
110
+ })
111
+ }) {
112
+ }
113
+ //# sourceMappingURL=AuditLog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuditLog.js","sourceRoot":"","sources":["../../src/PermissionService/AuditLog.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * @title PermissionGate — abstract "ask the user" interface
3
+ *
4
+ * Context.Tag (not Effect.Service) so different environments can
5
+ * provide different implementations:
6
+ * - Web: Deferred + SSE push (PermissionGateLive.ts)
7
+ * - TUI: stdin prompt (future)
8
+ * - Test: auto-allow Layer
9
+ *
10
+ * Only exposes `request` — the caller's view. The concrete implementation
11
+ * (PermissionGateLive) adds `resolve` and `getFirstPending` for the
12
+ * HTTP handler and SSE builder.
13
+ *
14
+ * @module
15
+ */
16
+ import type { Effect } from "effect";
17
+ import { Context, Schema } from "effect";
18
+ import type { PermissionDeniedError } from "../Errors.js";
19
+ declare const PermissionPrompt_base: Schema.Class<PermissionPrompt, {
20
+ id: typeof Schema.String;
21
+ operation: typeof Schema.String;
22
+ category: Schema.Literal<["read", "write"]>;
23
+ context: typeof Schema.String;
24
+ }, Schema.Struct.Encoded<{
25
+ id: typeof Schema.String;
26
+ operation: typeof Schema.String;
27
+ category: Schema.Literal<["read", "write"]>;
28
+ context: typeof Schema.String;
29
+ }>, never, {
30
+ readonly id: string;
31
+ } & {
32
+ readonly operation: string;
33
+ } & {
34
+ readonly context: string;
35
+ } & {
36
+ readonly category: "read" | "write";
37
+ }, {}, {}>;
38
+ export declare class PermissionPrompt extends PermissionPrompt_base {
39
+ }
40
+ export type PermissionResponse = "allow_once" | "always_allow" | "deny";
41
+ declare const PermissionGate_base: Context.TagClass<PermissionGate, "@knpkv/codecommit-core/PermissionGate", {
42
+ readonly request: (prompt: PermissionPrompt) => Effect.Effect<PermissionResponse, PermissionDeniedError>;
43
+ }>;
44
+ export declare class PermissionGate extends PermissionGate_base {
45
+ }
46
+ export {};
47
+ //# sourceMappingURL=PermissionGate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PermissionGate.d.ts","sourceRoot":"","sources":["../../src/PermissionService/PermissionGate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACxC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;;;;;;;;;;;;;;;;;;;;AAGzD,qBAAa,gBAAiB,SAAQ,qBAKpC;CAAG;AAEL,MAAM,MAAM,kBAAkB,GAAG,YAAY,GAAG,cAAc,GAAG,MAAM,CAAA;;sBAOjD,CAAC,MAAM,EAAE,gBAAgB,KAAK,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,qBAAqB,CAAC;;AAH5G,qBAAa,cAAe,SAAQ,mBAKjC;CAAG"}
@@ -0,0 +1,14 @@
1
+ import { Context, Schema } from "effect";
2
+ // UUID correlates the SSE prompt → client modal → POST response
3
+ export class PermissionPrompt extends Schema.Class("PermissionPrompt")({
4
+ id: Schema.String,
5
+ operation: Schema.String,
6
+ category: Schema.Literal("read", "write"),
7
+ context: Schema.String
8
+ }) {
9
+ }
10
+ // Blocks the calling fiber until user responds or 30s timeout.
11
+ // Returns the response, or fails with PermissionDeniedError.
12
+ export class PermissionGate extends Context.Tag("@knpkv/codecommit-core/PermissionGate")() {
13
+ }
14
+ //# sourceMappingURL=PermissionGate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PermissionGate.js","sourceRoot":"","sources":["../../src/PermissionService/PermissionGate.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAGxC,gEAAgE;AAChE,MAAM,OAAO,gBAAiB,SAAQ,MAAM,CAAC,KAAK,CAAmB,kBAAkB,CAAC,CAAC;IACvF,EAAE,EAAE,MAAM,CAAC,MAAM;IACjB,SAAS,EAAE,MAAM,CAAC,MAAM;IACxB,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC;IACzC,OAAO,EAAE,MAAM,CAAC,MAAM;CACvB,CAAC;CAAG;AAIL,+DAA+D;AAC/D,6DAA6D;AAC7D,MAAM,OAAO,cAAe,SAAQ,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,EAKrF;CAAG"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @title PermissionGateLive — Deferred-based prompt flow
3
+ *
4
+ * One `Deferred<PermissionResponse>` per prompt.
5
+ *
6
+ * Flow:
7
+ * 1. API call fiber creates Deferred, stores in pending Map
8
+ * 2. Publishes PermissionRequired → SSE rebuilds payload with prompt
9
+ * 3. Fiber blocks on Deferred.await (up to 30s)
10
+ * 4. User clicks modal → POST /api/permissions/respond
11
+ * 5. HTTP handler calls resolve() → Deferred.succeed → fiber unblocks
12
+ * 6. Publishes PermissionResolved → SSE removes prompt from payload
13
+ *
14
+ * Multi-tab: Deferred.succeed is idempotent — first responder wins,
15
+ * second tab's POST is a no-op. Both see prompt disappear via SSE.
16
+ *
17
+ * Separate Effect.Service tag (not just PermissionGate) because the
18
+ * HTTP handler and SSE builder need `resolve` and `getFirstPending`
19
+ * which the abstract interface doesn't expose.
20
+ *
21
+ * @module
22
+ */
23
+ import { Effect, Layer } from "effect";
24
+ import { EventsHub } from "../CacheService/EventsHub.js";
25
+ import { PermissionDeniedError } from "../Errors.js";
26
+ import { PermissionGate, type PermissionPrompt, type PermissionResponse } from "./PermissionGate.js";
27
+ export interface PermissionGateLive {
28
+ readonly request: (prompt: PermissionPrompt) => Effect.Effect<PermissionResponse, PermissionDeniedError>;
29
+ readonly resolve: (promptId: string, response: PermissionResponse) => Effect.Effect<void>;
30
+ readonly getFirstPending: () => Effect.Effect<PermissionPrompt | undefined>;
31
+ }
32
+ export declare const PermissionGateLiveTag: Effect.Service.Class<PermissionGateLive, "PermissionGateLive", {
33
+ readonly dependencies: readonly [Layer.Layer<EventsHub, never, never>];
34
+ readonly effect: Effect.Effect<{
35
+ request: (prompt: PermissionPrompt) => Effect.Effect<PermissionResponse, PermissionDeniedError>;
36
+ resolve: (promptId: string, response: PermissionResponse) => Effect.Effect<void>;
37
+ getFirstPending: () => Effect.Effect<PermissionPrompt | undefined>;
38
+ }, never, EventsHub>;
39
+ }>;
40
+ export declare const PermissionGateLiveLayer: Layer.Layer<PermissionGate, never, PermissionGateLive>;
41
+ //# sourceMappingURL=PermissionGateLive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PermissionGateLive.d.ts","sourceRoot":"","sources":["../../src/PermissionService/PermissionGateLive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAY,MAAM,EAAE,KAAK,EAAO,MAAM,QAAQ,CAAA;AACrD,OAAO,EAAE,SAAS,EAAc,MAAM,8BAA8B,CAAA;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AACpD,OAAO,EAAE,cAAc,EAAE,KAAK,gBAAgB,EAAE,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAOpG,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,CAAA;IACxG,QAAQ,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,kBAAkB,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACzF,QAAQ,CAAC,eAAe,EAAE,MAAM,MAAM,CAAC,MAAM,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAAA;CAC5E;AAED,eAAO,MAAM,qBAAqB;;;0BAWL,gBAAgB,KAAG,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,qBAAqB,CAAC;4BAqCzE,MAAM,YAAY,kBAAkB,KAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;+BAUzD,MAAM,CAAC,MAAM,CAAC,gBAAgB,GAAG,SAAS,CAAC;;EAUzE,CAAA;AAKF,eAAO,MAAM,uBAAuB,wDAGnC,CAAA"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * @title PermissionGateLive — Deferred-based prompt flow
3
+ *
4
+ * One `Deferred<PermissionResponse>` per prompt.
5
+ *
6
+ * Flow:
7
+ * 1. API call fiber creates Deferred, stores in pending Map
8
+ * 2. Publishes PermissionRequired → SSE rebuilds payload with prompt
9
+ * 3. Fiber blocks on Deferred.await (up to 30s)
10
+ * 4. User clicks modal → POST /api/permissions/respond
11
+ * 5. HTTP handler calls resolve() → Deferred.succeed → fiber unblocks
12
+ * 6. Publishes PermissionResolved → SSE removes prompt from payload
13
+ *
14
+ * Multi-tab: Deferred.succeed is idempotent — first responder wins,
15
+ * second tab's POST is a no-op. Both see prompt disappear via SSE.
16
+ *
17
+ * Separate Effect.Service tag (not just PermissionGate) because the
18
+ * HTTP handler and SSE builder need `resolve` and `getFirstPending`
19
+ * which the abstract interface doesn't expose.
20
+ *
21
+ * @module
22
+ */
23
+ import { Deferred, Effect, Layer, Ref } from "effect";
24
+ import { EventsHub, RepoChange } from "../CacheService/EventsHub.js";
25
+ import { PermissionDeniedError } from "../Errors.js";
26
+ import { PermissionGate } from "./PermissionGate.js";
27
+ export const PermissionGateLiveTag = Effect.Service()("PermissionGateLive", {
28
+ // EventsHub needed to publish PermissionRequired/Resolved events
29
+ // that trigger SSE payload rebuilds
30
+ dependencies: [EventsHub.Default],
31
+ effect: Effect.gen(function* () {
32
+ const hub = yield* EventsHub;
33
+ // Map<promptId, { deferred, prompt }>. Concurrent-safe via Ref.
34
+ // Multiple prompts can be pending simultaneously (e.g. initial
35
+ // refresh triggers getCallerIdentity + listRepositories at once).
36
+ const pending = yield* Ref.make(new Map());
37
+ const request = (prompt) => Effect.gen(function* () {
38
+ const deferred = yield* Deferred.make();
39
+ yield* Ref.update(pending, (m) => new Map(m).set(prompt.id, { deferred, prompt }));
40
+ yield* hub.publish(RepoChange.PermissionRequired());
41
+ const response = yield* Deferred.await(deferred).pipe(Effect.timeout("30 seconds"), Effect.catchTag("TimeoutException", () => {
42
+ return Effect.gen(function* () {
43
+ yield* Ref.update(pending, (m) => {
44
+ const n = new Map(m);
45
+ n.delete(prompt.id);
46
+ return n;
47
+ });
48
+ yield* hub.publish(RepoChange.PermissionResolved());
49
+ return yield* new PermissionDeniedError({ operation: prompt.operation, reason: "timeout" });
50
+ });
51
+ }));
52
+ yield* Ref.update(pending, (m) => {
53
+ const n = new Map(m);
54
+ n.delete(prompt.id);
55
+ return n;
56
+ });
57
+ yield* hub.publish(RepoChange.PermissionResolved());
58
+ if (response === "deny") {
59
+ return yield* new PermissionDeniedError({ operation: prompt.operation, reason: "denied" });
60
+ }
61
+ return response;
62
+ });
63
+ // Called by POST /api/permissions/respond handler.
64
+ // Deferred.succeed is idempotent — second call is a no-op.
65
+ // This is how multi-tab "first responder wins" works.
66
+ const resolve = (promptId, response) => Ref.get(pending).pipe(Effect.flatMap((m) => {
67
+ const entry = m.get(promptId);
68
+ return entry ? Deferred.succeed(entry.deferred, response) : Effect.void;
69
+ }));
70
+ // For SSE payload builder — shows one prompt at a time (FIFO).
71
+ // Remaining prompts queue behind; they'll surface as each resolves.
72
+ const getFirstPending = () => Ref.get(pending).pipe(Effect.map((m) => {
73
+ const first = m.values().next();
74
+ return first.done ? undefined : first.value.prompt;
75
+ }));
76
+ return { request, resolve, getFirstPending };
77
+ })
78
+ });
79
+ // Bridge: concrete service → abstract Context.Tag.
80
+ // Handlers use PermissionGateLiveTag (for resolve/getFirstPending),
81
+ // AwsClientGated uses PermissionGate (for request only).
82
+ export const PermissionGateLiveLayer = Layer.effect(PermissionGate, Effect.map(PermissionGateLiveTag, (live) => ({ request: live.request })));
83
+ //# sourceMappingURL=PermissionGateLive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PermissionGateLive.js","sourceRoot":"","sources":["../../src/PermissionService/PermissionGateLive.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
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 { Effect, Schema } from "effect";
18
+ import { allOperations, getOperationMeta, type OperationName, registerOperation } from "./operations.js";
19
+ export type { BuiltinOperation, OperationMeta, OperationName } from "./operations.js";
20
+ export { allOperations, getOperationMeta, registerOperation };
21
+ export declare const PermissionState: Schema.Literal<["always_allow", "allow", "deny"]>;
22
+ export type PermissionState = typeof PermissionState.Type;
23
+ declare const PermissionService_base: Effect.Service.Class<PermissionService, "PermissionService", {
24
+ readonly effect: Effect.Effect<{
25
+ check: (operation: OperationName) => Effect.Effect<PermissionState>;
26
+ set: (operation: OperationName, state: PermissionState) => Effect.Effect<void>;
27
+ getAll: () => Effect.Effect<Record<string, PermissionState>>;
28
+ resetAll: () => Effect.Effect<void>;
29
+ isAuditEnabled: () => Effect.Effect<boolean>;
30
+ getAuditRetention: () => Effect.Effect<number>;
31
+ setAudit: (opts: {
32
+ enabled?: boolean | undefined;
33
+ retentionDays?: number | undefined;
34
+ }) => Effect.Effect<void>;
35
+ }, never, FileSystem.FileSystem>;
36
+ }>;
37
+ export declare class PermissionService extends PermissionService_base {
38
+ }
39
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/PermissionService/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAU,MAAM,EAAO,MAAM,EAAE,MAAM,QAAQ,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,KAAK,aAAa,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAExG,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AACrF,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,CAAA;AAK7D,eAAO,MAAM,eAAe,mDAAkD,CAAA;AAC9E,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC,IAAI,CAAA;;;2BA6D3B,aAAa,KAAG,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC;yBAGhD,aAAa,SAAS,eAAe,KAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;sBAShE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;wBAG5C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;8BAMb,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;iCAEnB,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;yBAI3C;YAAE,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;YAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;SAAE,KAC1E,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;;;AAzC1B,qBAAa,iBAAkB,SAAQ,sBAuDrC;CAAG"}
@@ -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"}
package/dist/index.d.ts CHANGED
@@ -20,6 +20,7 @@ export * as ConfigService from "./ConfigService/index.js";
20
20
  export * as DateUtils from "./DateUtils.js";
21
21
  export * as Domain from "./Domain.js";
22
22
  export * as Errors from "./Errors.js";
23
+ export * as PermissionService from "./PermissionService/index.js";
23
24
  export * as PRService from "./PRService/index.js";
24
25
  export * as SandboxService from "./SandboxService/index.js";
25
26
  export * as StatsService from "./StatsService/index.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAA;AACjD,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAA;AACvD,OAAO,KAAK,YAAY,MAAM,yBAAyB,CAAA;AACvD,OAAO,KAAK,aAAa,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAA;AACjD,OAAO,KAAK,cAAc,MAAM,2BAA2B,CAAA;AAC3D,OAAO,KAAK,YAAY,MAAM,yBAAyB,CAAA;AAGvD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAA;AACjD,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAA;AACvD,OAAO,KAAK,YAAY,MAAM,yBAAyB,CAAA;AACvD,OAAO,KAAK,aAAa,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,iBAAiB,MAAM,8BAA8B,CAAA;AACjE,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAA;AACjD,OAAO,KAAK,cAAc,MAAM,2BAA2B,CAAA;AAC3D,OAAO,KAAK,YAAY,MAAM,yBAAyB,CAAA;AAGvD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA"}
package/dist/index.js CHANGED
@@ -20,6 +20,7 @@ export * as ConfigService from "./ConfigService/index.js";
20
20
  export * as DateUtils from "./DateUtils.js";
21
21
  export * as Domain from "./Domain.js";
22
22
  export * as Errors from "./Errors.js";
23
+ export * as PermissionService from "./PermissionService/index.js";
23
24
  export * as PRService from "./PRService/index.js";
24
25
  export * as SandboxService from "./SandboxService/index.js";
25
26
  export * as StatsService from "./StatsService/index.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAA;AACjD,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAA;AACvD,OAAO,KAAK,YAAY,MAAM,yBAAyB,CAAA;AACvD,OAAO,KAAK,aAAa,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAA;AACjD,OAAO,KAAK,cAAc,MAAM,2BAA2B,CAAA;AAC3D,OAAO,KAAK,YAAY,MAAM,yBAAyB,CAAA;AAEvD,gDAAgD;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAA;AACjD,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAA;AACvD,OAAO,KAAK,YAAY,MAAM,yBAAyB,CAAA;AACvD,OAAO,KAAK,aAAa,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,iBAAiB,MAAM,8BAA8B,CAAA;AACjE,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAA;AACjD,OAAO,KAAK,cAAc,MAAM,2BAA2B,CAAA;AAC3D,OAAO,KAAK,YAAY,MAAM,yBAAyB,CAAA;AAEvD,gDAAgD;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knpkv/codecommit-core",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "description": "Core logic for CodeCommit PR browser",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",