@01.works/visual-review 0.1.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.
package/LICENSE ADDED
@@ -0,0 +1,10 @@
1
+ Copyright (c) 2026 01.works. All rights reserved.
2
+
3
+ This package and the original 01.works Visual Review product code are
4
+ proprietary and are not offered under an open-source license. No permission is
5
+ granted to copy, modify, redistribute, sublicense, or create derivative works
6
+ except under a separate written agreement with 01.works.
7
+
8
+ Third-party components remain governed by their respective licenses. Their
9
+ copyright and license notices are provided in THIRD_PARTY_NOTICES.md and the
10
+ LICENSES directory.
@@ -0,0 +1,187 @@
1
+ Apache License
2
+
3
+ Version 2.0, January 2004
4
+
5
+ http://www.apache.org/licenses/
6
+
7
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
8
+
9
+ 1. Definitions.
10
+
11
+ "License" shall mean the terms and conditions for use, reproduction, and
12
+ distribution as defined by Sections 1 through 9 of this document.
13
+
14
+ "Licensor" shall mean the copyright owner or entity authorized by the
15
+ copyright owner that is granting the License.
16
+
17
+ "Legal Entity" shall mean the union of the acting entity and all other
18
+ entities that control, are controlled by, or are under common control with
19
+ that entity. For the purposes of this definition, "control" means (i) the
20
+ power, direct or indirect, to cause the direction or management of such
21
+ entity, whether by contract or otherwise, or (ii) ownership of fifty percent
22
+ (50%) or more of the outstanding shares, or (iii) beneficial ownership of
23
+ such entity.
24
+
25
+ "You" (or "Your") shall mean an individual or Legal Entity exercising
26
+ permissions granted by this License.
27
+
28
+ "Source" form shall mean the preferred form for making modifications,
29
+ including but not limited to software source code, documentation source, and
30
+ configuration files.
31
+
32
+ "Object" form shall mean any form resulting from mechanical transformation
33
+ or translation of a Source form, including but not limited to compiled object
34
+ code, generated documentation, and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or Object form,
37
+ made available under the License, as indicated by a copyright notice that is
38
+ included in or attached to the work.
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object form,
41
+ that is based on (or derived from) the Work and for which the editorial
42
+ revisions, annotations, elaborations, or other modifications represent, as a
43
+ whole, an original work of authorship. For the purposes of this License,
44
+ Derivative Works shall not include works that remain separable from, or
45
+ merely link (or bind by name) to the interfaces of, the Work and Derivative
46
+ Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including the original
49
+ version of the Work and any modifications or additions to that Work or
50
+ Derivative Works thereof, that is intentionally submitted to Licensor for
51
+ inclusion in the Work by the copyright owner or by an individual or Legal
52
+ Entity authorized to submit on behalf of the copyright owner. For the
53
+ purposes of this definition, "submitted" means any form of electronic,
54
+ verbal, or written communication sent to the Licensor or its representatives,
55
+ including but not limited to communication on electronic mailing lists,
56
+ source code control systems, and issue tracking systems that are managed by,
57
+ or on behalf of, the Licensor for the purpose of discussing and improving the
58
+ Work, but excluding communication that is conspicuously marked or otherwise
59
+ designated in writing by the copyright owner as "Not a Contribution."
60
+
61
+ "Contributor" shall mean Licensor and any individual or Legal Entity on
62
+ behalf of whom a Contribution has been received by Licensor and subsequently
63
+ incorporated within the Work.
64
+
65
+ 2. Grant of Copyright License. Subject to the terms and conditions of this
66
+ License, each Contributor hereby grants to You a perpetual, worldwide,
67
+ non-exclusive, no-charge, royalty-free, irrevocable copyright license to
68
+ reproduce, prepare Derivative Works of, publicly display, publicly perform,
69
+ sublicense, and distribute the Work and such Derivative Works in Source or
70
+ Object form.
71
+
72
+ 3. Grant of Patent License. Subject to the terms and conditions of this
73
+ License, each Contributor hereby grants to You a perpetual, worldwide,
74
+ non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this
75
+ section) patent license to make, have made, use, offer to sell, sell, import,
76
+ and otherwise transfer the Work, where such license applies only to those
77
+ patent claims licensable by such Contributor that are necessarily infringed
78
+ by their Contribution(s) alone or by combination of their Contribution(s)
79
+ with the Work to which such Contribution(s) was submitted. If You institute
80
+ patent litigation against any entity (including a cross-claim or counterclaim
81
+ in a lawsuit) alleging that the Work or a Contribution incorporated within
82
+ the Work constitutes direct or contributory patent infringement, then any
83
+ patent licenses granted to You under this License for that Work shall
84
+ terminate as of the date such litigation is filed.
85
+
86
+ 4. Redistribution. You may reproduce and distribute copies of the Work or
87
+ Derivative Works thereof in any medium, with or without modifications, and in
88
+ Source or Object form, provided that You meet the following conditions:
89
+
90
+ (a) You must give any other recipients of the Work or Derivative Works a copy
91
+ of this License; and
92
+
93
+ (b) You must cause any modified files to carry prominent notices stating that
94
+ You changed the files; and
95
+
96
+ (c) You must retain, in the Source form of any Derivative Works that You
97
+ distribute, all copyright, patent, trademark, and attribution notices from
98
+ the Source form of the Work, excluding those notices that do not pertain
99
+ to any part of the Derivative Works; and
100
+
101
+ (d) If the Work includes a "NOTICE" text file as part of its distribution,
102
+ then any Derivative Works that You distribute must include a readable copy
103
+ of the attribution notices contained within such NOTICE file, excluding
104
+ those notices that do not pertain to any part of the Derivative Works, in
105
+ at least one of the following places: within a NOTICE text file distributed
106
+ as part of the Derivative Works; within the Source form or documentation,
107
+ if provided along with the Derivative Works; or, within a display generated
108
+ by the Derivative Works, if and wherever such third-party notices normally
109
+ appear. The contents of the NOTICE file are for informational purposes only
110
+ and do not modify the License. You may add Your own attribution notices
111
+ within Derivative Works that You distribute, alongside or as an addendum to
112
+ the NOTICE text from the Work, provided that such additional attribution
113
+ notices cannot be construed as modifying the License.
114
+
115
+ You may add Your own copyright statement to Your modifications and may
116
+ provide additional or different license terms and conditions for use,
117
+ reproduction, or distribution of Your modifications, or for any such
118
+ Derivative Works as a whole, provided Your use, reproduction, and distribution
119
+ of the Work otherwise complies with the conditions stated in this License.
120
+
121
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any
122
+ Contribution intentionally submitted for inclusion in the Work by You to the
123
+ Licensor shall be under the terms and conditions of this License, without any
124
+ additional terms or conditions. Notwithstanding the above, nothing herein
125
+ shall supersede or modify the terms of any separate license agreement you may
126
+ have executed with Licensor regarding such Contributions.
127
+
128
+ 6. Trademarks. This License does not grant permission to use the trade names,
129
+ trademarks, service marks, or product names of the Licensor, except as required
130
+ for reasonable and customary use in describing the origin of the Work and
131
+ reproducing the content of the NOTICE file.
132
+
133
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in
134
+ writing, Licensor provides the Work (and each Contributor provides its
135
+ Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
136
+ KIND, either express or implied, including, without limitation, any warranties
137
+ or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
138
+ PARTICULAR PURPOSE. You are solely responsible for determining the
139
+ appropriateness of using or redistributing the Work and assume any risks
140
+ associated with Your exercise of permissions under this License.
141
+
142
+ 8. Limitation of Liability. In no event and under no legal theory, whether in
143
+ tort (including negligence), contract, or otherwise, unless required by
144
+ applicable law (such as deliberate and grossly negligent acts) or agreed to in
145
+ writing, shall any Contributor be liable to You for damages, including any
146
+ direct, indirect, special, incidental, or consequential damages of any
147
+ character arising as a result of this License or out of the use or inability
148
+ to use the Work (including but not limited to damages for loss of goodwill,
149
+ work stoppage, computer failure or malfunction, or any and all other
150
+ commercial damages or losses), even if such Contributor has been advised of
151
+ the possibility of such damages.
152
+
153
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work
154
+ or Derivative Works thereof, You may choose to offer, and charge a fee for,
155
+ acceptance of support, warranty, indemnity, or other liability obligations
156
+ and/or rights consistent with this License. However, in accepting such
157
+ obligations, You may act only on Your own behalf and on Your sole
158
+ responsibility, not on behalf of any other Contributor, and only if You agree
159
+ to indemnify, defend, and hold each Contributor harmless for any liability
160
+ incurred by, or claims asserted against, such Contributor by reason of your
161
+ accepting any such warranty or additional liability.
162
+
163
+ END OF TERMS AND CONDITIONS
164
+
165
+ APPENDIX: How to apply the Apache License to your work.
166
+
167
+ To apply the Apache License to your work, attach the following boilerplate
168
+ notice, with the fields enclosed by brackets "[]" replaced with your own
169
+ identifying information. (Don't include the brackets!) The text should be
170
+ enclosed in the appropriate comment syntax for the file format. We also
171
+ recommend that a file or class name and description of purpose be included on
172
+ the same "printed page" as the copyright notice for easier identification
173
+ within third-party archives.
174
+
175
+ Copyright [yyyy] [name of copyright owner]
176
+
177
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
178
+ this file except in compliance with the License. You may obtain a copy of the
179
+ License at
180
+
181
+ http://www.apache.org/licenses/LICENSE-2.0
182
+
183
+ Unless required by applicable law or agreed to in writing, software
184
+ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
185
+ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
186
+ License for the specific language governing permissions and limitations under
187
+ the License.
package/README.md ADDED
@@ -0,0 +1,212 @@
1
+ # @01.works/visual-review
2
+
3
+ 01.works가 호스팅하는 초대 전용 staging visual feedback widget입니다. 설치한
4
+ project는 InstantDB App ID나 admin credential을 설정하지 않습니다.
5
+
6
+ > Release status: package metadata와 React/Vite/Next 호환성 검증은 끝났지만
7
+ > `@01.works/visual-review`은 아직 npm에 publish하지 않았습니다.
8
+ > `visual-review.01.works`도 DNS/TLS 검증 전입니다. 아래 설치 예시는 최초 release
9
+ > 후의 public API입니다.
10
+
11
+ Package metadata의 consumer engine 선언은 Node `>=18.18`입니다. Release CI는
12
+ Node `24.18.0`에서 실행합니다.
13
+
14
+ ### Build adapter 의존성
15
+
16
+ `@babel/core`, `@babel/parser`, JSX/TypeScript transform plugin과 `magic-string`은
17
+ Vite/Next production build에서 source marker와 private-map index를 만드는 Node 전용
18
+ build adapter 의존성입니다. 브라우저 entry는 이 패키지들을 import하지 않으며,
19
+ release verifier가 dormant root의 정적 import 경계와 6 KB gzip 상한을 별도로
20
+ 검사합니다.
21
+
22
+ manifest의 caret 범위는 지원 가능한 adapter patch 범위를 의도적으로 표현합니다.
23
+ 실제 설치 버전은 consumer lockfile이 고정하므로 애플리케이션의 lockfile을 함께
24
+ 커밋해야 합니다. Release 검증은 빈 consumer 프로젝트에 tarball만 설치한 뒤 이
25
+ 범위에 맞는 resolved dependency tree와 `npm audit --omit=dev
26
+ --audit-level=moderate`를 검사합니다. 이 의존성이나 source-map token, InstantDB
27
+ credential을 browser 설정으로 전달하지 않습니다.
28
+
29
+ `@instantdb/core`는 hosted realtime/auth 경계에 필요한 직접 runtime dependency이며
30
+ `npm install @01.works/visual-review` 때 자동 설치됩니다. Consumer가 App ID를 넣는
31
+ 구조가 아니라, 활성 초대의 hosted bootstrap 응답으로 public App ID를 받습니다.
32
+
33
+ ## 설치
34
+
35
+ ```bash
36
+ npm install @01.works/visual-review
37
+ ```
38
+
39
+ ### React / Vite
40
+
41
+ Vite config에 build identity plugin을 한 번 추가하면 CI deployment metadata 또는
42
+ clean Git HEAD가 widget의 source provenance에 자동으로 기록됩니다. 브라우저에
43
+ 주입하는 build identity는 공개 build ID와 full commit SHA 두 값뿐입니다. provider deployment ID가 없는
44
+ same-commit rebuild에는 `git:<sha>:deploy:<public-random-variant>` 형식의 서로 다른
45
+ build ID를 발급합니다. 이 public variant는 private marker salt와 upload token에서
46
+ 독립적으로 생성되므로 token 회전 시에도 현재 build identity가 바뀌지 않습니다.
47
+
48
+ ```ts
49
+ // vite.config.ts
50
+ import { defineConfig } from 'vite';
51
+ import react from '@vitejs/plugin-react';
52
+ import { visualReview } from '@01.works/visual-review/vite';
53
+
54
+ export default defineConfig({
55
+ plugins: [react(), visualReview()],
56
+ });
57
+ ```
58
+
59
+ Vite와 Next.js의 production build는 upload token이 없어도 per-build HMAC opaque
60
+ marker와 generated-asset locator index를 기본 생성합니다. 공개 산출물에는 raw
61
+ repository source path/line, marker salt, upload token을 넣지 않습니다.
62
+ `sourceMetadata: false`를 명시한 경우에만 marker/index adapter를 끄고 공개 build
63
+ identity만 남깁니다. 이 설정은 private source-map upload를 활성화하거나 비활성화하지
64
+ 않으며 upload는 아래 `sourceMaps`/token gate를 그대로 따릅니다.
65
+
66
+ CI에 project-scoped `VISUAL_REVIEW_SOURCE_MAP_TOKEN`을 설정하면 같은 plugin이
67
+ browser build에 hidden source map을 만들고 기본 서비스
68
+ `https://visual-review.01.works`로 비공개 업로드합니다. 업로드가 완료되거나 실패한
69
+ 뒤에는 배포 `outDir`의 `.map`을 모두 제거하며, 업로드 또는 정리에 실패하면 build도
70
+ 실패합니다. token은 Vite config의 Node process에서만 읽고 browser `define`이나
71
+ runtime bundle에 넣지 않습니다. `inline` source map은 활성 상태에서 거부합니다.
72
+
73
+ Vite와 Next.js adapter, private upload API, 저장소, retention 경계는 package
74
+ verifier에서 함께 검증합니다. 다만 01.works production backend는 전용 PostgreSQL
75
+ runtime role, private Blob/OIDC gate가 provision되기 전까지
76
+ `VISUAL_REVIEW_SOURCE_MAP_BACKEND=disabled`로 명시적으로 닫아 둡니다. 해당 capability가
77
+ 활성화되기 전에는 production consumer에 source-map token을 설정하지 마세요.
78
+
79
+ local/self-hosted upload API를 검증할 때만 Node config에서 service origin을 바꿉니다.
80
+
81
+ ```ts
82
+ visualReview({
83
+ sourceMaps: {
84
+ serviceUrl: 'http://localhost:8787',
85
+ },
86
+ })
87
+ ```
88
+
89
+ `sourceMaps: false`는 CI environment에 token이 있어도 이 build의 업로드를 명시적으로
90
+ 끕니다. `sourceMaps: true`는 업로드를 명시적으로 요구하므로 token이 없으면 fail
91
+ closed합니다.
92
+
93
+ ```tsx
94
+ import { VisualReview } from '@01.works/visual-review/react';
95
+
96
+ export function App() {
97
+ return (
98
+ <VisualReview
99
+ enabled={import.meta.env.VITE_VISUAL_REVIEW_ENABLED === 'true'}
100
+ build={{ mode: 'preview' }}
101
+ />
102
+ );
103
+ }
104
+ ```
105
+
106
+ ### Next.js App Router
107
+
108
+ 지원 검증 범위는 Next.js 15.5와 16입니다. `/next` entry가 client boundary를
109
+ 포함하므로 server layout에서 import할 수 있습니다. `next.config` wrapper는
110
+ object와 sync/async config factory를 보존합니다. 기존 webpack/Turbopack 설정을
111
+ 유지하면서 실제 CLI가 선택한 bundler에 opaque source marker loader를 추가하고,
112
+ build identity로는 같은 공개 provenance 두 값만 추가합니다.
113
+ Next가 config를 다시 평가하는 compiler worker에는 main build가 확정한 공개
114
+ `buildId`/`gitCommit`만 process-local record로 전달합니다. 이 record는 엄격히
115
+ 검증되며 source-map token과 private marker salt를 포함하거나 산출물에 내보내지
116
+ 않습니다.
117
+
118
+ ```ts
119
+ // next.config.mjs
120
+ import { withVisualReview } from '@01.works/visual-review/next-config';
121
+
122
+ export default withVisualReview({
123
+ reactStrictMode: true,
124
+ });
125
+ ```
126
+
127
+ ```tsx
128
+ import { VisualReview } from '@01.works/visual-review/next';
129
+
130
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
131
+ return (
132
+ <html lang="ko">
133
+ <body>
134
+ {children}
135
+ <VisualReview
136
+ enabled={process.env.NEXT_PUBLIC_VISUAL_REVIEW_ENABLED === 'true'}
137
+ build={{ mode: 'preview' }}
138
+ />
139
+ </body>
140
+ </html>
141
+ );
142
+ }
143
+ ```
144
+
145
+ ### Vanilla TypeScript
146
+
147
+ ```ts
148
+ import { installVisualReview } from '@01.works/visual-review';
149
+
150
+ const review = installVisualReview({
151
+ enabled: import.meta.env.VITE_VISUAL_REVIEW_ENABLED === 'true',
152
+ });
153
+
154
+ // History API navigation is observed automatically.
155
+ // 필요한 경우 await review.refresh();
156
+ ```
157
+
158
+ 지원되는 deployment commit 환경변수가 없으면 clean consumer Git HEAD를 사용합니다.
159
+ dirty worktree, Git 미설치, 유효하지 않은 SHA에서는 commit을 추측하지 않고
160
+ `unversioned`/`null`로 남깁니다. 명시적 release identity가 필요하면 build config에서
161
+ `visualReview({ buildId, gitCommit })` 또는
162
+ `withVisualReview(config, { buildId, gitCommit })`을 사용합니다. `gitCommit: null`은
163
+ 자동 탐색을 명시적으로 끕니다. 명시한 `buildId`는 서로 다른 deployment output에
164
+ 재사용하면 immutable source-map release가 fail closed하므로 배포마다 고유해야 합니다.
165
+ commit은 full 40/64자리 SHA만 허용합니다.
166
+ build adapter는 staging/production mode를 추측하지 않으므로 review deployment의
167
+ component에는 `build={{ mode: 'preview' }}`를 명시합니다.
168
+
169
+ ## Activation
170
+
171
+ `enabled`가 생략됐거나 정확히 `true`가 아니면 DOM, storage, auth, dynamic runtime
172
+ import와 network bootstrap을 시작하지 않습니다. production에는 flag를 설정하지
173
+ 말고 Preview/Staging environment에만 설정합니다.
174
+
175
+ 처음에는 `?visual-review=<invitation-id>` 초대 링크로 접근합니다. hosted service가
176
+ 정확한 origin/path와 invitation을 activation gate로 확인하고, magic-code login 뒤
177
+ browser가 accept endpoint에 refresh token을 보냅니다. Server는
178
+ `db.asUser({ token })`으로 user-scoped claim을 실행하며 완료된 뒤에만 client가
179
+ 정확한 page를 선택해 Instant subscription과 overlay를 mount합니다. `revokedAt`,
180
+ expiry와 claim 시 membership/project mismatch는 fail closed합니다.
181
+
182
+ public `enabled` flag는 load gate이고 registered origin/path는 hosted
183
+ activation/page-selection gate입니다. 지속 InstantDB data capability는 active,
184
+ accepted, unexpired, non-tombstoned invitation이 선택한 project 범위입니다.
185
+ reviewer membership은 claim 검증과 comment/reply author identity에 사용되며,
186
+ 접근 철회는 invitation revoke로 수행합니다. admin token은 browser로 전달되지
187
+ 않습니다.
188
+
189
+ 정식 default service는 `https://visual-review.01.works`입니다. DNS 전 repository
190
+ 검증에서는 local service를 사용할 수 있습니다. 현재 public Vercel alias는 exact
191
+ `DASHBOARD_ORIGIN`과 달라 실제 owner workflow의 대체 URL이 아닙니다.
192
+
193
+ ```tsx
194
+ <VisualReview
195
+ enabled
196
+ serviceUrl="http://localhost:8787"
197
+ />
198
+ ```
199
+
200
+ `serviceUrl`은 local/self-hosted integration test용입니다. DNS/TLS 전환 뒤의
201
+ normal consumer는 이 override를 제거합니다.
202
+
203
+ strict CSP host는 response의 style nonce를 `styleNonce`로 전달할 수 있습니다.
204
+ 생략하면 document의 nonce가 있는 script/style에서 감지합니다. nonce는 Visual
205
+ Review auth/error surface와 widget stylesheet에만 적용됩니다.
206
+
207
+ ## 라이선스
208
+
209
+ 01.works 제품 코드는 `UNLICENSED`, All rights reserved입니다. public registry에
210
+ package가 노출되더라도 허가된 계약 범위 밖의 사용권을 부여하지 않습니다.
211
+ 포함된 Pindrop.js, React Grab, InstantDB 등 제3자 코드는 package와 함께 배포되는
212
+ [`THIRD_PARTY_NOTICES.md`](./THIRD_PARTY_NOTICES.md)의 각 라이선스를 따릅니다.
@@ -0,0 +1,160 @@
1
+ # Third-Party Notices
2
+
3
+ The notices below apply only to the identified third-party portions. They do
4
+ not change the proprietary license of the original 01.works product code.
5
+
6
+ ## Pindrop.js
7
+
8
+ Portions of the bundled annotation core and review widget are derived from a
9
+ one-time source snapshot of Pindrop.js.
10
+
11
+ - Repository: https://github.com/huangdun/pindrop.js
12
+ - Snapshot commit: `23d7be3cc3fcfaf29a02931b3537382a0e0f6aeb`
13
+ - Snapshot version: `0.1.30`
14
+ - Author: Dun Huang
15
+ - License: MIT
16
+
17
+ This product is not an upstream-compatible fork.
18
+
19
+ ### MIT License
20
+
21
+ Copyright (c) 2026 Dun Huang
22
+
23
+ Permission is hereby granted, free of charge, to any person obtaining a copy
24
+ of this software and associated documentation files (the "Software"), to deal
25
+ in the Software without restriction, including without limitation the rights
26
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
27
+ copies of the Software, and to permit persons to whom the Software is
28
+ furnished to do so, subject to the following conditions:
29
+
30
+ The above copyright notice and this permission notice shall be included in all
31
+ copies or substantial portions of the Software.
32
+
33
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39
+ SOFTWARE.
40
+
41
+ ## React Grab
42
+
43
+ The bundled selection engine uses `react-grab/primitives`, and the widget UI
44
+ adapts interface elements from the source snapshot below.
45
+
46
+ - Repository: https://github.com/aidenybai/react-grab
47
+ - Version first integrated: `0.1.50`
48
+ - Source snapshot commit: `2a39bc29e5f8bdbd69095cf1d33d91634576cd20`
49
+ - License: MIT
50
+
51
+ ### MIT License
52
+
53
+ Copyright (c) 2025 Aiden Bai
54
+
55
+ Permission is hereby granted, free of charge, to any person obtaining a copy
56
+ of this software and associated documentation files (the "Software"), to deal
57
+ in the Software without restriction, including without limitation the rights
58
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
59
+ copies of the Software, and to permit persons to whom the Software is
60
+ furnished to do so, subject to the following conditions:
61
+
62
+ The above copyright notice and this permission notice shall be included in all
63
+ copies or substantial portions of the Software.
64
+
65
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
66
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
67
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
68
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
69
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
70
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
71
+ SOFTWARE.
72
+
73
+ ## Bippy
74
+
75
+ React Grab includes portions of Bippy.
76
+
77
+ - Repository: https://github.com/aidenybai/bippy
78
+ - Version bundled: `0.6.1`
79
+ - License: MIT
80
+
81
+ Copyright 2024 Aiden Bai
82
+
83
+ Permission is hereby granted, free of charge, to any person obtaining a copy
84
+ of this software and associated documentation files (the "Software"), to deal
85
+ in the Software without restriction, including without limitation the rights
86
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
87
+ copies of the Software, and to permit persons to whom the Software is
88
+ furnished to do so, subject to the following conditions:
89
+
90
+ The above copyright notice and this permission notice shall be included in all
91
+ copies or substantial portions of the Software.
92
+
93
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
94
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
95
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
96
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
97
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
98
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
99
+ SOFTWARE.
100
+
101
+ ## InstantDB JavaScript SDK
102
+
103
+ The browser runtime bundles `@instantdb/core` and `@instantdb/version`, first
104
+ integrated at version `1.0.52`.
105
+
106
+ - Repository: https://github.com/instantdb/instant
107
+ - License: Apache License 2.0
108
+ - License text: `LICENSES/Apache-2.0.txt`
109
+
110
+ ## Mutative
111
+
112
+ - Repository: https://github.com/unadlib/mutative
113
+ - Version bundled: `1.3.0`
114
+ - License: MIT
115
+
116
+ Copyright (c) 2022 Michael Lin
117
+
118
+ Permission is hereby granted, free of charge, to any person obtaining a copy
119
+ of this software and associated documentation files (the "Software"), to deal
120
+ in the Software without restriction, including without limitation the rights
121
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
122
+ copies of the Software, and to permit persons to whom the Software is
123
+ furnished to do so, subject to the following conditions:
124
+
125
+ The above copyright notice and this permission notice shall be included in all
126
+ copies or substantial portions of the Software.
127
+
128
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
129
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
130
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
131
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
132
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
133
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
134
+ SOFTWARE.
135
+
136
+ ## UUID
137
+
138
+ - Repository: https://github.com/uuidjs/uuid
139
+ - Version bundled: `11.1.1`
140
+ - License: MIT
141
+
142
+ Copyright (c) 2010-2020 Robert Kieffer and other contributors
143
+
144
+ Permission is hereby granted, free of charge, to any person obtaining a copy
145
+ of this software and associated documentation files (the "Software"), to deal
146
+ in the Software without restriction, including without limitation the rights
147
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
148
+ copies of the Software, and to permit persons to whom the Software is
149
+ furnished to do so, subject to the following conditions:
150
+
151
+ The above copyright notice and this permission notice shall be included in all
152
+ copies or substantial portions of the Software.
153
+
154
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
155
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
156
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
157
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
158
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
159
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
160
+ SOFTWARE.
@@ -0,0 +1,114 @@
1
+ import { randomBytes } from "node:crypto";
2
+ import { execFileSync } from "node:child_process";
3
+ //#region src/build-identity.ts
4
+ const FULL_GIT_COMMIT = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/i;
5
+ const PUBLIC_BUILD_ID = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/;
6
+ const DEPLOYMENT_VARIANT = /^[0-9a-f]{32}$/;
7
+ const hasOwn = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
8
+ function resolveVisualReviewBuildIdentity(options = {}, context = {
9
+ cwd: process.cwd(),
10
+ env: process.env
11
+ }) {
12
+ const explicitCommit = resolveExplicitCommit(options);
13
+ const gitCommit = explicitCommit.configured ? explicitCommit.value : resolveProviderCommit(context.env) ?? resolveCleanGitHead(context.cwd, context.runGit ?? runGit);
14
+ return {
15
+ buildId: resolveBuildId(options, context.env, gitCommit, context.createDeploymentVariant ?? createDeploymentVariant),
16
+ gitCommit
17
+ };
18
+ }
19
+ function resolveExplicitCommit(options) {
20
+ if (!hasOwn(options, "gitCommit") || options.gitCommit === void 0) return {
21
+ configured: false,
22
+ value: null
23
+ };
24
+ if (options.gitCommit === null) return {
25
+ configured: true,
26
+ value: null
27
+ };
28
+ const commit = normalizeFullCommit(options.gitCommit);
29
+ if (!commit) throw new TypeError("visual-review gitCommit must be a full 40 or 64 character Git SHA");
30
+ return {
31
+ configured: true,
32
+ value: commit
33
+ };
34
+ }
35
+ function resolveProviderCommit(env) {
36
+ const candidates = [
37
+ env.VERCEL_GIT_COMMIT_SHA,
38
+ env.CF_PAGES_COMMIT_SHA,
39
+ env.NETLIFY === "true" ? env.COMMIT_REF : void 0,
40
+ env.RENDER_GIT_COMMIT,
41
+ env.RAILWAY_GIT_COMMIT_SHA,
42
+ env.GITHUB_ACTIONS === "true" ? env.GITHUB_SHA : void 0
43
+ ];
44
+ for (const candidate of candidates) {
45
+ const commit = normalizeFullCommit(candidate);
46
+ if (commit) return commit;
47
+ }
48
+ return null;
49
+ }
50
+ function resolveBuildId(options, env, gitCommit, createVariant) {
51
+ if (hasOwn(options, "buildId") && options.buildId !== void 0) {
52
+ if (!isPublicBuildId(options.buildId)) throw new TypeError("visual-review buildId must be 1-128 characters using letters, numbers, dot, underscore, colon, or hyphen");
53
+ return options.buildId;
54
+ }
55
+ const providerBuildId = [
56
+ prefixedProviderBuildId("vercel", env.VERCEL_DEPLOYMENT_ID),
57
+ env.NETLIFY === "true" ? prefixedProviderBuildId("netlify", env.DEPLOY_ID) : null,
58
+ prefixedProviderBuildId("railway", env.RAILWAY_DEPLOYMENT_ID)
59
+ ].find((value) => value !== null);
60
+ if (providerBuildId) return providerBuildId;
61
+ return gitCommit ? gitDeploymentBuildId(gitCommit, createVariant()) : "unversioned";
62
+ }
63
+ function gitDeploymentBuildId(gitCommit, variant) {
64
+ if (!DEPLOYMENT_VARIANT.test(variant)) throw new Error("visual-review generated an invalid deployment build variant");
65
+ return `git:${gitCommit}:deploy:${variant}`;
66
+ }
67
+ function createDeploymentVariant() {
68
+ return randomBytes(16).toString("hex");
69
+ }
70
+ function prefixedProviderBuildId(provider, value) {
71
+ if (!value) return null;
72
+ const buildId = `${provider}:${value}`;
73
+ return isPublicBuildId(buildId) ? buildId : null;
74
+ }
75
+ function normalizeFullCommit(value) {
76
+ if (typeof value !== "string") return null;
77
+ const normalized = value.trim().toLowerCase();
78
+ return FULL_GIT_COMMIT.test(normalized) ? normalized : null;
79
+ }
80
+ function isPublicBuildId(value) {
81
+ return typeof value === "string" && PUBLIC_BUILD_ID.test(value);
82
+ }
83
+ function resolveCleanGitHead(cwd, runner) {
84
+ try {
85
+ if (runner([
86
+ "status",
87
+ "--porcelain=v1",
88
+ "--untracked-files=all"
89
+ ], cwd).trim().length > 0) return null;
90
+ return normalizeFullCommit(runner([
91
+ "rev-parse",
92
+ "--verify",
93
+ "HEAD"
94
+ ], cwd));
95
+ } catch {
96
+ return null;
97
+ }
98
+ }
99
+ function runGit(arguments_, cwd) {
100
+ return execFileSync("git", arguments_, {
101
+ cwd,
102
+ encoding: "utf8",
103
+ maxBuffer: 64 * 1024,
104
+ stdio: [
105
+ "ignore",
106
+ "pipe",
107
+ "ignore"
108
+ ],
109
+ timeout: 2e3,
110
+ windowsHide: true
111
+ }).trim();
112
+ }
113
+ //#endregion
114
+ export { resolveVisualReviewBuildIdentity as t };