checkpoint-cli 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +213 -71
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -81,12 +81,15 @@ function requireAuth() {
|
|
|
81
81
|
/* ── Checkpoint Tracking Script (injected into HTML responses) ── */
|
|
82
82
|
function trackingScript() {
|
|
83
83
|
return `
|
|
84
|
-
<script data-checkpoint>
|
|
84
|
+
<script data-checkpoint-script="1">
|
|
85
85
|
(function(){
|
|
86
86
|
var lastPath='';
|
|
87
87
|
var pickMode=false;
|
|
88
88
|
var pickClickHandler=null;
|
|
89
89
|
var pickEscHandler=null;
|
|
90
|
+
var pickMoveHandler=null;
|
|
91
|
+
var pickInspectBox=null;
|
|
92
|
+
var pickInspectLabel=null;
|
|
90
93
|
|
|
91
94
|
function getMetrics(){
|
|
92
95
|
var de=document.documentElement;
|
|
@@ -120,6 +123,133 @@ function trackingScript() {
|
|
|
120
123
|
return String(value).replace(/\\s+/g,' ').trim().slice(0,120);
|
|
121
124
|
}
|
|
122
125
|
|
|
126
|
+
function getFileLeaf(path){
|
|
127
|
+
if(!path) return '';
|
|
128
|
+
try{
|
|
129
|
+
var raw=String(path);
|
|
130
|
+
var parts=raw.split(/[\\\\/]/);
|
|
131
|
+
return parts[parts.length-1]||raw;
|
|
132
|
+
}catch(e){}
|
|
133
|
+
return '';
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function getInspectElementLabel(el){
|
|
137
|
+
if(!el||!el.tagName) return '(unknown)';
|
|
138
|
+
var tag=String(el.tagName).toLowerCase();
|
|
139
|
+
var id=el.id?('#'+el.id):'';
|
|
140
|
+
var classes='';
|
|
141
|
+
try{
|
|
142
|
+
var cls=(el.className&&typeof el.className==='string')
|
|
143
|
+
? el.className.trim().split(/\\s+/).filter(Boolean).slice(0,3)
|
|
144
|
+
: [];
|
|
145
|
+
if(cls.length>0){
|
|
146
|
+
classes='.'+cls.join('.');
|
|
147
|
+
}
|
|
148
|
+
}catch(e){}
|
|
149
|
+
return shortText(tag+id+classes);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function ensurePickInspectUi(){
|
|
153
|
+
if(!document.body) return;
|
|
154
|
+
if(!pickInspectBox){
|
|
155
|
+
pickInspectBox=document.createElement('div');
|
|
156
|
+
pickInspectBox.setAttribute('data-checkpoint-inspect','box');
|
|
157
|
+
pickInspectBox.style.position='fixed';
|
|
158
|
+
pickInspectBox.style.left='0';
|
|
159
|
+
pickInspectBox.style.top='0';
|
|
160
|
+
pickInspectBox.style.width='0';
|
|
161
|
+
pickInspectBox.style.height='0';
|
|
162
|
+
pickInspectBox.style.border='2px solid #6366f1';
|
|
163
|
+
pickInspectBox.style.background='rgba(99,102,241,0.12)';
|
|
164
|
+
pickInspectBox.style.boxSizing='border-box';
|
|
165
|
+
pickInspectBox.style.borderRadius='4px';
|
|
166
|
+
pickInspectBox.style.pointerEvents='none';
|
|
167
|
+
pickInspectBox.style.zIndex='2147483646';
|
|
168
|
+
pickInspectBox.style.display='none';
|
|
169
|
+
document.body.appendChild(pickInspectBox);
|
|
170
|
+
}
|
|
171
|
+
if(!pickInspectLabel){
|
|
172
|
+
pickInspectLabel=document.createElement('div');
|
|
173
|
+
pickInspectLabel.setAttribute('data-checkpoint-inspect','label');
|
|
174
|
+
pickInspectLabel.style.position='fixed';
|
|
175
|
+
pickInspectLabel.style.left='0';
|
|
176
|
+
pickInspectLabel.style.top='0';
|
|
177
|
+
pickInspectLabel.style.maxWidth='380px';
|
|
178
|
+
pickInspectLabel.style.padding='6px 8px';
|
|
179
|
+
pickInspectLabel.style.borderRadius='8px';
|
|
180
|
+
pickInspectLabel.style.border='1px solid rgba(148,163,184,0.45)';
|
|
181
|
+
pickInspectLabel.style.background='rgba(15,23,42,0.96)';
|
|
182
|
+
pickInspectLabel.style.color='#e2e8f0';
|
|
183
|
+
pickInspectLabel.style.font='12px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace';
|
|
184
|
+
pickInspectLabel.style.whiteSpace='pre-line';
|
|
185
|
+
pickInspectLabel.style.wordBreak='break-word';
|
|
186
|
+
pickInspectLabel.style.pointerEvents='none';
|
|
187
|
+
pickInspectLabel.style.zIndex='2147483647';
|
|
188
|
+
pickInspectLabel.style.display='none';
|
|
189
|
+
pickInspectLabel.style.boxShadow='0 6px 20px rgba(0,0,0,0.35)';
|
|
190
|
+
document.body.appendChild(pickInspectLabel);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function hidePickInspectUi(){
|
|
195
|
+
if(pickInspectBox) pickInspectBox.style.display='none';
|
|
196
|
+
if(pickInspectLabel) pickInspectLabel.style.display='none';
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function renderPickInspect(target,mouseX,mouseY){
|
|
200
|
+
ensurePickInspectUi();
|
|
201
|
+
if(!pickInspectBox||!pickInspectLabel||!target||target.nodeType!==1){
|
|
202
|
+
hidePickInspectUi();
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
var sourceTarget=findBestSourceAnchorTarget(target);
|
|
206
|
+
var anchorEl=sourceTarget.element||target;
|
|
207
|
+
var sourceAnchor=sourceTarget.sourceAnchor||getSourceAnchor(anchorEl);
|
|
208
|
+
var rect=anchorEl.getBoundingClientRect?anchorEl.getBoundingClientRect():null;
|
|
209
|
+
if(!rect||rect.width<1||rect.height<1){
|
|
210
|
+
hidePickInspectUi();
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
pickInspectBox.style.display='block';
|
|
215
|
+
pickInspectBox.style.left=Math.max(0,rect.left)+'px';
|
|
216
|
+
pickInspectBox.style.top=Math.max(0,rect.top)+'px';
|
|
217
|
+
pickInspectBox.style.width=Math.max(1,rect.width)+'px';
|
|
218
|
+
pickInspectBox.style.height=Math.max(1,rect.height)+'px';
|
|
219
|
+
|
|
220
|
+
var primary=getInspectElementLabel(anchorEl);
|
|
221
|
+
var sourceLabel='(no source metadata)';
|
|
222
|
+
if(sourceAnchor){
|
|
223
|
+
var leaf=getFileLeaf(sourceAnchor.source_file);
|
|
224
|
+
if(leaf&&typeof sourceAnchor.source_line==='number'){
|
|
225
|
+
sourceLabel=leaf+':'+sourceAnchor.source_line;
|
|
226
|
+
}else if(leaf){
|
|
227
|
+
sourceLabel=leaf;
|
|
228
|
+
}else if(sourceAnchor.component_name){
|
|
229
|
+
sourceLabel=sourceAnchor.component_name;
|
|
230
|
+
}
|
|
231
|
+
if(sourceAnchor.explicit_id){
|
|
232
|
+
sourceLabel=sourceLabel+' · #'+sourceAnchor.explicit_id;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
pickInspectLabel.textContent=primary+'\\n'+sourceLabel;
|
|
236
|
+
pickInspectLabel.style.display='block';
|
|
237
|
+
|
|
238
|
+
var viewW=window.innerWidth||document.documentElement.clientWidth||0;
|
|
239
|
+
var viewH=window.innerHeight||document.documentElement.clientHeight||0;
|
|
240
|
+
var labelRect=pickInspectLabel.getBoundingClientRect();
|
|
241
|
+
var left=mouseX+14;
|
|
242
|
+
var top=mouseY+14;
|
|
243
|
+
if(left+labelRect.width>viewW-8){
|
|
244
|
+
left=Math.max(8,mouseX-labelRect.width-14);
|
|
245
|
+
}
|
|
246
|
+
if(top+labelRect.height>viewH-8){
|
|
247
|
+
top=Math.max(8,mouseY-labelRect.height-14);
|
|
248
|
+
}
|
|
249
|
+
pickInspectLabel.style.left=left+'px';
|
|
250
|
+
pickInspectLabel.style.top=top+'px';
|
|
251
|
+
}
|
|
252
|
+
|
|
123
253
|
function elementSelector(el){
|
|
124
254
|
if(!el||!el.tagName) return '';
|
|
125
255
|
var tag=el.tagName.toLowerCase();
|
|
@@ -372,6 +502,9 @@ function trackingScript() {
|
|
|
372
502
|
}
|
|
373
503
|
|
|
374
504
|
function buildAnchorPayload(el,clientX,clientY){
|
|
505
|
+
var sourceTarget=findBestSourceAnchorTarget(el);
|
|
506
|
+
var anchorEl=sourceTarget.element||el;
|
|
507
|
+
var sourceAnchor=sourceTarget.sourceAnchor||getSourceAnchor(anchorEl)||null;
|
|
375
508
|
var metrics=getMetrics();
|
|
376
509
|
var textSelf='';
|
|
377
510
|
var textParent='';
|
|
@@ -381,7 +514,7 @@ function trackingScript() {
|
|
|
381
514
|
}catch(e){}
|
|
382
515
|
var fallback=buildCoordFallback(clientX,clientY,metrics);
|
|
383
516
|
try{
|
|
384
|
-
var rect=
|
|
517
|
+
var rect=anchorEl&&anchorEl.getBoundingClientRect?anchorEl.getBoundingClientRect():null;
|
|
385
518
|
if(rect){
|
|
386
519
|
var safeW=Math.max(1,rect.width||1);
|
|
387
520
|
var safeH=Math.max(1,rect.height||1);
|
|
@@ -390,15 +523,15 @@ function trackingScript() {
|
|
|
390
523
|
}
|
|
391
524
|
}catch(e){}
|
|
392
525
|
return {
|
|
393
|
-
selector_chain:
|
|
394
|
-
dom_fingerprint:
|
|
526
|
+
selector_chain:[],
|
|
527
|
+
dom_fingerprint:null,
|
|
395
528
|
text_context:{
|
|
396
529
|
self:textSelf,
|
|
397
530
|
parent:textParent
|
|
398
531
|
},
|
|
399
|
-
container_hint:
|
|
532
|
+
container_hint:null,
|
|
400
533
|
transient_context:getTransientContext(el),
|
|
401
|
-
source_anchor:
|
|
534
|
+
source_anchor:sourceAnchor,
|
|
402
535
|
coord_fallback:fallback
|
|
403
536
|
};
|
|
404
537
|
}
|
|
@@ -548,6 +681,44 @@ function trackingScript() {
|
|
|
548
681
|
};
|
|
549
682
|
}
|
|
550
683
|
|
|
684
|
+
function getSourceAnchorStrength(anchor){
|
|
685
|
+
if(!anchor||typeof anchor!=='object') return 0;
|
|
686
|
+
var score=0;
|
|
687
|
+
if(anchor.explicit_id) score+=2000;
|
|
688
|
+
if(anchor.react_key) score+=400;
|
|
689
|
+
if(anchor.source_file) score+=420;
|
|
690
|
+
if(typeof anchor.source_line==='number') score+=260;
|
|
691
|
+
if(anchor.component_name) score+=160;
|
|
692
|
+
if(Array.isArray(anchor.owner_path)&&anchor.owner_path.length>0){
|
|
693
|
+
score+=Math.min(220,anchor.owner_path.length*28);
|
|
694
|
+
}
|
|
695
|
+
return score;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
function findBestSourceAnchorTarget(el){
|
|
699
|
+
if(!el||el.nodeType!==1) return { element:el, sourceAnchor:null };
|
|
700
|
+
var current=el;
|
|
701
|
+
var bestEl=el;
|
|
702
|
+
var bestAnchor=null;
|
|
703
|
+
var bestScore=0;
|
|
704
|
+
var depth=0;
|
|
705
|
+
while(current&¤t.nodeType===1&&depth<12){
|
|
706
|
+
var anchor=getSourceAnchor(current);
|
|
707
|
+
var score=getSourceAnchorStrength(anchor);
|
|
708
|
+
if(score>bestScore){
|
|
709
|
+
bestScore=score;
|
|
710
|
+
bestAnchor=anchor;
|
|
711
|
+
bestEl=current;
|
|
712
|
+
}
|
|
713
|
+
if(anchor&&anchor.explicit_id){
|
|
714
|
+
return { element:current, sourceAnchor:anchor };
|
|
715
|
+
}
|
|
716
|
+
current=current.parentElement;
|
|
717
|
+
depth++;
|
|
718
|
+
}
|
|
719
|
+
return { element:bestEl, sourceAnchor:bestAnchor };
|
|
720
|
+
}
|
|
721
|
+
|
|
551
722
|
function ownerPathSuffixMatches(current,expected){
|
|
552
723
|
if(!Array.isArray(current)||!Array.isArray(expected)||current.length===0||expected.length===0) return 0;
|
|
553
724
|
var i=current.length-1;
|
|
@@ -734,7 +905,10 @@ function trackingScript() {
|
|
|
734
905
|
}
|
|
735
906
|
consider(docNodes);
|
|
736
907
|
}
|
|
737
|
-
|
|
908
|
+
var minScore=160;
|
|
909
|
+
if(sourceAnchor.explicit_id) minScore=900;
|
|
910
|
+
else if(sourceAnchor.source_file) minScore=260;
|
|
911
|
+
if(bestScore<minScore){
|
|
738
912
|
return { element:null, score:bestScore };
|
|
739
913
|
}
|
|
740
914
|
return { element:best, score:bestScore };
|
|
@@ -771,9 +945,6 @@ function trackingScript() {
|
|
|
771
945
|
|
|
772
946
|
function resolveAnchor(payload){
|
|
773
947
|
if(!payload||typeof payload!=='object') return {coordFallback:null,strategy:'none',matchedSelector:null,status:'none'};
|
|
774
|
-
var element=null;
|
|
775
|
-
var strategy='none';
|
|
776
|
-
var matchedSelector=null;
|
|
777
948
|
var metrics=getMetrics();
|
|
778
949
|
var transientRoot=null;
|
|
779
950
|
var hasTransientContext=!!(payload.transient_context&&typeof payload.transient_context==='object');
|
|
@@ -784,72 +955,32 @@ function trackingScript() {
|
|
|
784
955
|
}
|
|
785
956
|
}
|
|
786
957
|
|
|
787
|
-
|
|
788
|
-
if(
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
element=found.element;
|
|
796
|
-
strategy='selector';
|
|
797
|
-
matchedSelector=(scopeTag?scopeTag+': ':'')+candidate.selector;
|
|
798
|
-
return true;
|
|
799
|
-
}
|
|
800
|
-
}
|
|
801
|
-
return false;
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
if(transientRoot){
|
|
805
|
-
trySelectorChain(transientRoot,'transient_root');
|
|
806
|
-
}
|
|
807
|
-
if(!element&&payload.source_anchor){
|
|
808
|
-
var sourceScope=transientRoot||document;
|
|
809
|
-
var sourceMatch=resolveFromSourceAnchor(payload.source_anchor,payload,metrics,sourceScope);
|
|
810
|
-
if(sourceMatch&&sourceMatch.element){
|
|
811
|
-
element=sourceMatch.element;
|
|
812
|
-
strategy='source';
|
|
813
|
-
matchedSelector='source_anchor';
|
|
958
|
+
if(!payload.source_anchor){
|
|
959
|
+
if(payload.coord_fallback){
|
|
960
|
+
return {
|
|
961
|
+
coordFallback:payload.coord_fallback,
|
|
962
|
+
strategy:'fallback',
|
|
963
|
+
matchedSelector:'legacy_coord_fallback',
|
|
964
|
+
status:'fallback_only'
|
|
965
|
+
};
|
|
814
966
|
}
|
|
815
|
-
|
|
816
|
-
if(!element){
|
|
817
|
-
trySelectorChain(document,'document');
|
|
967
|
+
return {coordFallback:null,strategy:'none',matchedSelector:null,status:'none'};
|
|
818
968
|
}
|
|
819
969
|
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
isStrongContainerHint(payload.container_hint)
|
|
825
|
-
){
|
|
826
|
-
var containerNodesInRoot=transientRoot?querySelectorAllSafe(transientRoot,payload.container_hint.selector):[];
|
|
827
|
-
var containerMatch=pickBestElement(containerNodesInRoot,payload,metrics,null);
|
|
828
|
-
if(!containerMatch.element){
|
|
829
|
-
var containerNodes=querySelectorAllSafe(document,payload.container_hint.selector);
|
|
830
|
-
containerMatch=pickBestElement(containerNodes,payload,metrics,null);
|
|
831
|
-
}
|
|
832
|
-
if(containerMatch.element){
|
|
833
|
-
element=containerMatch.element;
|
|
834
|
-
strategy='container';
|
|
835
|
-
matchedSelector=payload.container_hint.selector;
|
|
836
|
-
}
|
|
970
|
+
var sourceScope=transientRoot||document;
|
|
971
|
+
var sourceMatch=resolveFromSourceAnchor(payload.source_anchor,payload,metrics,sourceScope);
|
|
972
|
+
if(!sourceMatch||!sourceMatch.element){
|
|
973
|
+
return {coordFallback:null,strategy:'fallback',matchedSelector:'source_anchor_miss',status:'fallback_only'};
|
|
837
974
|
}
|
|
838
|
-
|
|
839
|
-
var fpMatch=resolveFromFingerprint(payload.dom_fingerprint,payload,metrics,transientRoot||undefined);
|
|
840
|
-
if(!fpMatch.element){
|
|
841
|
-
fpMatch=resolveFromFingerprint(payload.dom_fingerprint,payload,metrics,document);
|
|
842
|
-
}
|
|
843
|
-
if(fpMatch.element){
|
|
844
|
-
element=fpMatch.element;
|
|
845
|
-
strategy='fingerprint';
|
|
846
|
-
}
|
|
847
|
-
}
|
|
848
|
-
if(!element) return {coordFallback:null,strategy:'fallback',matchedSelector:null,status:'fallback_only'};
|
|
849
|
-
var point=getAnchorClientPoint(element,payload);
|
|
975
|
+
var point=getAnchorClientPoint(sourceMatch.element,payload);
|
|
850
976
|
var clientX=point.clientX;
|
|
851
977
|
var clientY=point.clientY;
|
|
852
|
-
return {
|
|
978
|
+
return {
|
|
979
|
+
coordFallback:buildCoordFallback(clientX,clientY,metrics),
|
|
980
|
+
strategy:'source',
|
|
981
|
+
matchedSelector:'source_anchor',
|
|
982
|
+
status:'resolved'
|
|
983
|
+
};
|
|
853
984
|
}
|
|
854
985
|
|
|
855
986
|
function setPickMode(enabled){
|
|
@@ -865,12 +996,22 @@ function trackingScript() {
|
|
|
865
996
|
window.removeEventListener('click',pickClickHandler,true);
|
|
866
997
|
pickClickHandler=null;
|
|
867
998
|
}
|
|
999
|
+
if(pickMoveHandler){
|
|
1000
|
+
window.removeEventListener('mousemove',pickMoveHandler,true);
|
|
1001
|
+
pickMoveHandler=null;
|
|
1002
|
+
}
|
|
868
1003
|
if(pickEscHandler){
|
|
869
1004
|
window.removeEventListener('keydown',pickEscHandler,true);
|
|
870
1005
|
pickEscHandler=null;
|
|
871
1006
|
}
|
|
1007
|
+
hidePickInspectUi();
|
|
872
1008
|
return;
|
|
873
1009
|
}
|
|
1010
|
+
pickMoveHandler=function(ev){
|
|
1011
|
+
if(!pickMode) return;
|
|
1012
|
+
var target=ev.target&&ev.target.nodeType===1?ev.target:null;
|
|
1013
|
+
renderPickInspect(target,ev.clientX,ev.clientY);
|
|
1014
|
+
};
|
|
874
1015
|
pickClickHandler=function(ev){
|
|
875
1016
|
try{
|
|
876
1017
|
if(!pickMode) return;
|
|
@@ -901,6 +1042,7 @@ function trackingScript() {
|
|
|
901
1042
|
setPickMode(false);
|
|
902
1043
|
}
|
|
903
1044
|
};
|
|
1045
|
+
window.addEventListener('mousemove',pickMoveHandler,true);
|
|
904
1046
|
window.addEventListener('click',pickClickHandler,true);
|
|
905
1047
|
window.addEventListener('keydown',pickEscHandler,true);
|
|
906
1048
|
}
|
|
@@ -1063,7 +1205,7 @@ function startInjectionProxy(targetPort) {
|
|
|
1063
1205
|
proxyRes.on('data', (chunk) => chunks.push(chunk));
|
|
1064
1206
|
proxyRes.on('end', () => {
|
|
1065
1207
|
let body = Buffer.concat(chunks).toString('utf-8');
|
|
1066
|
-
if (!body.includes('data-checkpoint')) {
|
|
1208
|
+
if (!body.includes('data-checkpoint-script="1"')) {
|
|
1067
1209
|
if (body.includes('</head>')) {
|
|
1068
1210
|
body = body.replace('</head>', SCRIPT + '\n</head>');
|
|
1069
1211
|
}
|