@runhalo/engine 0.3.1 → 0.5.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.
@@ -0,0 +1,106 @@
1
+ /**
2
+ * DataFlowTracer — single-file data-flow analysis using tree-sitter AST.
3
+ *
4
+ * Answers questions like:
5
+ * "Does this value pass through DOMPurify before reaching dangerouslySetInnerHTML?"
6
+ * "Is there a TTL field in this schema?"
7
+ *
8
+ * HARD SCOPE: Single-file only. No cross-file resolution.
9
+ */
10
+ import Parser from 'tree-sitter';
11
+ export declare class DataFlowTracer {
12
+ private rootNode;
13
+ constructor(tree: Parser.Tree);
14
+ /**
15
+ * Check if a value at `targetLine` (1-indexed) passes through any of the
16
+ * specified functions before being used. Searches backward from targetLine
17
+ * for call expressions whose name matches one of `functionNames`.
18
+ *
19
+ * Example:
20
+ * passesThrough(42, ['DOMPurify.sanitize', 'sanitize', 'xss'])
21
+ * checks if the value used at line 42 was sanitized.
22
+ */
23
+ passesThrough(targetLine: number, functionNames: string[]): boolean;
24
+ /**
25
+ * Check if any property with the given names exists in the same scope/block
26
+ * as the target line (1-indexed). Used for checking if a Schema has
27
+ * TTL/expires fields.
28
+ *
29
+ * Example:
30
+ * hasPropertyInScope(42, ['TTL', 'expires', 'retention', 'deleted_at'])
31
+ */
32
+ hasPropertyInScope(targetLine: number, propertyNames: string[]): boolean;
33
+ /**
34
+ * Find all call expressions within `range` lines of `targetLine` (1-indexed).
35
+ * Returns function name and line number (1-indexed).
36
+ */
37
+ findNearbyCallExpressions(targetLine: number, range: number): Array<{
38
+ name: string;
39
+ line: number;
40
+ }>;
41
+ /**
42
+ * Get the enclosing function/block scope for a given line (1-indexed).
43
+ * Returns the start line (1-indexed), end line (1-indexed), and type of the
44
+ * enclosing scope.
45
+ */
46
+ getEnclosingScope(line: number): {
47
+ startLine: number;
48
+ endLine: number;
49
+ type: string;
50
+ } | null;
51
+ /**
52
+ * Find all assignments to a variable name within the file.
53
+ * Returns line (1-indexed) and the textual representation of the assigned value.
54
+ */
55
+ findAssignments(variableName: string): Array<{
56
+ line: number;
57
+ value: string;
58
+ }>;
59
+ /**
60
+ * Check if a specific argument text is present in a function call at a
61
+ * given line (1-indexed).
62
+ *
63
+ * Handles:
64
+ * - Simple string/identifier args: ga('create', 'UA-X', 'auto')
65
+ * - Object literal properties: ga('create', 'UA-X', { child_directed_treatment: true })
66
+ * - new_expression args: new Analytics({ child_directed_treatment: true })
67
+ * - Nested object properties at any depth
68
+ *
69
+ * Example:
70
+ * hasArgument(42, 'child_directed_treatment')
71
+ */
72
+ hasArgument(callLine: number, argumentText: string): boolean;
73
+ /**
74
+ * Check if a variable/constant with a matching name exists in the same
75
+ * block scope as the target line (1-indexed).
76
+ *
77
+ * Searches for: variable declarations, const declarations, let declarations,
78
+ * parameter names, and property assignments.
79
+ *
80
+ * This catches cases like:
81
+ * - parent_email declared alongside child_email → suppresses coppa-flow-009
82
+ * - MAX_PAGES constant near IntersectionObserver → suppresses ETHICAL-001
83
+ */
84
+ hasVariableInScope(targetLine: number, variableNames: string[]): boolean;
85
+ /**
86
+ * Find the enclosing function-level scope for a 0-indexed line.
87
+ * Used by the public getEnclosingScope() API — returns function/class/program scopes.
88
+ */
89
+ private findEnclosingFunctionScope;
90
+ /**
91
+ * Find the enclosing scope node for a 0-indexed line (including block scopes).
92
+ * Used internally by hasPropertyInScope and hasVariableInScope for fine-grained
93
+ * variable/property resolution that respects block scoping.
94
+ */
95
+ private findEnclosingScopeNode;
96
+ /**
97
+ * Find the nearest block scope containing the given line (0-indexed).
98
+ * Falls back to the enclosing function/program scope.
99
+ * Used for variable declaration detection — checks both block and function scope.
100
+ */
101
+ private findNearestBlockOrScope;
102
+ /**
103
+ * Get the source text of a 0-indexed line by slicing the root node's text.
104
+ */
105
+ private getLineText;
106
+ }
@@ -0,0 +1,506 @@
1
+ "use strict";
2
+ /**
3
+ * DataFlowTracer — single-file data-flow analysis using tree-sitter AST.
4
+ *
5
+ * Answers questions like:
6
+ * "Does this value pass through DOMPurify before reaching dangerouslySetInnerHTML?"
7
+ * "Is there a TTL field in this schema?"
8
+ *
9
+ * HARD SCOPE: Single-file only. No cross-file resolution.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.DataFlowTracer = void 0;
13
+ // ---------------------------------------------------------------------------
14
+ // Helpers
15
+ // ---------------------------------------------------------------------------
16
+ /**
17
+ * Recursively walk every node in a subtree, calling `visitor` on each one.
18
+ */
19
+ function walk(node, visitor) {
20
+ if (!node || typeof node.type !== 'string')
21
+ return;
22
+ visitor(node);
23
+ const count = node.childCount || 0;
24
+ for (let i = 0; i < count; i++) {
25
+ walk(node.child(i), visitor);
26
+ }
27
+ }
28
+ /**
29
+ * Resolve the full text of a call expression's function name.
30
+ * Handles both simple identifiers (`sanitize`) and member expressions
31
+ * (`DOMPurify.sanitize`, `a.b.c`).
32
+ */
33
+ function resolveCallName(callNode) {
34
+ const func = callNode.childForFieldName('function');
35
+ if (!func)
36
+ return null;
37
+ if (func.type === 'identifier') {
38
+ return func.text;
39
+ }
40
+ if (func.type === 'member_expression') {
41
+ return func.text;
42
+ }
43
+ return func.text;
44
+ }
45
+ /**
46
+ * Find the deepest node whose range contains the given 0-indexed line.
47
+ */
48
+ function nodeAtLine(root, line0) {
49
+ let best = null;
50
+ walk(root, (n) => {
51
+ if (n.startPosition.row <= line0 && n.endPosition.row >= line0) {
52
+ best = n;
53
+ }
54
+ });
55
+ return best;
56
+ }
57
+ // ---------------------------------------------------------------------------
58
+ // DataFlowTracer
59
+ // ---------------------------------------------------------------------------
60
+ class DataFlowTracer {
61
+ constructor(tree) {
62
+ this.rootNode = tree.rootNode;
63
+ }
64
+ // -----------------------------------------------------------------------
65
+ // passesThrough
66
+ // -----------------------------------------------------------------------
67
+ /**
68
+ * Check if a value at `targetLine` (1-indexed) passes through any of the
69
+ * specified functions before being used. Searches backward from targetLine
70
+ * for call expressions whose name matches one of `functionNames`.
71
+ *
72
+ * Example:
73
+ * passesThrough(42, ['DOMPurify.sanitize', 'sanitize', 'xss'])
74
+ * checks if the value used at line 42 was sanitized.
75
+ */
76
+ passesThrough(targetLine, functionNames) {
77
+ const target0 = targetLine - 1; // convert to 0-indexed
78
+ // 1. Check for INLINE sanitizer calls on the target line itself.
79
+ // e.g., dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(content) }}
80
+ // or dangerouslySetInnerHTML={{ __html: sanitize(userInput) }}
81
+ let inlineFound = false;
82
+ walk(this.rootNode, (node) => {
83
+ if (inlineFound)
84
+ return;
85
+ if (node.type === 'call_expression' && node.startPosition.row === target0) {
86
+ const name = resolveCallName(node);
87
+ if (name && functionNames.some((fn) => name === fn || name.endsWith('.' + fn))) {
88
+ inlineFound = true;
89
+ }
90
+ }
91
+ });
92
+ if (inlineFound)
93
+ return true;
94
+ // 2. Collect all matching call_expression nodes that occur before the target line.
95
+ const matchingCalls = [];
96
+ walk(this.rootNode, (node) => {
97
+ if (node.type === 'call_expression' && node.startPosition.row < target0) {
98
+ const name = resolveCallName(node);
99
+ if (name && functionNames.some((fn) => name === fn || name.endsWith('.' + fn))) {
100
+ matchingCalls.push(node);
101
+ }
102
+ }
103
+ });
104
+ if (matchingCalls.length === 0)
105
+ return false;
106
+ // 3. Check if any of the matching calls assign to a variable that is
107
+ // referenced on the target line.
108
+ const targetLineText = this.getLineText(target0);
109
+ for (const call of matchingCalls) {
110
+ // Walk upward to find a variable_declarator or assignment_expression
111
+ // wrapping this call.
112
+ let parent = call.parent;
113
+ while (parent && parent.type !== 'variable_declarator' && parent.type !== 'assignment_expression') {
114
+ parent = parent.parent;
115
+ }
116
+ if (parent) {
117
+ let assignedName = null;
118
+ if (parent.type === 'variable_declarator') {
119
+ const nameNode = parent.childForFieldName('name');
120
+ if (nameNode)
121
+ assignedName = nameNode.text;
122
+ }
123
+ else if (parent.type === 'assignment_expression') {
124
+ const left = parent.childForFieldName('left');
125
+ if (left)
126
+ assignedName = left.text;
127
+ }
128
+ // If the variable assigned from the sanitizer call appears on the
129
+ // target line, the value passes through.
130
+ if (assignedName && targetLineText.includes(assignedName)) {
131
+ return true;
132
+ }
133
+ }
134
+ // Also handle the case where the call is used inline on a line just
135
+ // before the target (e.g., the call result is passed directly as an
136
+ // argument or stored in a variable used on the very next statement).
137
+ if (target0 - call.startPosition.row <= 2) {
138
+ return true;
139
+ }
140
+ }
141
+ return false;
142
+ }
143
+ // -----------------------------------------------------------------------
144
+ // hasPropertyInScope
145
+ // -----------------------------------------------------------------------
146
+ /**
147
+ * Check if any property with the given names exists in the same scope/block
148
+ * as the target line (1-indexed). Used for checking if a Schema has
149
+ * TTL/expires fields.
150
+ *
151
+ * Example:
152
+ * hasPropertyInScope(42, ['TTL', 'expires', 'retention', 'deleted_at'])
153
+ */
154
+ hasPropertyInScope(targetLine, propertyNames) {
155
+ const target0 = targetLine - 1;
156
+ const lowerNames = propertyNames.map((n) => n.toLowerCase());
157
+ // Find enclosing scope node.
158
+ const scope = this.findEnclosingScopeNode(target0);
159
+ if (!scope)
160
+ return false;
161
+ let found = false;
162
+ walk(scope, (node) => {
163
+ if (found)
164
+ return;
165
+ // property_identifier: key in { key: value }
166
+ // shorthand_property_identifier_pattern: { key } destructure
167
+ // shorthand_property_identifier: { key } shorthand
168
+ // pair → key child (for object literals)
169
+ if (node.type === 'property_identifier' ||
170
+ node.type === 'shorthand_property_identifier' ||
171
+ node.type === 'shorthand_property_identifier_pattern') {
172
+ if (lowerNames.includes(node.text.toLowerCase())) {
173
+ found = true;
174
+ }
175
+ }
176
+ // Also match string keys like 'TTL' in { 'TTL': 300 }
177
+ if (node.type === 'string' && node.parent?.type === 'pair') {
178
+ const raw = node.text.replace(/^['"]|['"]$/g, '');
179
+ if (lowerNames.includes(raw.toLowerCase())) {
180
+ found = true;
181
+ }
182
+ }
183
+ // Match identifiers that look like property names in type annotations
184
+ // or interfaces, e.g. `deleted_at: Date`
185
+ if (node.type === 'identifier' || node.type === 'property_identifier') {
186
+ if (lowerNames.includes(node.text.toLowerCase())) {
187
+ found = true;
188
+ }
189
+ }
190
+ });
191
+ return found;
192
+ }
193
+ // -----------------------------------------------------------------------
194
+ // findNearbyCallExpressions
195
+ // -----------------------------------------------------------------------
196
+ /**
197
+ * Find all call expressions within `range` lines of `targetLine` (1-indexed).
198
+ * Returns function name and line number (1-indexed).
199
+ */
200
+ findNearbyCallExpressions(targetLine, range) {
201
+ const target0 = targetLine - 1;
202
+ const results = [];
203
+ walk(this.rootNode, (node) => {
204
+ if (node.type === 'call_expression') {
205
+ const line0 = node.startPosition.row;
206
+ if (Math.abs(line0 - target0) <= range) {
207
+ const name = resolveCallName(node);
208
+ if (name) {
209
+ results.push({ name, line: line0 + 1 });
210
+ }
211
+ }
212
+ }
213
+ });
214
+ return results;
215
+ }
216
+ // -----------------------------------------------------------------------
217
+ // getEnclosingScope
218
+ // -----------------------------------------------------------------------
219
+ /**
220
+ * Get the enclosing function/block scope for a given line (1-indexed).
221
+ * Returns the start line (1-indexed), end line (1-indexed), and type of the
222
+ * enclosing scope.
223
+ */
224
+ getEnclosingScope(line) {
225
+ const scope = this.findEnclosingFunctionScope(line - 1);
226
+ if (!scope)
227
+ return null;
228
+ return {
229
+ startLine: scope.startPosition.row + 1,
230
+ endLine: scope.endPosition.row + 1,
231
+ type: scope.type,
232
+ };
233
+ }
234
+ // -----------------------------------------------------------------------
235
+ // findAssignments
236
+ // -----------------------------------------------------------------------
237
+ /**
238
+ * Find all assignments to a variable name within the file.
239
+ * Returns line (1-indexed) and the textual representation of the assigned value.
240
+ */
241
+ findAssignments(variableName) {
242
+ const results = [];
243
+ walk(this.rootNode, (node) => {
244
+ // const x = ... / let x = ... / var x = ...
245
+ if (node.type === 'variable_declarator') {
246
+ const nameNode = node.childForFieldName('name');
247
+ const valueNode = node.childForFieldName('value');
248
+ if (nameNode && nameNode.text === variableName && valueNode) {
249
+ results.push({
250
+ line: node.startPosition.row + 1,
251
+ value: valueNode.text,
252
+ });
253
+ }
254
+ }
255
+ // x = ... (reassignment)
256
+ if (node.type === 'assignment_expression') {
257
+ const left = node.childForFieldName('left');
258
+ const right = node.childForFieldName('right');
259
+ if (left && left.text === variableName && right) {
260
+ results.push({
261
+ line: node.startPosition.row + 1,
262
+ value: right.text,
263
+ });
264
+ }
265
+ }
266
+ });
267
+ return results;
268
+ }
269
+ // -----------------------------------------------------------------------
270
+ // hasArgument
271
+ // -----------------------------------------------------------------------
272
+ /**
273
+ * Check if a specific argument text is present in a function call at a
274
+ * given line (1-indexed).
275
+ *
276
+ * Handles:
277
+ * - Simple string/identifier args: ga('create', 'UA-X', 'auto')
278
+ * - Object literal properties: ga('create', 'UA-X', { child_directed_treatment: true })
279
+ * - new_expression args: new Analytics({ child_directed_treatment: true })
280
+ * - Nested object properties at any depth
281
+ *
282
+ * Example:
283
+ * hasArgument(42, 'child_directed_treatment')
284
+ */
285
+ hasArgument(callLine, argumentText) {
286
+ const call0 = callLine - 1;
287
+ const lowerTarget = argumentText.toLowerCase();
288
+ let found = false;
289
+ walk(this.rootNode, (node) => {
290
+ if (found)
291
+ return;
292
+ // Match both call_expression and new_expression at the target line
293
+ const isCallOrNew = node.type === 'call_expression' || node.type === 'new_expression';
294
+ if (isCallOrNew && node.startPosition.row === call0) {
295
+ const args = node.childForFieldName('arguments');
296
+ if (args) {
297
+ // Deep walk the arguments subtree — inspect every node including
298
+ // object literal property keys, values, and nested structures.
299
+ walk(args, (argNode) => {
300
+ if (found)
301
+ return;
302
+ // Check property keys in object literals: { child_directed_treatment: true }
303
+ if (argNode.type === 'property_identifier' || argNode.type === 'shorthand_property_identifier') {
304
+ if (argNode.text.toLowerCase().includes(lowerTarget)) {
305
+ found = true;
306
+ return;
307
+ }
308
+ }
309
+ // Check string keys: { 'child_directed_treatment': true }
310
+ if (argNode.type === 'string' || argNode.type === 'template_string') {
311
+ const raw = argNode.text.replace(/^['"`]|['"`]$/g, '');
312
+ if (raw.toLowerCase().includes(lowerTarget)) {
313
+ found = true;
314
+ return;
315
+ }
316
+ }
317
+ // Check identifiers (variable names, boolean keywords, etc.)
318
+ if (argNode.type === 'identifier') {
319
+ if (argNode.text.toLowerCase().includes(lowerTarget)) {
320
+ found = true;
321
+ return;
322
+ }
323
+ }
324
+ // Fallback: raw text check on any node
325
+ if (argNode.text.includes(argumentText)) {
326
+ found = true;
327
+ }
328
+ });
329
+ }
330
+ }
331
+ });
332
+ return found;
333
+ }
334
+ // -----------------------------------------------------------------------
335
+ // hasVariableInScope (Sprint 9 — Richard Pass 4 fix)
336
+ // -----------------------------------------------------------------------
337
+ /**
338
+ * Check if a variable/constant with a matching name exists in the same
339
+ * block scope as the target line (1-indexed).
340
+ *
341
+ * Searches for: variable declarations, const declarations, let declarations,
342
+ * parameter names, and property assignments.
343
+ *
344
+ * This catches cases like:
345
+ * - parent_email declared alongside child_email → suppresses coppa-flow-009
346
+ * - MAX_PAGES constant near IntersectionObserver → suppresses ETHICAL-001
347
+ */
348
+ hasVariableInScope(targetLine, variableNames) {
349
+ const target0 = targetLine - 1;
350
+ const lowerNames = variableNames.map(n => n.toLowerCase());
351
+ // Check both the immediate block scope AND the enclosing function scope
352
+ const blockScope = this.findNearestBlockOrScope(target0);
353
+ const funcScope = this.findEnclosingScopeNode(target0);
354
+ const scopesToCheck = new Set();
355
+ if (blockScope)
356
+ scopesToCheck.add(blockScope);
357
+ if (funcScope)
358
+ scopesToCheck.add(funcScope);
359
+ for (const scope of scopesToCheck) {
360
+ let found = false;
361
+ walk(scope, (node) => {
362
+ if (found)
363
+ return;
364
+ // Variable declarators: const MAX_PAGES = 10, let parent_email = ...
365
+ if (node.type === 'variable_declarator') {
366
+ const nameNode = node.childForFieldName('name');
367
+ if (nameNode && lowerNames.includes(nameNode.text.toLowerCase())) {
368
+ found = true;
369
+ return;
370
+ }
371
+ }
372
+ // Function parameters: function handler(parent_email, child_email)
373
+ if (node.type === 'identifier' && node.parent?.type === 'formal_parameters') {
374
+ if (lowerNames.includes(node.text.toLowerCase())) {
375
+ found = true;
376
+ return;
377
+ }
378
+ }
379
+ // Assignment expressions: parent_email = req.body.email
380
+ if (node.type === 'assignment_expression') {
381
+ const left = node.childForFieldName('left');
382
+ if (left && lowerNames.includes(left.text.toLowerCase())) {
383
+ found = true;
384
+ return;
385
+ }
386
+ }
387
+ // Identifier references: catches bare references like MAX_PAGES in
388
+ // `if (page < MAX_PAGES)` — the presence of the identifier anywhere
389
+ // in scope (even without a local declaration) is meaningful.
390
+ // Exclude identifiers that are property accesses (member_expression object/property)
391
+ // to avoid matching unrelated nested properties.
392
+ if (node.type === 'identifier') {
393
+ if (node.parent?.type !== 'formal_parameters' &&
394
+ node.parent?.type !== 'variable_declarator' &&
395
+ node.parent?.type !== 'property_identifier') {
396
+ if (lowerNames.includes(node.text.toLowerCase())) {
397
+ found = true;
398
+ return;
399
+ }
400
+ }
401
+ }
402
+ });
403
+ if (found)
404
+ return true;
405
+ }
406
+ return false;
407
+ }
408
+ // -----------------------------------------------------------------------
409
+ // Private helpers
410
+ // -----------------------------------------------------------------------
411
+ /**
412
+ * Find the enclosing function-level scope for a 0-indexed line.
413
+ * Used by the public getEnclosingScope() API — returns function/class/program scopes.
414
+ */
415
+ findEnclosingFunctionScope(line0) {
416
+ const scopeTypes = new Set([
417
+ 'function_declaration',
418
+ 'function',
419
+ 'arrow_function',
420
+ 'method_definition',
421
+ 'class_body',
422
+ 'class_declaration',
423
+ 'program',
424
+ ]);
425
+ // Fall back to rootNode if nodeAtLine returns null (e.g., empty leading lines
426
+ // where tree-sitter's program node may start at a later row)
427
+ let node = nodeAtLine(this.rootNode, line0) ?? this.rootNode;
428
+ while (node) {
429
+ if (scopeTypes.has(node.type)) {
430
+ return node;
431
+ }
432
+ node = node.parent;
433
+ }
434
+ return null;
435
+ }
436
+ /**
437
+ * Find the enclosing scope node for a 0-indexed line (including block scopes).
438
+ * Used internally by hasPropertyInScope and hasVariableInScope for fine-grained
439
+ * variable/property resolution that respects block scoping.
440
+ */
441
+ findEnclosingScopeNode(line0) {
442
+ const scopeTypes = new Set([
443
+ 'function_declaration',
444
+ 'function',
445
+ 'arrow_function',
446
+ 'method_definition',
447
+ 'class_body',
448
+ 'class_declaration',
449
+ 'program',
450
+ // Sprint 9: Also consider block-level scopes for variable resolution
451
+ 'statement_block',
452
+ 'if_statement',
453
+ 'for_statement',
454
+ 'for_in_statement',
455
+ 'for_of_statement',
456
+ 'while_statement',
457
+ 'switch_body',
458
+ 'export_statement',
459
+ ]);
460
+ // Fall back to rootNode if nodeAtLine returns null (e.g., empty leading lines)
461
+ let node = nodeAtLine(this.rootNode, line0) ?? this.rootNode;
462
+ while (node) {
463
+ if (scopeTypes.has(node.type)) {
464
+ return node;
465
+ }
466
+ node = node.parent;
467
+ }
468
+ return null;
469
+ }
470
+ /**
471
+ * Find the nearest block scope containing the given line (0-indexed).
472
+ * Falls back to the enclosing function/program scope.
473
+ * Used for variable declaration detection — checks both block and function scope.
474
+ */
475
+ findNearestBlockOrScope(line0) {
476
+ const blockTypes = new Set([
477
+ 'statement_block',
478
+ 'function_declaration',
479
+ 'function',
480
+ 'arrow_function',
481
+ 'method_definition',
482
+ 'class_body',
483
+ 'class_declaration',
484
+ 'program',
485
+ ]);
486
+ // Fall back to rootNode if nodeAtLine returns null (e.g., empty leading lines)
487
+ let node = nodeAtLine(this.rootNode, line0) ?? this.rootNode;
488
+ while (node) {
489
+ if (blockTypes.has(node.type)) {
490
+ return node;
491
+ }
492
+ node = node.parent;
493
+ }
494
+ return null;
495
+ }
496
+ /**
497
+ * Get the source text of a 0-indexed line by slicing the root node's text.
498
+ */
499
+ getLineText(line0) {
500
+ const text = this.rootNode.text;
501
+ const lines = text.split('\n');
502
+ return lines[line0] ?? '';
503
+ }
504
+ }
505
+ exports.DataFlowTracer = DataFlowTracer;
506
+ //# sourceMappingURL=data-flow-tracer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-flow-tracer.js","sourceRoot":"","sources":["../src/data-flow-tracer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Django Framework Profile
3
+ *
4
+ * Django provides built-in protections that overlap with several COPPA rules:
5
+ * - Template engine auto-escapes all variables by default
6
+ * - SecurityMiddleware enforces HTTPS when configured
7
+ * - Built-in password validators enforce complexity requirements
8
+ * - django-lifecycle and django-reversion can handle data retention externally
9
+ */
10
+ import { FrameworkProfile } from './types';
11
+ export declare const djangoProfile: FrameworkProfile;