@shivaedev/server 0.9.3 → 0.11.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 (77) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/README.md +24 -19
  3. package/dist/appDatabase.d.ts +14 -0
  4. package/dist/appDatabase.d.ts.map +1 -0
  5. package/dist/{databaseLayer.js → appDatabase.js} +6 -6
  6. package/dist/appDatabase.js.map +1 -0
  7. package/dist/appHost.d.ts +1 -14
  8. package/dist/appHost.d.ts.map +1 -1
  9. package/dist/appHost.js +5 -10
  10. package/dist/appHost.js.map +1 -1
  11. package/dist/appHostHttp.d.ts +29 -29
  12. package/dist/appHostHttp.d.ts.map +1 -1
  13. package/dist/appHostHttp.js +7 -7
  14. package/dist/appHostHttp.js.map +1 -1
  15. package/dist/bearerSocketRpc.d.ts +5 -0
  16. package/dist/bearerSocketRpc.d.ts.map +1 -0
  17. package/dist/bearerSocketRpc.js +69 -0
  18. package/dist/bearerSocketRpc.js.map +1 -0
  19. package/dist/hostChanges.d.ts +2 -3
  20. package/dist/hostChanges.d.ts.map +1 -1
  21. package/dist/hostChanges.js +9 -14
  22. package/dist/hostChanges.js.map +1 -1
  23. package/dist/hostRpcRoutes.d.ts +2 -3
  24. package/dist/hostRpcRoutes.d.ts.map +1 -1
  25. package/dist/hostRpcRoutes.js +4 -2
  26. package/dist/hostRpcRoutes.js.map +1 -1
  27. package/dist/otlpHttpClient.js +2 -2
  28. package/dist/otlpHttpClient.js.map +1 -1
  29. package/dist/redactingDiagnostics.d.ts +0 -2
  30. package/dist/redactingDiagnostics.d.ts.map +1 -1
  31. package/dist/redactingDiagnostics.js +1 -4
  32. package/dist/redactingDiagnostics.js.map +1 -1
  33. package/dist/redactingTracer.d.ts.map +1 -1
  34. package/dist/redactingTracer.js +6 -5
  35. package/dist/redactingTracer.js.map +1 -1
  36. package/dist/safeOtlpSerialization.d.ts +0 -2
  37. package/dist/safeOtlpSerialization.d.ts.map +1 -1
  38. package/dist/safeOtlpSerialization.js +5 -12
  39. package/dist/safeOtlpSerialization.js.map +1 -1
  40. package/dist/setupDatabases.d.ts +1 -1
  41. package/dist/setupDatabases.d.ts.map +1 -1
  42. package/dist/setupDatabases.js +1 -1
  43. package/dist/setupDatabases.js.map +1 -1
  44. package/dist/socketRpc.d.ts.map +1 -1
  45. package/dist/socketRpc.js +6 -4
  46. package/dist/socketRpc.js.map +1 -1
  47. package/package.json +11 -17
  48. package/src/{databaseLayer.ts → appDatabase.ts} +6 -6
  49. package/src/appHost.ts +5 -11
  50. package/src/appHostHttp.ts +8 -11
  51. package/src/bearerSocketRpc.ts +80 -0
  52. package/src/hostChanges.ts +12 -22
  53. package/src/hostRpcRoutes.ts +4 -6
  54. package/src/otlpHttpClient.ts +2 -2
  55. package/src/redactingDiagnostics.ts +1 -5
  56. package/src/redactingTracer.ts +7 -5
  57. package/src/safeOtlpSerialization.ts +5 -12
  58. package/src/setupDatabases.ts +1 -1
  59. package/src/socketRpc.ts +6 -6
  60. package/dist/databaseLayer.d.ts +0 -14
  61. package/dist/databaseLayer.d.ts.map +0 -1
  62. package/dist/databaseLayer.js.map +0 -1
  63. package/dist/redactOtlpUrl.d.ts +0 -2
  64. package/dist/redactOtlpUrl.d.ts.map +0 -1
  65. package/dist/redactOtlpUrl.js +0 -41
  66. package/dist/redactOtlpUrl.js.map +0 -1
  67. package/dist/schemaSensitiveAst.d.ts +0 -7
  68. package/dist/schemaSensitiveAst.d.ts.map +0 -1
  69. package/dist/schemaSensitiveAst.js +0 -102
  70. package/dist/schemaSensitiveAst.js.map +0 -1
  71. package/dist/schemaSensitiveKeys.d.ts +0 -6
  72. package/dist/schemaSensitiveKeys.d.ts.map +0 -1
  73. package/dist/schemaSensitiveKeys.js +0 -47
  74. package/dist/schemaSensitiveKeys.js.map +0 -1
  75. package/src/redactOtlpUrl.ts +0 -48
  76. package/src/schemaSensitiveAst.ts +0 -106
  77. package/src/schemaSensitiveKeys.ts +0 -49
@@ -1,102 +0,0 @@
1
- import { Predicate } from "effect";
2
- import { isSensitiveKey } from "@shivaedev/errors/sensitive.ts";
3
- function children(ast) {
4
- switch (ast._tag) {
5
- case "Objects":
6
- return [...ast.propertySignatures.map((property) => property.type), ...ast.indexSignatures.flatMap((index) => [index.parameter, index.type])];
7
- case "Arrays":
8
- return [...ast.elements, ...ast.rest];
9
- case "Union":
10
- return ast.types;
11
- case "Declaration":
12
- return ast.typeParameters;
13
- case "Suspend":
14
- return [ast.thunk()];
15
- default:
16
- return [];
17
- }
18
- }
19
- function sensitiveCheck(check) {
20
- return check.annotations?.sensitive === true || (check._tag === "FilterGroup" && check.checks.some(sensitiveCheck));
21
- }
22
- export function marked(ast, seen = new Set()) {
23
- if (seen.has(ast)) {
24
- return false;
25
- }
26
- seen.add(ast);
27
- if (ast.annotations?.sensitive === true
28
- || ast.context?.annotations?.sensitive === true
29
- || ast.checks?.some(sensitiveCheck)
30
- || (Predicate.hasProperty(ast.annotations?.representation, "id") && ast.annotations.representation.id === "effect/schema/Redacted")) {
31
- return true;
32
- }
33
- const nested = ast._tag === "Objects" ? ast.indexSignatures.map((index) => index.type) : children(ast);
34
- return (ast.encoding?.some((link) => marked(link.to, seen)) ?? false) || nested.some((type) => marked(type, seen));
35
- }
36
- function containsSensitive(ast, keys) {
37
- return (marked(ast)
38
- || propertiesOf(ast).some((property) => typeof property.name === "string" && (keys.has(property.name) || isSensitiveKey(property.name))));
39
- }
40
- export function collectEncodedKeys(ast, keys) {
41
- let source = ast;
42
- let sensitive = false;
43
- for (const link of ast.encoding ?? []) {
44
- sensitive ||= containsSensitive(source, keys);
45
- if (sensitive) {
46
- for (const property of propertiesOf(link.to)) {
47
- if (typeof property.name === "string") {
48
- keys.add(property.name);
49
- }
50
- }
51
- }
52
- source = link.to;
53
- }
54
- }
55
- function fixedOutput(ast) {
56
- if (ast._tag === "Union") {
57
- return ast.types.every(fixedOutput);
58
- }
59
- return ast._tag === "Objects" && ast.indexSignatures.length === 0;
60
- }
61
- export function maskedValue(ast, keys, seen = new Set()) {
62
- if (seen.has(ast)) {
63
- return false;
64
- }
65
- seen.add(ast);
66
- if (marked(ast)) {
67
- return true;
68
- }
69
- let source = ast;
70
- let sensitive = false;
71
- for (const link of ast.encoding ?? []) {
72
- sensitive ||= containsSensitive(source, keys);
73
- if (sensitive && !fixedOutput(link.to)) {
74
- return true;
75
- }
76
- source = link.to;
77
- }
78
- const nested = ast._tag === "Objects" ? ast.indexSignatures.map((index) => index.type) : children(ast);
79
- return nested.some((type) => maskedValue(type, keys, seen));
80
- }
81
- export function collect(ast, nodes, encodings = true) {
82
- if (nodes.has(ast)) {
83
- return;
84
- }
85
- nodes.add(ast);
86
- for (const child of [...children(ast), ...(encodings ? (ast.encoding?.map((link) => link.to) ?? []) : [])]) {
87
- collect(child, nodes, encodings);
88
- }
89
- }
90
- function propertiesOf(ast) {
91
- const nodes = new Set();
92
- collect(ast, nodes, false);
93
- return [...nodes].flatMap((node) => (node._tag === "Objects" ? node.propertySignatures : []));
94
- }
95
- export function collectFieldKeys(properties, keys, sensitive) {
96
- for (const property of properties) {
97
- if (typeof property.name === "string" && sensitive(property.type)) {
98
- keys.add(property.name);
99
- }
100
- }
101
- }
102
- //# sourceMappingURL=schemaSensitiveAst.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"schemaSensitiveAst.js","sourceRoot":"","sources":["../src/schemaSensitiveAst.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAkB,MAAM,QAAQ,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAEhE,SAAS,QAAQ,CAAC,GAAkB;IACnC,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,SAAS;YACb,OAAO,CAAC,GAAG,GAAG,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/I,KAAK,QAAQ;YACZ,OAAO,CAAC,GAAG,GAAG,CAAC,QAAQ,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;QACvC,KAAK,OAAO;YACX,OAAO,GAAG,CAAC,KAAK,CAAC;QAClB,KAAK,aAAa;YACjB,OAAO,GAAG,CAAC,cAAc,CAAC;QAC3B,KAAK,SAAS;YACb,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;QACtB;YACC,OAAO,EAAE,CAAC;IACZ,CAAC;AACF,CAAC;AACD,SAAS,cAAc,CAAC,KAA6B;IACpD,OAAO,KAAK,CAAC,WAAW,EAAE,SAAS,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,aAAa,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;AACrH,CAAC;AACD,MAAM,UAAU,MAAM,CAAC,GAAkB,EAAE,IAAI,GAAG,IAAI,GAAG,EAAiB;IACzE,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QACnB,OAAO,KAAK,CAAC;IACd,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACd,IACC,GAAG,CAAC,WAAW,EAAE,SAAS,KAAK,IAAI;WAChC,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,KAAK,IAAI;WAC5C,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,CAAC;WAChC,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,EAAE,cAAc,EAAE,IAAI,CAAC,IAAI,GAAG,CAAC,WAAW,CAAC,cAAc,CAAC,EAAE,KAAK,wBAAwB,CAAC,EAClI,CAAC;QACF,OAAO,IAAI,CAAC;IACb,CAAC;IACD,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACvG,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;AACpH,CAAC;AACD,SAAS,iBAAiB,CAAC,GAAkB,EAAE,IAAyB;IACvE,OAAO,CACN,MAAM,CAAC,GAAG,CAAC;WACR,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CACxI,CAAC;AACH,CAAC;AACD,MAAM,UAAU,kBAAkB,CAAC,GAAkB,EAAE,IAAiB;IACvE,IAAI,MAAM,GAAG,GAAG,CAAC;IACjB,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;QACvC,SAAS,KAAK,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC9C,IAAI,SAAS,EAAE,CAAC;YACf,KAAK,MAAM,QAAQ,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC9C,IAAI,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACvC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBACzB,CAAC;YACF,CAAC;QACF,CAAC;QACD,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IAClB,CAAC;AACF,CAAC;AACD,SAAS,WAAW,CAAC,GAAkB;IACtC,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC1B,OAAO,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,GAAG,CAAC,eAAe,CAAC,MAAM,KAAK,CAAC,CAAC;AACnE,CAAC;AACD,MAAM,UAAU,WAAW,CAAC,GAAkB,EAAE,IAAyB,EAAE,IAAI,GAAG,IAAI,GAAG,EAAiB;IACzG,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QACnB,OAAO,KAAK,CAAC;IACd,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACd,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QACjB,OAAO,IAAI,CAAC;IACb,CAAC;IACD,IAAI,MAAM,GAAG,GAAG,CAAC;IACjB,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;QACvC,SAAS,KAAK,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC9C,IAAI,SAAS,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YACxC,OAAO,IAAI,CAAC;QACb,CAAC;QACD,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IAClB,CAAC;IACD,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACvG,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;AAC7D,CAAC;AACD,MAAM,UAAU,OAAO,CAAC,GAAkB,EAAE,KAAyB,EAAE,SAAS,GAAG,IAAI;IACtF,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QACpB,OAAO;IACR,CAAC;IACD,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,KAAK,IAAI,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAC5G,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IAClC,CAAC;AACF,CAAC;AACD,SAAS,YAAY,CAAC,GAAkB;IACvC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAiB,CAAC;IACvC,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC3B,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/F,CAAC;AACD,MAAM,UAAU,gBAAgB,CAAC,UAAmD,EAAE,IAAiB,EAAE,SAA0C;IAClJ,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,IAAI,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACnE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;IACF,CAAC;AACF,CAAC"}
@@ -1,6 +0,0 @@
1
- import { Rpc, type RpcGroup } from "effect/rpc";
2
- export declare function schemaSensitiveKeys<R extends Rpc.Any>(group: RpcGroup.RpcGroup<R>, extra?: readonly string[]): ((key: string) => boolean) & {
3
- forRpc: (tag: string | undefined) => (key: string) => boolean;
4
- maskFailure: (tag: string | undefined, reason: "Fail" | "Die") => boolean;
5
- };
6
- //# sourceMappingURL=schemaSensitiveKeys.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"schemaSensitiveKeys.d.ts","sourceRoot":"","sources":["../src/schemaSensitiveKeys.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAgChD,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,GAAE,SAAS,MAAM,EAAO,UAOxF,MAAM;kBAIf,MAAM,GAAG,SAAS,WAJT,MAAM;uBAKV,MAAM,GAAG,SAAS,UAAU,MAAM,GAAG,KAAK;EAG9D"}
@@ -1,47 +0,0 @@
1
- import { Rpc } from "effect/rpc";
2
- import { isSensitiveKey } from "@shivaedev/errors/sensitive.ts";
3
- import { collect, collectEncodedKeys, collectFieldKeys, marked, maskedValue } from "#schemaSensitiveAst.ts";
4
- function rpcSensitiveKeys(rpc, extra) {
5
- const keys = new Set(extra);
6
- const nodes = new Set();
7
- const schemas = [
8
- rpc.payloadSchema,
9
- rpc.successSchema,
10
- rpc.errorSchema,
11
- rpc.defectSchema,
12
- ...[...rpc.middlewares].map((m) => m.error),
13
- ];
14
- for (const schema of schemas) {
15
- collect(schema.ast, nodes);
16
- }
17
- const properties = [...nodes].flatMap((ast) => (ast._tag === "Objects" ? ast.propertySignatures : []));
18
- collectFieldKeys(properties, keys, marked);
19
- let previousSize;
20
- do {
21
- previousSize = keys.size;
22
- collectFieldKeys(properties, keys, (ast) => maskedValue(ast, keys));
23
- for (const ast of nodes) {
24
- collectEncodedKeys(ast, keys);
25
- }
26
- } while (keys.size !== previousSize);
27
- return Object.assign((key) => keys.has(key) || isSensitiveKey(key), {
28
- die: maskedValue(rpc.defectSchema.ast, keys),
29
- fail: [rpc.errorSchema, ...[...rpc.middlewares].map((m) => m.error)].some((schema) => maskedValue(schema.ast, keys)),
30
- });
31
- }
32
- export function schemaSensitiveKeys(group, extra = []) {
33
- const policies = new Map();
34
- for (const rpc of group.requests.values()) {
35
- if (Rpc.isRpc(rpc)) {
36
- policies.set(rpc._tag, rpcSensitiveKeys(rpc, extra));
37
- }
38
- }
39
- function sensitive(key) {
40
- return extra.includes(key) || isSensitiveKey(key) || [...policies.values()].some((policy) => policy(key));
41
- }
42
- return Object.assign(sensitive, {
43
- forRpc: (tag) => (tag === undefined ? sensitive : (policies.get(tag) ?? sensitive)),
44
- maskFailure: (tag, reason) => [...policies].some(([method, policy]) => (tag === undefined || tag === method) && (reason === "Fail" ? policy.fail : policy.die)),
45
- });
46
- }
47
- //# sourceMappingURL=schemaSensitiveKeys.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"schemaSensitiveKeys.js","sourceRoot":"","sources":["../src/schemaSensitiveKeys.ts"],"names":[],"mappings":"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"}
@@ -1,48 +0,0 @@
1
- import { REDACTED } from "@shivaedev/errors/sensitive.ts";
2
-
3
- function query(value: string): string {
4
- return value
5
- .split("&")
6
- .map((part) => (part === "" ? part : `${part.split("=", 1)[0]}=${REDACTED}`))
7
- .join("&");
8
- }
9
-
10
- function url(value: string): string {
11
- const fragment = value.indexOf("#");
12
- const target = fragment === -1 ? value : value.slice(0, fragment);
13
- const separator = target.indexOf("?");
14
- return (
15
- (separator === -1 ? target : `${target.slice(0, separator + 1)}${query(target.slice(separator + 1))}`).replaceAll(
16
- /(?<authority>(?:\b[a-z][a-z0-9+.-]*:)?\/\/)[^/?#]*@/giu,
17
- `$<authority>${REDACTED}@`,
18
- ) + (fragment === -1 ? "" : `#${REDACTED}`)
19
- );
20
- }
21
-
22
- function structured(value: string): string | undefined {
23
- try {
24
- return JSON.stringify(JSON.parse(value, (key: string, item: unknown) => (typeof item === "string" ? redactOtlpUrl(item, key) : item)));
25
- } catch {
26
- return undefined;
27
- }
28
- }
29
-
30
- export function redactOtlpUrl(value: string, key = ""): string {
31
- if (/(?:^|[._-])(?:fragment|userinfo|username|password)$/iu.test(key)) {
32
- return REDACTED;
33
- }
34
- if (/(?:^|[._-])query$/iu.test(key)) {
35
- return url(`?${value}`).slice(1);
36
- }
37
- if (/(?:^|[._-])(?:url|uri|target)(?:$|[._-])/iu.test(key) || /(?:^|[._-])(?:referer|referrer|location|origin)$/iu.test(key)) {
38
- return url(value);
39
- }
40
- if (/^\s*[[{]/u.test(value)) {
41
- const redacted = structured(value);
42
- if (redacted !== undefined) {
43
- return redacted;
44
- }
45
- }
46
- // Quotes and whitespace can belong to secret values, so free text has no safe closing delimiter.
47
- return value.replaceAll(/(?:[a-z][a-z0-9+.-]*:\/\/|[/?#]).*/gisu, url);
48
- }
@@ -1,106 +0,0 @@
1
- import { Predicate, type SchemaAST } from "effect";
2
- import { isSensitiveKey } from "@shivaedev/errors/sensitive.ts";
3
-
4
- function children(ast: SchemaAST.AST): readonly SchemaAST.AST[] {
5
- switch (ast._tag) {
6
- case "Objects":
7
- return [...ast.propertySignatures.map((property) => property.type), ...ast.indexSignatures.flatMap((index) => [index.parameter, index.type])];
8
- case "Arrays":
9
- return [...ast.elements, ...ast.rest];
10
- case "Union":
11
- return ast.types;
12
- case "Declaration":
13
- return ast.typeParameters;
14
- case "Suspend":
15
- return [ast.thunk()];
16
- default:
17
- return [];
18
- }
19
- }
20
- function sensitiveCheck(check: SchemaAST.Check<never>): boolean {
21
- return check.annotations?.sensitive === true || (check._tag === "FilterGroup" && check.checks.some(sensitiveCheck));
22
- }
23
- export function marked(ast: SchemaAST.AST, seen = new Set<SchemaAST.AST>()): boolean {
24
- if (seen.has(ast)) {
25
- return false;
26
- }
27
- seen.add(ast);
28
- if (
29
- ast.annotations?.sensitive === true
30
- || ast.context?.annotations?.sensitive === true
31
- || ast.checks?.some(sensitiveCheck)
32
- || (Predicate.hasProperty(ast.annotations?.representation, "id") && ast.annotations.representation.id === "effect/schema/Redacted")
33
- ) {
34
- return true;
35
- }
36
- const nested = ast._tag === "Objects" ? ast.indexSignatures.map((index) => index.type) : children(ast);
37
- return (ast.encoding?.some((link) => marked(link.to, seen)) ?? false) || nested.some((type) => marked(type, seen));
38
- }
39
- function containsSensitive(ast: SchemaAST.AST, keys: ReadonlySet<string>): boolean {
40
- return (
41
- marked(ast)
42
- || propertiesOf(ast).some((property) => typeof property.name === "string" && (keys.has(property.name) || isSensitiveKey(property.name)))
43
- );
44
- }
45
- export function collectEncodedKeys(ast: SchemaAST.AST, keys: Set<string>) {
46
- let source = ast;
47
- let sensitive = false;
48
- for (const link of ast.encoding ?? []) {
49
- sensitive ||= containsSensitive(source, keys);
50
- if (sensitive) {
51
- for (const property of propertiesOf(link.to)) {
52
- if (typeof property.name === "string") {
53
- keys.add(property.name);
54
- }
55
- }
56
- }
57
- source = link.to;
58
- }
59
- }
60
- function fixedOutput(ast: SchemaAST.AST): boolean {
61
- if (ast._tag === "Union") {
62
- return ast.types.every(fixedOutput);
63
- }
64
- return ast._tag === "Objects" && ast.indexSignatures.length === 0;
65
- }
66
- export function maskedValue(ast: SchemaAST.AST, keys: ReadonlySet<string>, seen = new Set<SchemaAST.AST>()): boolean {
67
- if (seen.has(ast)) {
68
- return false;
69
- }
70
- seen.add(ast);
71
- if (marked(ast)) {
72
- return true;
73
- }
74
- let source = ast;
75
- let sensitive = false;
76
- for (const link of ast.encoding ?? []) {
77
- sensitive ||= containsSensitive(source, keys);
78
- if (sensitive && !fixedOutput(link.to)) {
79
- return true;
80
- }
81
- source = link.to;
82
- }
83
- const nested = ast._tag === "Objects" ? ast.indexSignatures.map((index) => index.type) : children(ast);
84
- return nested.some((type) => maskedValue(type, keys, seen));
85
- }
86
- export function collect(ast: SchemaAST.AST, nodes: Set<SchemaAST.AST>, encodings = true) {
87
- if (nodes.has(ast)) {
88
- return;
89
- }
90
- nodes.add(ast);
91
- for (const child of [...children(ast), ...(encodings ? (ast.encoding?.map((link) => link.to) ?? []) : [])]) {
92
- collect(child, nodes, encodings);
93
- }
94
- }
95
- function propertiesOf(ast: SchemaAST.AST) {
96
- const nodes = new Set<SchemaAST.AST>();
97
- collect(ast, nodes, false);
98
- return [...nodes].flatMap((node) => (node._tag === "Objects" ? node.propertySignatures : []));
99
- }
100
- export function collectFieldKeys(properties: SchemaAST.Objects["propertySignatures"], keys: Set<string>, sensitive: (ast: SchemaAST.AST) => boolean) {
101
- for (const property of properties) {
102
- if (typeof property.name === "string" && sensitive(property.type)) {
103
- keys.add(property.name);
104
- }
105
- }
106
- }
@@ -1,49 +0,0 @@
1
- import type { Schema, SchemaAST } from "effect";
2
- import { Rpc, type RpcGroup } from "effect/rpc";
3
- import { isSensitiveKey } from "@shivaedev/errors/sensitive.ts";
4
- import { collect, collectEncodedKeys, collectFieldKeys, marked, maskedValue } from "#schemaSensitiveAst.ts";
5
-
6
- function rpcSensitiveKeys(rpc: Rpc.AnyWithProps, extra: readonly string[]) {
7
- const keys = new Set(extra);
8
- const nodes = new Set<SchemaAST.AST>();
9
- const schemas: Schema.Top[] = [
10
- rpc.payloadSchema,
11
- rpc.successSchema,
12
- rpc.errorSchema,
13
- rpc.defectSchema,
14
- ...[...rpc.middlewares].map((m) => m.error),
15
- ];
16
- for (const schema of schemas) {
17
- collect(schema.ast, nodes);
18
- }
19
- const properties = [...nodes].flatMap((ast) => (ast._tag === "Objects" ? ast.propertySignatures : []));
20
- collectFieldKeys(properties, keys, marked);
21
- let previousSize: number;
22
- do {
23
- previousSize = keys.size;
24
- collectFieldKeys(properties, keys, (ast) => maskedValue(ast, keys));
25
- for (const ast of nodes) {
26
- collectEncodedKeys(ast, keys);
27
- }
28
- } while (keys.size !== previousSize);
29
- return Object.assign((key: string) => keys.has(key) || isSensitiveKey(key), {
30
- die: maskedValue(rpc.defectSchema.ast, keys),
31
- fail: [rpc.errorSchema, ...[...rpc.middlewares].map((m) => m.error)].some((schema) => maskedValue(schema.ast, keys)),
32
- });
33
- }
34
- export function schemaSensitiveKeys<R extends Rpc.Any>(group: RpcGroup.RpcGroup<R>, extra: readonly string[] = []) {
35
- const policies = new Map<string, ReturnType<typeof rpcSensitiveKeys>>();
36
- for (const rpc of group.requests.values()) {
37
- if (Rpc.isRpc(rpc)) {
38
- policies.set(rpc._tag, rpcSensitiveKeys(rpc, extra));
39
- }
40
- }
41
- function sensitive(key: string) {
42
- return extra.includes(key) || isSensitiveKey(key) || [...policies.values()].some((policy) => policy(key));
43
- }
44
- return Object.assign(sensitive, {
45
- forRpc: (tag: string | undefined) => (tag === undefined ? sensitive : (policies.get(tag) ?? sensitive)),
46
- maskFailure: (tag: string | undefined, reason: "Fail" | "Die") =>
47
- [...policies].some(([method, policy]) => (tag === undefined || tag === method) && (reason === "Fail" ? policy.fail : policy.die)),
48
- });
49
- }