isthmus-cli 0.4.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 (104) hide show
  1. package/README.ko.md +64 -22
  2. package/README.md +70 -26
  3. package/Skills/isthmus/SKILL.md +93 -4
  4. package/dist/cli/check-command.d.ts +2 -25
  5. package/dist/cli/check-command.js +27 -181
  6. package/dist/cli/check-command.js.map +1 -1
  7. package/dist/cli/command-support.d.ts +48 -0
  8. package/dist/cli/command-support.js +144 -0
  9. package/dist/cli/command-support.js.map +1 -0
  10. package/dist/cli/diff-command.d.ts +1 -1
  11. package/dist/cli/diff-command.js +1 -1
  12. package/dist/cli/diff-command.js.map +1 -1
  13. package/dist/cli/graph-command.d.ts +1 -1
  14. package/dist/cli/graph-command.js +15 -14
  15. package/dist/cli/graph-command.js.map +1 -1
  16. package/dist/cli/impact-command.d.ts +5 -0
  17. package/dist/cli/impact-command.js +111 -0
  18. package/dist/cli/impact-command.js.map +1 -0
  19. package/dist/cli/main.js +35 -13
  20. package/dist/cli/main.js.map +1 -1
  21. package/dist/cli/parse-arguments.d.ts +18 -0
  22. package/dist/cli/parse-arguments.js +48 -0
  23. package/dist/cli/parse-arguments.js.map +1 -0
  24. package/dist/cli/preflight-command.d.ts +5 -0
  25. package/dist/cli/preflight-command.js +83 -0
  26. package/dist/cli/preflight-command.js.map +1 -0
  27. package/dist/cli/query-command.d.ts +1 -1
  28. package/dist/cli/query-command.js +30 -10
  29. package/dist/cli/query-command.js.map +1 -1
  30. package/dist/cli/retentions-command.d.ts +1 -1
  31. package/dist/cli/retentions-command.js +11 -10
  32. package/dist/cli/retentions-command.js.map +1 -1
  33. package/dist/cli/runtime-command.d.ts +5 -0
  34. package/dist/cli/runtime-command.js +42 -0
  35. package/dist/cli/runtime-command.js.map +1 -0
  36. package/dist/cli/runtime-json-reader.d.ts +12 -0
  37. package/dist/cli/runtime-json-reader.js +37 -0
  38. package/dist/cli/runtime-json-reader.js.map +1 -0
  39. package/dist/exchange/impact-selection.d.ts +13 -0
  40. package/dist/exchange/impact-selection.js +35 -0
  41. package/dist/exchange/impact-selection.js.map +1 -0
  42. package/dist/exchange/kartograph-impact.d.ts +4 -0
  43. package/dist/exchange/kartograph-impact.js +169 -0
  44. package/dist/exchange/kartograph-impact.js.map +1 -0
  45. package/dist/exchange/messages.d.ts +51 -0
  46. package/dist/exchange/messages.js +126 -0
  47. package/dist/exchange/messages.js.map +1 -0
  48. package/dist/exchange/parse.d.ts +8 -0
  49. package/dist/exchange/parse.js +12 -8
  50. package/dist/exchange/parse.js.map +1 -1
  51. package/dist/exchange/preflight-context.d.ts +71 -0
  52. package/dist/exchange/preflight-context.js +317 -0
  53. package/dist/exchange/preflight-context.js.map +1 -0
  54. package/dist/exchange/producer-impact.d.ts +17 -0
  55. package/dist/exchange/producer-impact.js +226 -0
  56. package/dist/exchange/producer-impact.js.map +1 -0
  57. package/dist/exchange/runtime.d.ts +69 -0
  58. package/dist/exchange/runtime.js +160 -0
  59. package/dist/exchange/runtime.js.map +1 -0
  60. package/dist/join/message-address.d.ts +7 -0
  61. package/dist/join/message-address.js +37 -0
  62. package/dist/join/message-address.js.map +1 -0
  63. package/dist/join/messages.d.ts +23 -0
  64. package/dist/join/messages.js +80 -0
  65. package/dist/join/messages.js.map +1 -0
  66. package/dist/report/diff.d.ts +40 -33
  67. package/dist/report/diff.js +8 -4
  68. package/dist/report/diff.js.map +1 -1
  69. package/dist/report/impact.d.ts +62 -0
  70. package/dist/report/impact.js +168 -0
  71. package/dist/report/impact.js.map +1 -0
  72. package/dist/report/preflight-runtime.d.ts +42 -0
  73. package/dist/report/preflight-runtime.js +193 -0
  74. package/dist/report/preflight-runtime.js.map +1 -0
  75. package/dist/report/preflight-view.d.ts +146 -0
  76. package/dist/report/preflight-view.js +189 -0
  77. package/dist/report/preflight-view.js.map +1 -0
  78. package/dist/report/preflight.d.ts +104 -0
  79. package/dist/report/preflight.js +296 -0
  80. package/dist/report/preflight.js.map +1 -0
  81. package/dist/report/query.js +9 -2
  82. package/dist/report/query.js.map +1 -1
  83. package/dist/report/runtime-impact.d.ts +38 -0
  84. package/dist/report/runtime-impact.js +94 -0
  85. package/dist/report/runtime-impact.js.map +1 -0
  86. package/dist/report/runtime.d.ts +54 -0
  87. package/dist/report/runtime.js +137 -0
  88. package/dist/report/runtime.js.map +1 -0
  89. package/dist/report/sarif.d.ts +9 -2
  90. package/dist/report/sarif.js +4 -10
  91. package/dist/report/sarif.js.map +1 -1
  92. package/dist/report/sorted-json.d.ts +1 -1
  93. package/dist/report/sorted-json.js +2 -2
  94. package/dist/report/sorted-json.js.map +1 -1
  95. package/docs/BRIDGE-MESSAGES.md +102 -0
  96. package/docs/GRAPH-EXCHANGE.md +255 -0
  97. package/docs/IMPACT.md +96 -0
  98. package/docs/PREFLIGHT.md +295 -0
  99. package/docs/RUNTIME.md +172 -0
  100. package/docs/TOOLCHAIN.md +101 -0
  101. package/package.json +11 -2
  102. package/scripts/build-preflight-toolchain.mjs +186 -0
  103. package/scripts/capture-preflight.mjs +392 -0
  104. package/scripts/run-child.mjs +16 -0
@@ -0,0 +1,126 @@
1
+ import { BridgeFactsValidationError, isBridgeTimestamp, isSafeNonEmptyString, MAX_FACTS_PER_DOCUMENT, validateLocation, validateSourceLanguage, validateSymbol } from "./parse.js";
2
+ /** 입력 묶음의 역할·프로젝트 범위를 값 조인 없이 검증한다. */
3
+ export function validateMessageDocuments(documents, project) {
4
+ if (documents.length === 0)
5
+ return;
6
+ if (documents.length > 256 || documents.some((document) => document.project !== project) ||
7
+ !documents.some(({ platform }) => platform === 'dart') || !documents.some(({ platform }) => platform === 'swift' || platform === 'kotlin')) {
8
+ fail('Message inputs require Dart and native documents for the same project.');
9
+ }
10
+ }
11
+ /** Basic 전용 v2를 검증하고 알려진 필드만 복사한다. v1 입력 파서는 그대로 유지한다. */
12
+ export function parseMessageBridgeDocument(input) {
13
+ const value = object(input);
14
+ if (value.format !== 'bridge-facts' || value.version !== 2 || value.transport !== 'basic-message-channel') {
15
+ fail('Expected bridge-facts version 2 for basic-message-channel.');
16
+ }
17
+ if (value.platform !== 'dart' && value.platform !== 'swift' && value.platform !== 'kotlin')
18
+ fail('Unsupported message bridge platform.');
19
+ if (!Array.isArray(value.facts) || value.facts.length > MAX_FACTS_PER_DOCUMENT)
20
+ fail('Invalid message bridge fact count.');
21
+ if (value.target !== (value.facts.length ? 'flutter' : null))
22
+ fail('Invalid message bridge target.');
23
+ if (!isBridgeTimestamp(value.generatedAt))
24
+ fail('Invalid message bridge timestamp.');
25
+ const project = safe(value.project);
26
+ const tool = object(value.tool);
27
+ const limitations = value.limitations;
28
+ if (!Array.isArray(limitations) || !limitations.every((item) => typeof item === 'string'))
29
+ fail('Invalid message bridge limitations.');
30
+ let dependencyCount = 0;
31
+ const consumeDependencies = (count) => {
32
+ dependencyCount += count;
33
+ if (dependencyCount > 1_000_000)
34
+ fail('Message dependency budget exceeded.');
35
+ };
36
+ const facts = value.facts.map((item, index) => {
37
+ const fact = object(item);
38
+ const expectedKind = value.platform === 'dart' ? 'message-send' : 'message-handle';
39
+ if (fact.kind !== expectedKind || fact.method !== undefined)
40
+ fail('Invalid message bridge fact kind or method.');
41
+ if (fact.channel === null ? fact.kind !== 'message-handle' : !isSafeNonEmptyString(fact.channel))
42
+ fail('Invalid message bridge channel.');
43
+ if (typeof fact.dynamic !== 'boolean')
44
+ fail('Invalid message bridge dynamic flag.');
45
+ if (fact.channelPrefix !== undefined && (!fact.dynamic || fact.channel === null || !isSafeNonEmptyString(fact.channelPrefix))) {
46
+ fail('Message prefix requires a dynamic channel and a non-empty proven prefix.');
47
+ }
48
+ validateLocation(fact.location, index);
49
+ validateSymbol(fact.symbol, index);
50
+ const location = fact.location;
51
+ const symbol = fact.symbol;
52
+ validateSourceLanguage(fact.sourceLanguage, value.platform, location, symbol, index);
53
+ let handlerScope;
54
+ let dependencies;
55
+ if (fact.handlerScope !== undefined || fact.dependencies !== undefined) {
56
+ if (expectedKind !== 'message-handle' || fact.sourceLanguage !== undefined)
57
+ fail('Handler dependencies require a native message handler.');
58
+ const scope = object(fact.handlerScope);
59
+ const start = copyLocation(scope.start, index);
60
+ const end = copyLocation(scope.end, index);
61
+ if (typeof scope.complete !== 'boolean' || start.path !== location.path || end.path !== location.path ||
62
+ position(start, end) > 0 || (scope.complete && symbol?.usr === undefined))
63
+ fail('Invalid message handler scope.');
64
+ handlerScope = { start, end, complete: scope.complete };
65
+ const raw = dependencyArray(fact.dependencies);
66
+ consumeDependencies(raw.length);
67
+ dependencies = raw.map((input) => {
68
+ const row = object(input);
69
+ if ((row.kind !== 'call' && row.kind !== 'reference') || (row.scope !== 'handler' && row.scope !== 'registration')) {
70
+ fail('Invalid message dependency kind or scope.');
71
+ }
72
+ const at = copyLocation(row.location, index);
73
+ const inside = position(start, at) <= 0 && position(at, end) <= 0;
74
+ if (at.path !== location.path || inside !== (row.scope === 'handler'))
75
+ fail('Message dependency is outside its declared scope.');
76
+ const dispatch = row.dispatchTargets === undefined ? undefined : dependencyArray(row.dispatchTargets);
77
+ consumeDependencies(dispatch?.length ?? 0);
78
+ return { kind: row.kind, scope: row.scope, location: at, symbol: indexedSymbol(row.symbol, index),
79
+ ...(dispatch === undefined ? {} : { dispatchTargets: dispatch.map((target) => indexedSymbol(target, index)) }) };
80
+ });
81
+ }
82
+ return { kind: expectedKind, channel: fact.channel, dynamic: fact.dynamic,
83
+ location: { path: location.path, line: location.line, column: location.column },
84
+ ...(fact.channelPrefix === undefined ? {} : { channelPrefix: fact.channelPrefix }),
85
+ ...(symbol === undefined ? {} : { symbol: { qualifiedName: symbol.qualifiedName, ...(symbol.usr === undefined ? {} : { usr: symbol.usr }) } }),
86
+ ...(fact.sourceLanguage === undefined ? {} : { sourceLanguage: fact.sourceLanguage }),
87
+ ...(handlerScope === undefined ? {} : { handlerScope, dependencies: dependencies }),
88
+ };
89
+ });
90
+ if (facts.some((fact) => fact.channel === null) && !limitations.some((item) => item.startsWith('unattributed-message-handles:'))) {
91
+ fail('Unattributed message handles require a limitation.');
92
+ }
93
+ return { format: 'bridge-facts', version: 2, transport: 'basic-message-channel', platform: value.platform,
94
+ target: facts.length ? 'flutter' : null, project, generatedAt: value.generatedAt,
95
+ tool: { name: safe(tool.name), version: safe(tool.version) }, facts, limitations: [...limitations] };
96
+ }
97
+ function copyLocation(input, index) {
98
+ validateLocation(input, index);
99
+ const at = input;
100
+ return { path: at.path, line: at.line, column: at.column };
101
+ }
102
+ function indexedSymbol(input, index) {
103
+ validateSymbol(input, index);
104
+ const symbol = object(input);
105
+ return { qualifiedName: safe(symbol.qualifiedName), usr: safe(symbol.usr) };
106
+ }
107
+ function dependencyArray(input) {
108
+ if (!Array.isArray(input) || input.length > 10_000)
109
+ fail('Invalid message dependency count.');
110
+ return input;
111
+ }
112
+ function position(a, b) {
113
+ return a.line - b.line || a.column - b.column;
114
+ }
115
+ function object(value) {
116
+ if (value === null || typeof value !== 'object' || Array.isArray(value))
117
+ fail('Message bridge input must be a JSON object.');
118
+ return value;
119
+ }
120
+ function safe(value) {
121
+ if (!isSafeNonEmptyString(value))
122
+ fail('Invalid message bridge metadata.');
123
+ return value;
124
+ }
125
+ function fail(message) { throw new BridgeFactsValidationError(message); }
126
+ //# sourceMappingURL=messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/exchange/messages.ts"],"names":[],"mappings":"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","sourcesContent":["import { BridgeFactsValidationError, isBridgeTimestamp, isSafeNonEmptyString, MAX_FACTS_PER_DOCUMENT,\n validateLocation, validateSourceLanguage, validateSymbol } from './parse.ts';\nimport type { BridgeLocation, BridgeSourceLanguage, BridgeSymbol } from './parse.ts';\n\n/** producer가 관찰한 사용 관계를 귀속한 실제 native handler 범위다. */\nexport interface BridgeHandlerScope {\n readonly start: BridgeLocation;\n readonly end: BridgeLocation;\n readonly complete: boolean;\n}\n\n/** 실제 참조 위치와 대상, index의 overrides로 확인한 dispatch 후보를 보존한다. */\nexport interface BridgeHandlerDependency {\n readonly kind: 'call' | 'reference';\n readonly scope: 'handler' | 'registration';\n readonly location: BridgeLocation;\n readonly symbol: BridgeSymbol & { readonly usr: string };\n readonly dispatchTargets?: readonly (BridgeSymbol & { readonly usr: string })[];\n}\n\n/** Basic 채널의 send·handler 사실이며 MethodChannel 메서드를 합성하지 않는다. */\nexport interface BridgeMessageFact {\n readonly kind: 'message-send' | 'message-handle';\n readonly channel: string | null;\n readonly dynamic: boolean;\n readonly channelPrefix?: string;\n readonly location: BridgeLocation;\n readonly symbol?: BridgeSymbol;\n readonly sourceLanguage?: BridgeSourceLanguage;\n readonly handlerScope?: BridgeHandlerScope;\n readonly dependencies?: readonly BridgeHandlerDependency[];\n}\n\n/** v1 전용 소비자가 조용히 무시하지 못하도록 별도 버전으로 전달하는 Basic 문서다. */\nexport interface BridgeMessageDocument {\n readonly format: 'bridge-facts';\n readonly version: 2;\n readonly transport: 'basic-message-channel';\n readonly platform: 'dart' | 'swift' | 'kotlin';\n readonly target: 'flutter' | null;\n readonly project: string;\n readonly generatedAt: string;\n readonly tool: { readonly name: string; readonly version: string };\n readonly facts: readonly BridgeMessageFact[];\n readonly limitations: readonly string[];\n}\n\n/** 입력 묶음의 역할·프로젝트 범위를 값 조인 없이 검증한다. */\nexport function validateMessageDocuments(documents: readonly BridgeMessageDocument[], project: string): void {\n if (documents.length === 0) return;\n if (documents.length > 256 || documents.some((document) => document.project !== project) ||\n !documents.some(({ platform }) => platform === 'dart') || !documents.some(({ platform }) => platform === 'swift' || platform === 'kotlin')) {\n fail('Message inputs require Dart and native documents for the same project.');\n }\n}\n\n/** Basic 전용 v2를 검증하고 알려진 필드만 복사한다. v1 입력 파서는 그대로 유지한다. */\nexport function parseMessageBridgeDocument(input: unknown): BridgeMessageDocument {\n const value = object(input);\n if (value.format !== 'bridge-facts' || value.version !== 2 || value.transport !== 'basic-message-channel') {\n fail('Expected bridge-facts version 2 for basic-message-channel.');\n }\n if (value.platform !== 'dart' && value.platform !== 'swift' && value.platform !== 'kotlin') fail('Unsupported message bridge platform.');\n if (!Array.isArray(value.facts) || value.facts.length > MAX_FACTS_PER_DOCUMENT) fail('Invalid message bridge fact count.');\n if (value.target !== (value.facts.length ? 'flutter' : null)) fail('Invalid message bridge target.');\n if (!isBridgeTimestamp(value.generatedAt)) fail('Invalid message bridge timestamp.');\n const project = safe(value.project);\n const tool = object(value.tool);\n const limitations = value.limitations;\n if (!Array.isArray(limitations) || !limitations.every((item) => typeof item === 'string')) fail('Invalid message bridge limitations.');\n let dependencyCount = 0;\n const consumeDependencies = (count: number): void => {\n dependencyCount += count;\n if (dependencyCount > 1_000_000) fail('Message dependency budget exceeded.');\n };\n const facts = value.facts.map((item, index): BridgeMessageFact => {\n const fact = object(item);\n const expectedKind = value.platform === 'dart' ? 'message-send' : 'message-handle';\n if (fact.kind !== expectedKind || fact.method !== undefined) fail('Invalid message bridge fact kind or method.');\n if (fact.channel === null ? fact.kind !== 'message-handle' : !isSafeNonEmptyString(fact.channel)) fail('Invalid message bridge channel.');\n if (typeof fact.dynamic !== 'boolean') fail('Invalid message bridge dynamic flag.');\n if (fact.channelPrefix !== undefined && (!fact.dynamic || fact.channel === null || !isSafeNonEmptyString(fact.channelPrefix))) {\n fail('Message prefix requires a dynamic channel and a non-empty proven prefix.');\n }\n validateLocation(fact.location, index);\n validateSymbol(fact.symbol, index);\n const location = fact.location as BridgeLocation;\n const symbol = fact.symbol as BridgeSymbol | undefined;\n validateSourceLanguage(fact.sourceLanguage, value.platform, location, symbol, index);\n let handlerScope: BridgeHandlerScope | undefined;\n let dependencies: readonly BridgeHandlerDependency[] | undefined;\n if (fact.handlerScope !== undefined || fact.dependencies !== undefined) {\n if (expectedKind !== 'message-handle' || fact.sourceLanguage !== undefined) fail('Handler dependencies require a native message handler.');\n const scope = object(fact.handlerScope);\n const start = copyLocation(scope.start, index);\n const end = copyLocation(scope.end, index);\n if (typeof scope.complete !== 'boolean' || start.path !== location.path || end.path !== location.path ||\n position(start, end) > 0 || (scope.complete && symbol?.usr === undefined)) fail('Invalid message handler scope.');\n handlerScope = { start, end, complete: scope.complete };\n const raw = dependencyArray(fact.dependencies);\n consumeDependencies(raw.length);\n dependencies = raw.map((input): BridgeHandlerDependency => {\n const row = object(input);\n if ((row.kind !== 'call' && row.kind !== 'reference') || (row.scope !== 'handler' && row.scope !== 'registration')) {\n fail('Invalid message dependency kind or scope.');\n }\n const at = copyLocation(row.location, index);\n const inside = position(start, at) <= 0 && position(at, end) <= 0;\n if (at.path !== location.path || inside !== (row.scope === 'handler')) fail('Message dependency is outside its declared scope.');\n const dispatch = row.dispatchTargets === undefined ? undefined : dependencyArray(row.dispatchTargets);\n consumeDependencies(dispatch?.length ?? 0);\n return { kind: row.kind, scope: row.scope, location: at, symbol: indexedSymbol(row.symbol, index),\n ...(dispatch === undefined ? {} : { dispatchTargets: dispatch.map((target) => indexedSymbol(target, index)) }) };\n });\n }\n return { kind: expectedKind, channel: fact.channel as string | null, dynamic: fact.dynamic,\n location: { path: location.path, line: location.line, column: location.column },\n ...(fact.channelPrefix === undefined ? {} : { channelPrefix: fact.channelPrefix as string }),\n ...(symbol === undefined ? {} : { symbol: { qualifiedName: symbol.qualifiedName, ...(symbol.usr === undefined ? {} : { usr: symbol.usr }) } }),\n ...(fact.sourceLanguage === undefined ? {} : { sourceLanguage: fact.sourceLanguage as BridgeSourceLanguage }),\n ...(handlerScope === undefined ? {} : { handlerScope, dependencies: dependencies! }),\n };\n });\n if (facts.some((fact) => fact.channel === null) && !limitations.some((item) => item.startsWith('unattributed-message-handles:'))) {\n fail('Unattributed message handles require a limitation.');\n }\n return { format: 'bridge-facts', version: 2, transport: 'basic-message-channel', platform: value.platform,\n target: facts.length ? 'flutter' : null, project, generatedAt: value.generatedAt,\n tool: { name: safe(tool.name), version: safe(tool.version) }, facts, limitations: [...limitations] };\n}\n\nfunction copyLocation(input: unknown, index: number): BridgeLocation {\n validateLocation(input, index);\n const at = input as BridgeLocation;\n return { path: at.path, line: at.line, column: at.column };\n}\nfunction indexedSymbol(input: unknown, index: number): BridgeSymbol & { readonly usr: string } {\n validateSymbol(input, index);\n const symbol = object(input);\n return { qualifiedName: safe(symbol.qualifiedName), usr: safe(symbol.usr) };\n}\nfunction dependencyArray(input: unknown): unknown[] {\n if (!Array.isArray(input) || input.length > 10_000) fail('Invalid message dependency count.');\n return input;\n}\nfunction position(a: BridgeLocation, b: BridgeLocation): number {\n return a.line - b.line || a.column - b.column;\n}\n\nfunction object(value: unknown): Record<string, unknown> {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) fail('Message bridge input must be a JSON object.');\n return value as Record<string, unknown>;\n}\nfunction safe(value: unknown): string {\n if (!isSafeNonEmptyString(value)) fail('Invalid message bridge metadata.');\n return value as string;\n}\nfunction fail(message: string): never { throw new BridgeFactsValidationError(message); }\n"]}
@@ -68,6 +68,14 @@ export declare function isReceiverPlatform(platform: unknown): platform is 'swif
68
68
  export declare function isBridgeTarget(value: unknown): value is BridgeTarget;
69
69
  /** 조인 키를 깨뜨리는 제어 문자가 없는 비어 있지 않은 문자열인지 확인한다. */
70
70
  export declare function isSafeNonEmptyString(value: unknown): value is string;
71
+ /** 사실 위치가 상대 경로와 1부터 시작하는 줄·열을 갖는지 검증한다. */
72
+ export declare function validateLocation(value: unknown, index: number): void;
73
+ /** 절대·상위 경로와 제어 문자를 제외한 프로젝트 상대 경로인지 확인한다. */
74
+ export declare function isProjectRelativePath(value: unknown): value is string;
75
+ /** 선택 symbol의 이름과 USR이 비어 있지 않은지 검증한다. */
76
+ export declare function validateSymbol(value: unknown, index: number): void;
77
+ /** 교환 계약별 파서가 Objective-C 출처·경로·실제 Clang 신원 규칙을 공유한다. */
78
+ export declare function validateSourceLanguage(value: unknown, platform: unknown, location: BridgeLocation, symbol: BridgeSymbol | undefined, index: number): void;
71
79
  /** ISO 계열 생성 시각으로 해석할 수 있는지 확인한다. */
72
80
  export declare function isBridgeTimestamp(value: unknown): value is string;
73
81
  /** 배열과 null을 제외한 JSON 객체인지 확인한다. isthmus 소유 문서 검증도 재사용한다. */
@@ -153,11 +153,7 @@ function validateFact(value, index, platform) {
153
153
  fail(`Invalid dynamic flag at index ${index}.`);
154
154
  validateLocation(value.location, index);
155
155
  validateSymbol(value.symbol, index);
156
- if (value.sourceLanguage !== undefined && (value.sourceLanguage !== 'objective-c' || platform !== 'swift' ||
157
- !/\.(?:m|mm)$/u.test(value.location.path) ||
158
- (value.symbol !== undefined && value.symbol.usr !== undefined &&
159
- !value.symbol.usr?.startsWith('c:'))))
160
- fail(`Invalid source language at index ${index}.`);
156
+ validateSourceLanguage(value.sourceLanguage, platform, value.location, value.symbol, index);
161
157
  }
162
158
  /** 호출 측과 수신 측 플랫폼이 생산할 수 있는 fact 종류인지 확인한다. */
163
159
  function isFactKindForPlatform(platform, kind) {
@@ -190,7 +186,7 @@ function hasUnpairedSurrogate(value) {
190
186
  return value.toWellFormed() !== value;
191
187
  }
192
188
  /** 사실 위치가 상대 경로와 1부터 시작하는 줄·열을 갖는지 검증한다. */
193
- function validateLocation(value, index) {
189
+ export function validateLocation(value, index) {
194
190
  if (!isJsonObject(value) ||
195
191
  !isProjectRelativePath(value.path) ||
196
192
  !isPositiveInteger(value.line) ||
@@ -199,7 +195,7 @@ function validateLocation(value, index) {
199
195
  }
200
196
  }
201
197
  /** 절대·상위 경로와 제어 문자를 제외한 프로젝트 상대 경로인지 확인한다. */
202
- function isProjectRelativePath(value) {
198
+ export function isProjectRelativePath(value) {
203
199
  if (!isNonEmptyString(value))
204
200
  return false;
205
201
  if (/^(?:[/\\]|[A-Za-z]:)/u.test(value))
@@ -210,7 +206,7 @@ function isProjectRelativePath(value) {
210
206
  return !value.split(/[/\\]/u).includes('..');
211
207
  }
212
208
  /** 선택 symbol의 이름과 USR이 비어 있지 않은지 검증한다. */
213
- function validateSymbol(value, index) {
209
+ export function validateSymbol(value, index) {
214
210
  if (value === undefined)
215
211
  return;
216
212
  if (!isJsonObject(value) ||
@@ -219,6 +215,14 @@ function validateSymbol(value, index) {
219
215
  fail(`Invalid fact symbol at index ${index}.`);
220
216
  }
221
217
  }
218
+ /** 교환 계약별 파서가 Objective-C 출처·경로·실제 Clang 신원 규칙을 공유한다. */
219
+ export function validateSourceLanguage(value, platform, location, symbol, index) {
220
+ if (value !== undefined && (value !== 'objective-c' || platform !== 'swift' ||
221
+ !/\.(?:m|mm)$/u.test(location.path) ||
222
+ (symbol?.usr !== undefined && !symbol.usr.startsWith('c:')))) {
223
+ fail(`Invalid source language at index ${index}.`);
224
+ }
225
+ }
222
226
  /** 생산 도구 이름과 버전이 비어 있지 않은지 검증한다. */
223
227
  function validateTool(value) {
224
228
  if (!isJsonObject(value) ||
@@ -1 +1 @@
1
- {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/exchange/parse.ts"],"names":[],"mappings":"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","sourcesContent":["/** bridge-facts 생산 플랫폼이다. */\nexport type BridgePlatform = 'dart' | 'swift' | 'kotlin' | 'js';\n\n/** 언어 경계를 잇는 메커니즘이다. */\nexport type BridgeTarget = 'flutter' | 'react-native' | 'capacitor';\n\n/** Swift 플랫폼 문서에 실린 Objective-C 구현을 Swift 보존 대상과 구분한다. */\nexport type BridgeSourceLanguage = 'objective-c';\n\n/** 특정 한계 전체의 영향을 포함하는 채널 집합. 일부 발견 목록이 아니다. */\nexport interface BridgeLimitationScope {\n readonly limitationIndex: number;\n readonly channels: readonly string[];\n}\n\n/** 확장 메타데이터가 입력 자원 상한을 우회하지 못하게 한다. */\nexport const MAX_LIMITATION_SCOPES = 1_000;\nexport const MAX_SCOPED_CHANNELS = 10_000;\n\n/** 교환 형식의 사실 종류다. */\nexport type BridgeFactKind =\n | 'channel-create'\n | 'channel-register'\n | 'method-invoke'\n | 'method-handle'\n | 'module-export'\n | 'module-import'\n | 'component-export'\n | 'component-require';\n\n/** 한 생산 문서가 담을 수 있는 최대 사실 수다. */\nexport const MAX_FACTS_PER_DOCUMENT = 100_000;\n\n/** 사실의 프로젝트 상대 소스 위치다. */\nexport interface BridgeLocation {\n readonly path: string;\n readonly line: number;\n readonly column: number;\n}\n\n/** 사실을 감싸는 언어별 선언 식별자다. */\nexport interface BridgeSymbol {\n readonly qualifiedName: string;\n readonly usr?: string;\n}\n\n/** 생산 도구 하나가 관찰한 언어 경계 사실이다. */\nexport interface BridgeFact {\n readonly kind: BridgeFactKind;\n readonly channel: string | null;\n readonly method?: string;\n readonly dynamic: boolean;\n readonly location: BridgeLocation;\n readonly symbol?: BridgeSymbol;\n readonly sourceLanguage?: BridgeSourceLanguage;\n}\n\n/** bridge-facts 버전 1 문서다. */\nexport interface BridgeFactsDocument {\n readonly format: 'bridge-facts';\n readonly version: 1;\n readonly tool: Readonly<{ name: string; version: string }>;\n readonly generatedAt: string;\n readonly platform: BridgePlatform;\n readonly target: BridgeTarget | null;\n readonly project: string;\n readonly facts: readonly BridgeFact[];\n readonly limitations: readonly string[];\n readonly limitationScopes?: readonly BridgeLimitationScope[];\n}\n\n/** 외부 교환 문서가 v1 계약을 어겼음을 나타낸다. */\nexport class BridgeFactsValidationError extends Error {\n /** 입력 내용을 노출하지 않는 안전한 메시지를 보존한다. */\n constructor(message: string) {\n super(message);\n this.name = 'BridgeFactsValidationError';\n }\n}\n\n/** 신뢰하지 않는 JSON 값을 검증된 bridge-facts v1 문서로 바꾼다. */\nexport function parseBridgeFactsDocument(input: unknown): BridgeFactsDocument {\n if (!isJsonObject(input)) {\n throw new BridgeFactsValidationError(\n 'Bridge facts must be a JSON object.',\n );\n }\n if (input.format !== 'bridge-facts') {\n throw new BridgeFactsValidationError('Expected format \"bridge-facts\".');\n }\n if (input.version !== 1) {\n throw new BridgeFactsValidationError(\n 'Unsupported bridge-facts version; expected version 1.',\n );\n }\n validateDocumentMetadata(input);\n return normalizeDocument(input);\n}\n\n/** 검증된 입력에서 v1 허용 필드만 복사해 신뢰 경계 밖 데이터를 제거한다. */\nfunction normalizeDocument(document: BridgeFactsDocument): BridgeFactsDocument {\n return {\n format: 'bridge-facts',\n version: 1,\n tool: { name: document.tool.name, version: document.tool.version },\n generatedAt: document.generatedAt,\n platform: document.platform,\n target: document.target,\n project: document.project,\n facts: document.facts.map(normalizeFact),\n limitations: [...document.limitations],\n ...(document.limitationScopes === undefined ? {} : {\n limitationScopes: document.limitationScopes.map((scope) => ({\n limitationIndex: scope.limitationIndex,\n channels: [...new Set(scope.channels)].sort(),\n })).sort((a, b) => a.limitationIndex - b.limitationIndex),\n }),\n };\n}\n\n/** 사실과 중첩 위치·심볼에서 계약 필드만 보존한다. */\nfunction normalizeFact(fact: BridgeFact): BridgeFact {\n const symbol = fact.symbol === undefined\n ? {}\n : {\n symbol: {\n qualifiedName: fact.symbol.qualifiedName,\n ...(fact.symbol.usr === undefined ? {} : { usr: fact.symbol.usr }),\n },\n };\n return {\n kind: fact.kind,\n channel: fact.channel,\n ...(fact.method === undefined ? {} : { method: fact.method }),\n dynamic: fact.dynamic,\n location: {\n path: fact.location.path,\n line: fact.location.line,\n column: fact.location.column,\n },\n ...symbol,\n ...(fact.sourceLanguage === undefined ? {} : { sourceLanguage: fact.sourceLanguage }),\n };\n}\n\n/** 문서 수준 필드가 v1 타입과 허용값을 따르는지 검증한다. */\nfunction validateDocumentMetadata(\n document: Record<string, unknown>,\n): asserts document is Record<string, unknown> & BridgeFactsDocument {\n validateTool(document.tool);\n if (!isBridgeTimestamp(document.generatedAt)) fail('Invalid generatedAt timestamp.');\n if (!bridgePlatforms.has(document.platform)) fail('Unsupported bridge platform.');\n if (document.target !== null && !bridgeTargets.has(document.target)) {\n fail('Unsupported bridge target.');\n }\n if (!isSafeNonEmptyString(document.project)) fail('Invalid project path.');\n if (!Array.isArray(document.facts)) fail('Facts must be an array.');\n if (document.facts.length > MAX_FACTS_PER_DOCUMENT) {\n fail(`Facts exceed the ${MAX_FACTS_PER_DOCUMENT} item limit.`);\n }\n document.facts.forEach((fact, index) =>\n validateFact(fact, index, document.platform),\n );\n if ((document.target === null) !== (document.facts.length === 0)) {\n fail('Target must be set exactly when facts are present.');\n }\n if (!isStringArray(document.limitations)) fail('Limitations must be strings.');\n validateLimitationScopes(document.limitationScopes, document.limitations.length);\n const hasUnattributedHandler = document.facts.some(\n (fact) =>\n isJsonObject(fact) &&\n fact.kind === 'method-handle' &&\n fact.channel === null,\n );\n if (\n hasUnattributedHandler &&\n !document.limitations.some((message) =>\n message.startsWith('unattributed-method-handles:'))\n ) {\n fail('Unattributed method handles require a limitation.');\n }\n}\n\n/** 잘못된 범위를 무시하면 거짓 error가 생기므로 입력 단계에서 명시적으로 거부한다. */\nfunction validateLimitationScopes(value: unknown, limitationCount: number): void {\n if (value === undefined) return;\n if (!Array.isArray(value) || value.length > MAX_LIMITATION_SCOPES) {\n fail('Invalid limitation scopes array.');\n }\n const indices = new Set<number>();\n let channelCount = 0;\n for (const entry of value) {\n if (!isJsonObject(entry) || !Number.isSafeInteger(entry.limitationIndex) ||\n typeof entry.limitationIndex !== 'number' || entry.limitationIndex < 0 ||\n entry.limitationIndex >= limitationCount || indices.has(entry.limitationIndex)) {\n fail('Invalid or duplicate limitation scope index.');\n }\n if (!Array.isArray(entry.channels) || entry.channels.length === 0 ||\n !entry.channels.every(isSafeNonEmptyString)) {\n fail('Limitation scope channels must be non-empty safe strings.');\n }\n channelCount += entry.channels.length;\n if (channelCount > MAX_SCOPED_CHANNELS) fail('Too many scoped channels.');\n indices.add(entry.limitationIndex);\n }\n}\n\n/** 사실 하나의 조인 키와 증거 필드를 검증한다. */\nfunction validateFact(value: unknown, index: number, platform: unknown): void {\n if (!isJsonObject(value)) fail(`Fact at index ${index} must be a JSON object.`);\n if (!bridgeFactKinds.has(value.kind)) fail(`Invalid fact kind at index ${index}.`);\n if (!supportedBridgeFactKinds.has(value.kind)) {\n fail(`Fact kind is reserved but not supported by this isthmus version at index ${index}.`);\n }\n if (!isFactKindForPlatform(platform, value.kind)) {\n fail(`Fact kind is not valid for platform at index ${index}.`);\n }\n if (!methodFactKinds.has(value.kind) && value.method !== undefined) {\n fail(`Unexpected method at index ${index}.`);\n }\n if (\n value.channel === null\n ? value.kind !== 'method-handle'\n : !isSafeNonEmptyString(value.channel)\n ) {\n fail(`Invalid fact channel at index ${index}.`);\n }\n if (methodFactKinds.has(value.kind) && !isSafeNonEmptyString(value.method)) {\n fail(`Method fact at index ${index} requires a method name.`);\n }\n if (typeof value.dynamic !== 'boolean') fail(`Invalid dynamic flag at index ${index}.`);\n validateLocation(value.location, index);\n validateSymbol(value.symbol, index);\n if (value.sourceLanguage !== undefined && (\n value.sourceLanguage !== 'objective-c' || platform !== 'swift' ||\n !/\\.(?:m|mm)$/u.test((value.location as BridgeLocation).path) ||\n (value.symbol !== undefined && (value.symbol as BridgeSymbol).usr !== undefined &&\n !(value.symbol as BridgeSymbol).usr?.startsWith('c:'))\n )) fail(`Invalid source language at index ${index}.`);\n}\n\n/** 호출 측과 수신 측 플랫폼이 생산할 수 있는 fact 종류인지 확인한다. */\nfunction isFactKindForPlatform(platform: unknown, kind: unknown): boolean {\n return isCallerPlatform(platform)\n ? callerFactKinds.has(kind)\n : receiverFactKinds.has(kind);\n}\n\n/** 브리지 호출 측 사실을 생산하는 플랫폼인지 확인한다. */\nexport function isCallerPlatform(platform: unknown): platform is 'dart' | 'js' {\n return platform === 'dart' || platform === 'js';\n}\n\n/** 브리지 수신 측 사실을 생산하는 플랫폼인지 확인한다. */\nexport function isReceiverPlatform(\n platform: unknown,\n): platform is 'swift' | 'kotlin' {\n return platform === 'swift' || platform === 'kotlin';\n}\n\n/** 값이 계약이 정한 브리지 메커니즘 이름인지 확인한다. */\nexport function isBridgeTarget(value: unknown): value is BridgeTarget {\n return bridgeTargets.has(value);\n}\n\n/** 조인 키를 깨뜨리는 제어 문자가 없는 비어 있지 않은 문자열인지 확인한다. */\nexport function isSafeNonEmptyString(value: unknown): value is string {\n return isNonEmptyString(value) && !controlCharacterPattern.test(value) &&\n !hasUnpairedSurrogate(value);\n}\n\n/** 유효한 UTF-16 문자열인지, 즉 짝 없는 서러게이트가 없는지 확인한다. */\nfunction hasUnpairedSurrogate(value: string): boolean {\n // 아스트랄 문자(이모지 등)는 유효한 서러게이트 쌍이므로 그대로 통과한다.\n // 짝 없는 서러게이트는 어떤 인코딩의 파일에도 존재할 수 없어 JSON 이스케이프로만\n // 들어오며, URI 인코딩이 실패하는 등 소비 경로마다 깨진다.\n return value.toWellFormed() !== value;\n}\n\n/** 사실 위치가 상대 경로와 1부터 시작하는 줄·열을 갖는지 검증한다. */\nfunction validateLocation(value: unknown, index: number): void {\n if (\n !isJsonObject(value) ||\n !isProjectRelativePath(value.path) ||\n !isPositiveInteger(value.line) ||\n !isPositiveInteger(value.column)\n ) {\n fail(`Invalid fact location at index ${index}.`);\n }\n}\n\n/** 절대·상위 경로와 제어 문자를 제외한 프로젝트 상대 경로인지 확인한다. */\nfunction isProjectRelativePath(value: unknown): value is string {\n if (!isNonEmptyString(value)) return false;\n if (/^(?:[/\\\\]|[A-Za-z]:)/u.test(value)) return false;\n if (controlCharacterPattern.test(value) || hasUnpairedSurrogate(value)) {\n return false;\n }\n return !value.split(/[/\\\\]/u).includes('..');\n}\n\n/** 선택 symbol의 이름과 USR이 비어 있지 않은지 검증한다. */\nfunction validateSymbol(value: unknown, index: number): void {\n if (value === undefined) return;\n if (\n !isJsonObject(value) ||\n !isSafeNonEmptyString(value.qualifiedName) ||\n (value.usr !== undefined && !isSafeNonEmptyString(value.usr))\n ) {\n fail(`Invalid fact symbol at index ${index}.`);\n }\n}\n\n/** 생산 도구 이름과 버전이 비어 있지 않은지 검증한다. */\nfunction validateTool(value: unknown): void {\n if (\n !isJsonObject(value) ||\n !isSafeNonEmptyString(value.name) ||\n !isSafeNonEmptyString(value.version)\n ) {\n fail('Invalid tool metadata.');\n }\n}\n\n/** ISO 계열 생성 시각으로 해석할 수 있는지 확인한다. */\nexport function isBridgeTimestamp(value: unknown): value is string {\n if (typeof value !== 'string') return false;\n const match = timestampPattern.exec(value);\n if (match === null || Number.isNaN(Date.parse(value))) return false;\n const year = Number(match[1]);\n const month = Number(match[2]);\n const day = Number(match[3]);\n const hour = Number(match[4]);\n const minute = Number(match[5]);\n const second = Number(match[6]);\n return (\n month >= 1 &&\n month <= 12 &&\n day >= 1 &&\n day <= daysInMonth(year, month) &&\n hour <= 23 &&\n minute <= 59 &&\n second <= 59\n );\n}\n\n/** 윤년을 포함한 주어진 달의 실제 일수를 반환한다. */\nfunction daysInMonth(year: number, month: number): number {\n if (month === 2) {\n const isLeapYear = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);\n return isLeapYear ? 29 : 28;\n }\n return [4, 6, 9, 11].includes(month) ? 30 : 31;\n}\n\n/** 공백만 있지 않은 문자열인지 확인한다. */\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.trim().length > 0;\n}\n\n/** 모든 원소가 문자열인 배열인지 확인한다. */\nfunction isStringArray(value: unknown): value is readonly string[] {\n return Array.isArray(value) && value.every((item) => typeof item === 'string');\n}\n\n/** 1부터 시작하는 정수인지 확인한다. */\nfunction isPositiveInteger(value: unknown): value is number {\n return Number.isSafeInteger(value) && Number(value) >= 1;\n}\n\n/** 입력 값을 포함하지 않는 검증 오류를 던진다. */\nfunction fail(message: string): never {\n throw new BridgeFactsValidationError(message);\n}\n\n/** 지원하는 생산 플랫폼 집합이다. */\nconst bridgePlatforms = new Set<unknown>(['dart', 'swift', 'kotlin', 'js']);\n\n/** 지원하는 브리지 메커니즘 집합이다. */\nconst bridgeTargets = new Set<unknown>([\n 'flutter',\n 'react-native',\n 'capacitor',\n]);\n\n/** 버전 1이 정의한 사실 종류 집합이다. */\nconst bridgeFactKinds = new Set<unknown>([\n 'channel-create',\n 'channel-register',\n 'method-invoke',\n 'method-handle',\n 'module-export',\n 'module-import',\n 'component-export',\n 'component-require',\n]);\n\n/** 0.1 조인과 보고가 실제로 처리하는 사실 종류다. */\nconst supportedBridgeFactKinds = new Set<unknown>([\n 'channel-create',\n 'channel-register',\n 'method-invoke',\n 'method-handle',\n]);\n\nconst callerFactKinds = new Set<unknown>([\n 'channel-create',\n 'method-invoke',\n 'module-import',\n 'component-require',\n]);\nconst receiverFactKinds = new Set<unknown>([\n 'channel-register',\n 'method-handle',\n 'module-export',\n 'component-export',\n]);\n\n/** method 필드가 필수인 사실 종류다. */\nconst methodFactKinds = new Set<unknown>(['method-invoke', 'method-handle']);\n\nconst timestampPattern =\n /^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(?:\\.\\d+)?(?:Z|[+-]\\d{2}:\\d{2})$/u;\nconst controlCharacterPattern = /[\\u0000-\\u001f\\u007f-\\u009f\\u2028\\u2029]/u;\n\n/** 배열과 null을 제외한 JSON 객체인지 확인한다. isthmus 소유 문서 검증도 재사용한다. */\nexport function isJsonObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n"]}
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/exchange/parse.ts"],"names":[],"mappings":"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","sourcesContent":["/** bridge-facts 생산 플랫폼이다. */\nexport type BridgePlatform = 'dart' | 'swift' | 'kotlin' | 'js';\n\n/** 언어 경계를 잇는 메커니즘이다. */\nexport type BridgeTarget = 'flutter' | 'react-native' | 'capacitor';\n\n/** Swift 플랫폼 문서에 실린 Objective-C 구현을 Swift 보존 대상과 구분한다. */\nexport type BridgeSourceLanguage = 'objective-c';\n\n/** 특정 한계 전체의 영향을 포함하는 채널 집합. 일부 발견 목록이 아니다. */\nexport interface BridgeLimitationScope {\n readonly limitationIndex: number;\n readonly channels: readonly string[];\n}\n\n/** 확장 메타데이터가 입력 자원 상한을 우회하지 못하게 한다. */\nexport const MAX_LIMITATION_SCOPES = 1_000;\nexport const MAX_SCOPED_CHANNELS = 10_000;\n\n/** 교환 형식의 사실 종류다. */\nexport type BridgeFactKind =\n | 'channel-create'\n | 'channel-register'\n | 'method-invoke'\n | 'method-handle'\n | 'module-export'\n | 'module-import'\n | 'component-export'\n | 'component-require';\n\n/** 한 생산 문서가 담을 수 있는 최대 사실 수다. */\nexport const MAX_FACTS_PER_DOCUMENT = 100_000;\n\n/** 사실의 프로젝트 상대 소스 위치다. */\nexport interface BridgeLocation {\n readonly path: string;\n readonly line: number;\n readonly column: number;\n}\n\n/** 사실을 감싸는 언어별 선언 식별자다. */\nexport interface BridgeSymbol {\n readonly qualifiedName: string;\n readonly usr?: string;\n}\n\n/** 생산 도구 하나가 관찰한 언어 경계 사실이다. */\nexport interface BridgeFact {\n readonly kind: BridgeFactKind;\n readonly channel: string | null;\n readonly method?: string;\n readonly dynamic: boolean;\n readonly location: BridgeLocation;\n readonly symbol?: BridgeSymbol;\n readonly sourceLanguage?: BridgeSourceLanguage;\n}\n\n/** bridge-facts 버전 1 문서다. */\nexport interface BridgeFactsDocument {\n readonly format: 'bridge-facts';\n readonly version: 1;\n readonly tool: Readonly<{ name: string; version: string }>;\n readonly generatedAt: string;\n readonly platform: BridgePlatform;\n readonly target: BridgeTarget | null;\n readonly project: string;\n readonly facts: readonly BridgeFact[];\n readonly limitations: readonly string[];\n readonly limitationScopes?: readonly BridgeLimitationScope[];\n}\n\n/** 외부 교환 문서가 v1 계약을 어겼음을 나타낸다. */\nexport class BridgeFactsValidationError extends Error {\n /** 입력 내용을 노출하지 않는 안전한 메시지를 보존한다. */\n constructor(message: string) {\n super(message);\n this.name = 'BridgeFactsValidationError';\n }\n}\n\n/** 신뢰하지 않는 JSON 값을 검증된 bridge-facts v1 문서로 바꾼다. */\nexport function parseBridgeFactsDocument(input: unknown): BridgeFactsDocument {\n if (!isJsonObject(input)) {\n throw new BridgeFactsValidationError(\n 'Bridge facts must be a JSON object.',\n );\n }\n if (input.format !== 'bridge-facts') {\n throw new BridgeFactsValidationError('Expected format \"bridge-facts\".');\n }\n if (input.version !== 1) {\n throw new BridgeFactsValidationError(\n 'Unsupported bridge-facts version; expected version 1.',\n );\n }\n validateDocumentMetadata(input);\n return normalizeDocument(input);\n}\n\n/** 검증된 입력에서 v1 허용 필드만 복사해 신뢰 경계 밖 데이터를 제거한다. */\nfunction normalizeDocument(document: BridgeFactsDocument): BridgeFactsDocument {\n return {\n format: 'bridge-facts',\n version: 1,\n tool: { name: document.tool.name, version: document.tool.version },\n generatedAt: document.generatedAt,\n platform: document.platform,\n target: document.target,\n project: document.project,\n facts: document.facts.map(normalizeFact),\n limitations: [...document.limitations],\n ...(document.limitationScopes === undefined ? {} : {\n limitationScopes: document.limitationScopes.map((scope) => ({\n limitationIndex: scope.limitationIndex,\n channels: [...new Set(scope.channels)].sort(),\n })).sort((a, b) => a.limitationIndex - b.limitationIndex),\n }),\n };\n}\n\n/** 사실과 중첩 위치·심볼에서 계약 필드만 보존한다. */\nfunction normalizeFact(fact: BridgeFact): BridgeFact {\n const symbol = fact.symbol === undefined\n ? {}\n : {\n symbol: {\n qualifiedName: fact.symbol.qualifiedName,\n ...(fact.symbol.usr === undefined ? {} : { usr: fact.symbol.usr }),\n },\n };\n return {\n kind: fact.kind,\n channel: fact.channel,\n ...(fact.method === undefined ? {} : { method: fact.method }),\n dynamic: fact.dynamic,\n location: {\n path: fact.location.path,\n line: fact.location.line,\n column: fact.location.column,\n },\n ...symbol,\n ...(fact.sourceLanguage === undefined ? {} : { sourceLanguage: fact.sourceLanguage }),\n };\n}\n\n/** 문서 수준 필드가 v1 타입과 허용값을 따르는지 검증한다. */\nfunction validateDocumentMetadata(\n document: Record<string, unknown>,\n): asserts document is Record<string, unknown> & BridgeFactsDocument {\n validateTool(document.tool);\n if (!isBridgeTimestamp(document.generatedAt)) fail('Invalid generatedAt timestamp.');\n if (!bridgePlatforms.has(document.platform)) fail('Unsupported bridge platform.');\n if (document.target !== null && !bridgeTargets.has(document.target)) {\n fail('Unsupported bridge target.');\n }\n if (!isSafeNonEmptyString(document.project)) fail('Invalid project path.');\n if (!Array.isArray(document.facts)) fail('Facts must be an array.');\n if (document.facts.length > MAX_FACTS_PER_DOCUMENT) {\n fail(`Facts exceed the ${MAX_FACTS_PER_DOCUMENT} item limit.`);\n }\n document.facts.forEach((fact, index) =>\n validateFact(fact, index, document.platform),\n );\n if ((document.target === null) !== (document.facts.length === 0)) {\n fail('Target must be set exactly when facts are present.');\n }\n if (!isStringArray(document.limitations)) fail('Limitations must be strings.');\n validateLimitationScopes(document.limitationScopes, document.limitations.length);\n const hasUnattributedHandler = document.facts.some(\n (fact) =>\n isJsonObject(fact) &&\n fact.kind === 'method-handle' &&\n fact.channel === null,\n );\n if (\n hasUnattributedHandler &&\n !document.limitations.some((message) =>\n message.startsWith('unattributed-method-handles:'))\n ) {\n fail('Unattributed method handles require a limitation.');\n }\n}\n\n/** 잘못된 범위를 무시하면 거짓 error가 생기므로 입력 단계에서 명시적으로 거부한다. */\nfunction validateLimitationScopes(value: unknown, limitationCount: number): void {\n if (value === undefined) return;\n if (!Array.isArray(value) || value.length > MAX_LIMITATION_SCOPES) {\n fail('Invalid limitation scopes array.');\n }\n const indices = new Set<number>();\n let channelCount = 0;\n for (const entry of value) {\n if (!isJsonObject(entry) || !Number.isSafeInteger(entry.limitationIndex) ||\n typeof entry.limitationIndex !== 'number' || entry.limitationIndex < 0 ||\n entry.limitationIndex >= limitationCount || indices.has(entry.limitationIndex)) {\n fail('Invalid or duplicate limitation scope index.');\n }\n if (!Array.isArray(entry.channels) || entry.channels.length === 0 ||\n !entry.channels.every(isSafeNonEmptyString)) {\n fail('Limitation scope channels must be non-empty safe strings.');\n }\n channelCount += entry.channels.length;\n if (channelCount > MAX_SCOPED_CHANNELS) fail('Too many scoped channels.');\n indices.add(entry.limitationIndex);\n }\n}\n\n/** 사실 하나의 조인 키와 증거 필드를 검증한다. */\nfunction validateFact(value: unknown, index: number, platform: unknown): void {\n if (!isJsonObject(value)) fail(`Fact at index ${index} must be a JSON object.`);\n if (!bridgeFactKinds.has(value.kind)) fail(`Invalid fact kind at index ${index}.`);\n if (!supportedBridgeFactKinds.has(value.kind)) {\n fail(`Fact kind is reserved but not supported by this isthmus version at index ${index}.`);\n }\n if (!isFactKindForPlatform(platform, value.kind)) {\n fail(`Fact kind is not valid for platform at index ${index}.`);\n }\n if (!methodFactKinds.has(value.kind) && value.method !== undefined) {\n fail(`Unexpected method at index ${index}.`);\n }\n if (\n value.channel === null\n ? value.kind !== 'method-handle'\n : !isSafeNonEmptyString(value.channel)\n ) {\n fail(`Invalid fact channel at index ${index}.`);\n }\n if (methodFactKinds.has(value.kind) && !isSafeNonEmptyString(value.method)) {\n fail(`Method fact at index ${index} requires a method name.`);\n }\n if (typeof value.dynamic !== 'boolean') fail(`Invalid dynamic flag at index ${index}.`);\n validateLocation(value.location, index);\n validateSymbol(value.symbol, index);\n validateSourceLanguage(value.sourceLanguage, platform, value.location as BridgeLocation, value.symbol as BridgeSymbol | undefined, index);\n}\n\n/** 호출 측과 수신 측 플랫폼이 생산할 수 있는 fact 종류인지 확인한다. */\nfunction isFactKindForPlatform(platform: unknown, kind: unknown): boolean {\n return isCallerPlatform(platform)\n ? callerFactKinds.has(kind)\n : receiverFactKinds.has(kind);\n}\n\n/** 브리지 호출 측 사실을 생산하는 플랫폼인지 확인한다. */\nexport function isCallerPlatform(platform: unknown): platform is 'dart' | 'js' {\n return platform === 'dart' || platform === 'js';\n}\n\n/** 브리지 수신 측 사실을 생산하는 플랫폼인지 확인한다. */\nexport function isReceiverPlatform(\n platform: unknown,\n): platform is 'swift' | 'kotlin' {\n return platform === 'swift' || platform === 'kotlin';\n}\n\n/** 값이 계약이 정한 브리지 메커니즘 이름인지 확인한다. */\nexport function isBridgeTarget(value: unknown): value is BridgeTarget {\n return bridgeTargets.has(value);\n}\n\n/** 조인 키를 깨뜨리는 제어 문자가 없는 비어 있지 않은 문자열인지 확인한다. */\nexport function isSafeNonEmptyString(value: unknown): value is string {\n return isNonEmptyString(value) && !controlCharacterPattern.test(value) &&\n !hasUnpairedSurrogate(value);\n}\n\n/** 유효한 UTF-16 문자열인지, 즉 짝 없는 서러게이트가 없는지 확인한다. */\nfunction hasUnpairedSurrogate(value: string): boolean {\n // 아스트랄 문자(이모지 등)는 유효한 서러게이트 쌍이므로 그대로 통과한다.\n // 짝 없는 서러게이트는 어떤 인코딩의 파일에도 존재할 수 없어 JSON 이스케이프로만\n // 들어오며, URI 인코딩이 실패하는 등 소비 경로마다 깨진다.\n return value.toWellFormed() !== value;\n}\n\n/** 사실 위치가 상대 경로와 1부터 시작하는 줄·열을 갖는지 검증한다. */\nexport function validateLocation(value: unknown, index: number): void {\n if (\n !isJsonObject(value) ||\n !isProjectRelativePath(value.path) ||\n !isPositiveInteger(value.line) ||\n !isPositiveInteger(value.column)\n ) {\n fail(`Invalid fact location at index ${index}.`);\n }\n}\n\n/** 절대·상위 경로와 제어 문자를 제외한 프로젝트 상대 경로인지 확인한다. */\nexport function isProjectRelativePath(value: unknown): value is string {\n if (!isNonEmptyString(value)) return false;\n if (/^(?:[/\\\\]|[A-Za-z]:)/u.test(value)) return false;\n if (controlCharacterPattern.test(value) || hasUnpairedSurrogate(value)) {\n return false;\n }\n return !value.split(/[/\\\\]/u).includes('..');\n}\n\n/** 선택 symbol의 이름과 USR이 비어 있지 않은지 검증한다. */\nexport function validateSymbol(value: unknown, index: number): void {\n if (value === undefined) return;\n if (\n !isJsonObject(value) ||\n !isSafeNonEmptyString(value.qualifiedName) ||\n (value.usr !== undefined && !isSafeNonEmptyString(value.usr))\n ) {\n fail(`Invalid fact symbol at index ${index}.`);\n }\n}\n\n/** 교환 계약별 파서가 Objective-C 출처·경로·실제 Clang 신원 규칙을 공유한다. */\nexport function validateSourceLanguage(value: unknown, platform: unknown, location: BridgeLocation,\n symbol: BridgeSymbol | undefined, index: number): void {\n if (value !== undefined && (value !== 'objective-c' || platform !== 'swift' ||\n !/\\.(?:m|mm)$/u.test(location.path) ||\n (symbol?.usr !== undefined && !symbol.usr.startsWith('c:')))) {\n fail(`Invalid source language at index ${index}.`);\n }\n}\n\n/** 생산 도구 이름과 버전이 비어 있지 않은지 검증한다. */\nfunction validateTool(value: unknown): void {\n if (\n !isJsonObject(value) ||\n !isSafeNonEmptyString(value.name) ||\n !isSafeNonEmptyString(value.version)\n ) {\n fail('Invalid tool metadata.');\n }\n}\n\n/** ISO 계열 생성 시각으로 해석할 수 있는지 확인한다. */\nexport function isBridgeTimestamp(value: unknown): value is string {\n if (typeof value !== 'string') return false;\n const match = timestampPattern.exec(value);\n if (match === null || Number.isNaN(Date.parse(value))) return false;\n const year = Number(match[1]);\n const month = Number(match[2]);\n const day = Number(match[3]);\n const hour = Number(match[4]);\n const minute = Number(match[5]);\n const second = Number(match[6]);\n return (\n month >= 1 &&\n month <= 12 &&\n day >= 1 &&\n day <= daysInMonth(year, month) &&\n hour <= 23 &&\n minute <= 59 &&\n second <= 59\n );\n}\n\n/** 윤년을 포함한 주어진 달의 실제 일수를 반환한다. */\nfunction daysInMonth(year: number, month: number): number {\n if (month === 2) {\n const isLeapYear = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);\n return isLeapYear ? 29 : 28;\n }\n return [4, 6, 9, 11].includes(month) ? 30 : 31;\n}\n\n/** 공백만 있지 않은 문자열인지 확인한다. */\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.trim().length > 0;\n}\n\n/** 모든 원소가 문자열인 배열인지 확인한다. */\nfunction isStringArray(value: unknown): value is readonly string[] {\n return Array.isArray(value) && value.every((item) => typeof item === 'string');\n}\n\n/** 1부터 시작하는 정수인지 확인한다. */\nfunction isPositiveInteger(value: unknown): value is number {\n return Number.isSafeInteger(value) && Number(value) >= 1;\n}\n\n/** 입력 값을 포함하지 않는 검증 오류를 던진다. */\nfunction fail(message: string): never {\n throw new BridgeFactsValidationError(message);\n}\n\n/** 지원하는 생산 플랫폼 집합이다. */\nconst bridgePlatforms = new Set<unknown>(['dart', 'swift', 'kotlin', 'js']);\n\n/** 지원하는 브리지 메커니즘 집합이다. */\nconst bridgeTargets = new Set<unknown>([\n 'flutter',\n 'react-native',\n 'capacitor',\n]);\n\n/** 버전 1이 정의한 사실 종류 집합이다. */\nconst bridgeFactKinds = new Set<unknown>([\n 'channel-create',\n 'channel-register',\n 'method-invoke',\n 'method-handle',\n 'module-export',\n 'module-import',\n 'component-export',\n 'component-require',\n]);\n\n/** 0.1 조인과 보고가 실제로 처리하는 사실 종류다. */\nconst supportedBridgeFactKinds = new Set<unknown>([\n 'channel-create',\n 'channel-register',\n 'method-invoke',\n 'method-handle',\n]);\n\nconst callerFactKinds = new Set<unknown>([\n 'channel-create',\n 'method-invoke',\n 'module-import',\n 'component-require',\n]);\nconst receiverFactKinds = new Set<unknown>([\n 'channel-register',\n 'method-handle',\n 'module-export',\n 'component-export',\n]);\n\n/** method 필드가 필수인 사실 종류다. */\nconst methodFactKinds = new Set<unknown>(['method-invoke', 'method-handle']);\n\nconst timestampPattern =\n /^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(?:\\.\\d+)?(?:Z|[+-]\\d{2}:\\d{2})$/u;\nconst controlCharacterPattern = /[\\u0000-\\u001f\\u007f-\\u009f\\u2028\\u2029]/u;\n\n/** 배열과 null을 제외한 JSON 객체인지 확인한다. isthmus 소유 문서 검증도 재사용한다. */\nexport function isJsonObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n"]}
@@ -0,0 +1,71 @@
1
+ import type { BridgeFactsDocument, BridgeLocation } from './parse.ts';
2
+ import type { ImpactSelection } from './impact-selection.ts';
3
+ import type { BridgeMessageDocument } from './messages.ts';
4
+ /** 영향 분석에서 사용하는, 생산자가 증명한 심볼 식별자다. */
5
+ export interface ImpactSymbol {
6
+ readonly id: string;
7
+ readonly qualifiedName: string;
8
+ readonly kind?: string;
9
+ readonly location?: Readonly<{
10
+ path: string;
11
+ line?: number;
12
+ column?: number;
13
+ }>;
14
+ }
15
+ /** 한 언어 producer가 한 선택에 대해 관찰한 영향 범위다. */
16
+ export interface LanguageImpact {
17
+ readonly id: string;
18
+ readonly platform: 'dart' | 'swift' | 'kotlin';
19
+ readonly tool: Readonly<{
20
+ name: string;
21
+ version: string;
22
+ }>;
23
+ readonly requested: ImpactSelection;
24
+ readonly trigger?: string;
25
+ readonly roots: readonly ImpactSymbol[];
26
+ readonly affected: readonly {
27
+ readonly symbol: ImpactSymbol;
28
+ readonly via: string;
29
+ readonly depth: number;
30
+ readonly relationships: readonly string[];
31
+ }[];
32
+ readonly limitations: readonly string[];
33
+ readonly truncated: boolean;
34
+ }
35
+ /** Dart fact와 query symbol을 추측 없이 연결하는 호출자 근거다. */
36
+ export interface CallerBinding {
37
+ readonly platform: 'dart';
38
+ readonly location: BridgeLocation;
39
+ readonly requested: string;
40
+ readonly symbol: ImpactSymbol;
41
+ }
42
+ /** 변경 사전 점검이 재사용할 입력·분석·호출자 근거를 묶은 문서다. */
43
+ export interface PreflightContext {
44
+ readonly format: 'isthmus-preflight-context';
45
+ readonly version: 1;
46
+ readonly project: string;
47
+ readonly revision: string;
48
+ readonly selection: Readonly<{
49
+ readonly dart?: ImpactSelection;
50
+ readonly swift?: ImpactSelection;
51
+ readonly kotlin?: ImpactSelection;
52
+ }>;
53
+ readonly bridges: readonly BridgeFactsDocument[];
54
+ readonly messages?: readonly BridgeMessageDocument[];
55
+ readonly bindings: readonly CallerBinding[];
56
+ readonly analyses: readonly LanguageImpact[];
57
+ readonly limitations: readonly string[];
58
+ }
59
+ /** preflight 입력이 계약을 어겼음을 나타내며 원문 데이터를 오류에 넣지 않는다. */
60
+ export declare class PreflightValidationError extends Error {
61
+ constructor(message: string);
62
+ }
63
+ export declare const MAX_PREFLIGHT_ANALYSES = 256;
64
+ export declare const MAX_PREFLIGHT_GRAPH_ITEMS = 50000;
65
+ export declare const MAX_PREFLIGHT_BINDINGS = 100000;
66
+ export declare const MAX_PREFLIGHT_DEPTH = 128;
67
+ export declare const MAX_PREFLIGHT_RELATIONSHIPS = 32;
68
+ /** 신뢰하지 않는 JSON을 정규화된 preflight-context v1으로 검증한다. */
69
+ export declare function parsePreflightContext(input: unknown): PreflightContext;
70
+ /** producer adapter가 만든 분석도 context parser와 같은 그래프 규칙을 사용하게 한다. */
71
+ export declare function validateLanguageImpact(input: unknown): LanguageImpact;