@shivam995364/uplink-nodejs-test 0.1.0-beta.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 (73) hide show
  1. package/Makefile +945 -0
  2. package/README.md +281 -0
  3. package/binding.gyp +105 -0
  4. package/dist/access/index.d.ts +102 -0
  5. package/dist/access/index.d.ts.map +1 -0
  6. package/dist/access/index.js +168 -0
  7. package/dist/access/index.js.map +1 -0
  8. package/dist/debug/index.d.ts +54 -0
  9. package/dist/debug/index.d.ts.map +1 -0
  10. package/dist/debug/index.js +61 -0
  11. package/dist/debug/index.js.map +1 -0
  12. package/dist/download/index.d.ts +106 -0
  13. package/dist/download/index.d.ts.map +1 -0
  14. package/dist/download/index.js +153 -0
  15. package/dist/download/index.js.map +1 -0
  16. package/dist/edge/index.d.ts +101 -0
  17. package/dist/edge/index.d.ts.map +1 -0
  18. package/dist/edge/index.js +128 -0
  19. package/dist/edge/index.js.map +1 -0
  20. package/dist/errors/codes.d.ts +29 -0
  21. package/dist/errors/codes.d.ts.map +1 -0
  22. package/dist/errors/codes.js +35 -0
  23. package/dist/errors/codes.js.map +1 -0
  24. package/dist/errors/exceptions.d.ts +135 -0
  25. package/dist/errors/exceptions.d.ts.map +1 -0
  26. package/dist/errors/exceptions.js +203 -0
  27. package/dist/errors/exceptions.js.map +1 -0
  28. package/dist/errors/factory.d.ts +69 -0
  29. package/dist/errors/factory.d.ts.map +1 -0
  30. package/dist/errors/factory.js +121 -0
  31. package/dist/errors/factory.js.map +1 -0
  32. package/dist/errors/index.d.ts +35 -0
  33. package/dist/errors/index.d.ts.map +1 -0
  34. package/dist/errors/index.js +69 -0
  35. package/dist/errors/index.js.map +1 -0
  36. package/dist/index.d.ts +22 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +61 -0
  39. package/dist/index.js.map +1 -0
  40. package/dist/multipart/index.d.ts +146 -0
  41. package/dist/multipart/index.d.ts.map +1 -0
  42. package/dist/multipart/index.js +244 -0
  43. package/dist/multipart/index.js.map +1 -0
  44. package/dist/native/index.d.ts +72 -0
  45. package/dist/native/index.d.ts.map +1 -0
  46. package/dist/native/index.js +34 -0
  47. package/dist/native/index.js.map +1 -0
  48. package/dist/project/index.d.ts +409 -0
  49. package/dist/project/index.d.ts.map +1 -0
  50. package/dist/project/index.js +529 -0
  51. package/dist/project/index.js.map +1 -0
  52. package/dist/types/index.d.ts +299 -0
  53. package/dist/types/index.d.ts.map +1 -0
  54. package/dist/types/index.js +59 -0
  55. package/dist/types/index.js.map +1 -0
  56. package/dist/uplink.d.ts +99 -0
  57. package/dist/uplink.d.ts.map +1 -0
  58. package/dist/uplink.js +135 -0
  59. package/dist/uplink.js.map +1 -0
  60. package/dist/upload/index.d.ts +153 -0
  61. package/dist/upload/index.d.ts.map +1 -0
  62. package/dist/upload/index.js +206 -0
  63. package/dist/upload/index.js.map +1 -0
  64. package/native/include/uplink.h +545 -0
  65. package/native/include/uplink_compat.h +111 -0
  66. package/native/include/uplink_definitions.h +344 -0
  67. package/native/include/uplink_msvc_compat.h +0 -0
  68. package/native/prebuilds/darwin-arm64/libuplink.dylib +0 -0
  69. package/native/prebuilds/darwin-arm64/uplink_native.node +0 -0
  70. package/native/prebuilds/win32-x64/libuplink.dll +0 -0
  71. package/native/prebuilds/win32-x64/uplink.def +87 -0
  72. package/native/prebuilds/win32-x64/uplink.lib +0 -0
  73. package/package.json +94 -0
package/Makefile ADDED
@@ -0,0 +1,945 @@
1
+ # Makefile for uplink-nodejs
2
+ # Works on: Linux, macOS, Windows (CMD, PowerShell, MinGW/MSYS2)
3
+ #
4
+ # Installation Options:
5
+ # make install - Auto-detect best installation method
6
+ # make install-source - Build everything from source (requires Go)
7
+ # make install-hybrid - Download lib, build addon (requires C compiler)
8
+ # make install-prebuilt - Download everything (Node.js only)
9
+ #
10
+ # Build Commands:
11
+ # make build - Build TypeScript + Native addon
12
+ # make build-uplink - Build uplink-c library from source
13
+ # make build-native - Build Node.js native addon
14
+ #
15
+ # Other Commands:
16
+ # make help - Show this help
17
+ # make verify - Verify installation
18
+ # make clean - Clean build artifacts
19
+ # make test - Run all tests
20
+
21
+ # Detect OS
22
+ # On Windows GitHub Actions (MSYS2/Git Bash), OS=Windows_NT but shell is bash.
23
+ # Detect MSYS/MinGW environment and use POSIX commands in that case.
24
+ # WINDOWS_NATIVE is set only when using cmd.exe (not MSYS2/Git Bash).
25
+ ifeq ($(OS),Windows_NT)
26
+ DETECTED_OS := windows
27
+ ifeq ($(PROCESSOR_ARCHITECTURE),AMD64)
28
+ DETECTED_ARCH := x64
29
+ else ifeq ($(PROCESSOR_ARCHITECTURE),x86)
30
+ DETECTED_ARCH := x86
31
+ else
32
+ DETECTED_ARCH := $(PROCESSOR_ARCHITECTURE)
33
+ endif
34
+ LIB_EXT = .dll
35
+ LIB_PREFIX = lib
36
+ LIB_NAME = libuplink.dll
37
+ PLATFORM = win32-x64
38
+ # Check if running under MSYS2/Git Bash (GitHub Actions Windows runners)
39
+ ifneq ($(MSYSTEM),)
40
+ USE_POSIX_CMDS := 1
41
+ else ifneq ($(shell echo $$BASH_VERSION 2>/dev/null),)
42
+ USE_POSIX_CMDS := 1
43
+ endif
44
+ ifdef USE_POSIX_CMDS
45
+ # MSYS2/Git Bash: use POSIX commands
46
+ MKDIR = mkdir -p $1
47
+ RM = rm -f $1
48
+ RMDIR = rm -rf $1
49
+ CP = cp -f $1 $2
50
+ SEP = /
51
+ else
52
+ # Native Windows (cmd.exe): use Windows commands
53
+ WINDOWS_NATIVE := 1
54
+ MKDIR = if not exist "$(subst /,\,$1)" mkdir "$(subst /,\,$1)"
55
+ RM = if exist "$(subst /,\,$1)" del /q "$(subst /,\,$1)"
56
+ RMDIR = if exist "$(subst /,\,$1)" rmdir /s /q "$(subst /,\,$1)"
57
+ CP = copy /y "$(subst /,\,$1)" "$(subst /,\,$2)"
58
+ SEP = \\
59
+ endif
60
+ else
61
+ UNAME_S := $(shell uname -s)
62
+ UNAME_M := $(shell uname -m)
63
+ ifeq ($(UNAME_S),Darwin)
64
+ DETECTED_OS := darwin
65
+ LIB_EXT = .dylib
66
+ LIB_PREFIX = lib
67
+ LIB_NAME = libuplink.dylib
68
+ else
69
+ DETECTED_OS := linux
70
+ LIB_EXT = .so
71
+ LIB_PREFIX = lib
72
+ LIB_NAME = libuplink.so
73
+ endif
74
+ ifeq ($(UNAME_M),x86_64)
75
+ DETECTED_ARCH := x64
76
+ else ifeq ($(UNAME_M),aarch64)
77
+ DETECTED_ARCH := arm64
78
+ else ifeq ($(UNAME_M),arm64)
79
+ DETECTED_ARCH := arm64
80
+ else
81
+ DETECTED_ARCH := $(UNAME_M)
82
+ endif
83
+ # Unix commands
84
+ MKDIR = mkdir -p $1
85
+ RM = rm -f $1
86
+ RMDIR = rm -rf $1
87
+ CP = cp -f $1 $2
88
+ SEP = /
89
+ WHICH = command -v
90
+ NULL_REDIR = /dev/null
91
+ FILE_EXISTS = test -f
92
+ DIR_EXISTS = test -d
93
+ PLATFORM = $(DETECTED_OS)-$(DETECTED_ARCH)
94
+ endif
95
+
96
+ # Directories
97
+ PROJECT_DIR := $(CURDIR)
98
+ UPLINK_C_DIR := $(PROJECT_DIR)/../uplink-c
99
+ PREBUILDS_DIR := $(PROJECT_DIR)/native/prebuilds
100
+ INCLUDE_DIR := $(PROJECT_DIR)/native/include
101
+ PLATFORM_DIR := $(PREBUILDS_DIR)/$(PLATFORM)
102
+ BUILD_DIR := $(PROJECT_DIR)/build
103
+ DIST_DIR := $(PROJECT_DIR)/dist
104
+
105
+ # When PLATFORM is overridden (e.g., PLATFORM=darwin-x64 for cross-compilation),
106
+ # derive the target arch from PLATFORM so Go and node-gyp build for the right arch.
107
+ PLATFORM_ARCH := $(lastword $(subst -, ,$(PLATFORM)))
108
+ ifneq ($(PLATFORM_ARCH),$(DETECTED_ARCH))
109
+ EFFECTIVE_ARCH := $(PLATFORM_ARCH)
110
+ else
111
+ EFFECTIVE_ARCH := $(DETECTED_ARCH)
112
+ endif
113
+
114
+ # Go settings for building uplink-c
115
+ GO_OS_darwin := darwin
116
+ GO_OS_linux := linux
117
+ GO_OS_windows := windows
118
+ GO_OS := $(GO_OS_$(DETECTED_OS))
119
+
120
+ GO_ARCH_x64 := amd64
121
+ GO_ARCH_arm64 := arm64
122
+ GO_ARCH := $(GO_ARCH_$(EFFECTIVE_ARCH))
123
+
124
+ # Default target
125
+ .PHONY: all
126
+ all: prebuild build
127
+
128
+ # Info (use 'make help' for full command list)
129
+ .PHONY: info
130
+ info:
131
+ @echo "Build Information:"
132
+ @echo " OS: $(DETECTED_OS)"
133
+ @echo " Architecture: $(DETECTED_ARCH)"
134
+ @echo " Platform: $(PLATFORM)"
135
+ @echo " Library: $(LIB_NAME)"
136
+ @echo " Go OS: $(GO_OS)"
137
+ @echo " Go Arch: $(GO_ARCH)"
138
+ @echo " Project Dir: $(PROJECT_DIR)"
139
+ @echo " Uplink-C Dir: $(UPLINK_C_DIR)"
140
+ @echo " Prebuilds: $(PLATFORM_DIR)"
141
+
142
+ # Create directories
143
+ $(PLATFORM_DIR):
144
+ $(call MKDIR,$(PLATFORM_DIR))
145
+
146
+ $(BUILD_DIR):
147
+ $(call MKDIR,$(BUILD_DIR))
148
+
149
+ $(DIST_DIR):
150
+ $(call MKDIR,$(DIST_DIR))
151
+
152
+ # Prebuild - prepare platform directory
153
+ .PHONY: prebuild
154
+ prebuild: $(PLATFORM_DIR)
155
+ @echo "Prebuild directory ready: $(PLATFORM_DIR)"
156
+
157
+ # Build uplink-c from source (requires Go)
158
+ .PHONY: build-uplink
159
+ build-uplink: $(PLATFORM_DIR)
160
+ @echo "Building uplink-c for $(PLATFORM)..."
161
+ @echo "Source: $(UPLINK_C_DIR)"
162
+ ifdef WINDOWS_NATIVE
163
+ cd "$(UPLINK_C_DIR)" && set CGO_ENABLED=1 && set GOOS=$(GO_OS) && set GOARCH=$(GO_ARCH) && go build -buildmode=c-shared -o $(LIB_NAME)
164
+ $(call CP,$(UPLINK_C_DIR)/$(LIB_NAME),$(PLATFORM_DIR)/$(LIB_NAME))
165
+ @if exist "$(subst /,\,$(UPLINK_C_DIR)/libuplink.h)" $(call CP,$(UPLINK_C_DIR)/libuplink.h,$(INCLUDE_DIR)/uplink.h)
166
+ @if exist "$(subst /,\,$(UPLINK_C_DIR)/uplink_definitions.h)" $(call CP,$(UPLINK_C_DIR)/uplink_definitions.h,$(INCLUDE_DIR)/uplink_definitions.h)
167
+ @if exist "$(subst /,\,$(UPLINK_C_DIR)/uplink_compat.h)" $(call CP,$(UPLINK_C_DIR)/uplink_compat.h,$(INCLUDE_DIR)/uplink_compat.h)
168
+ else
169
+ cd "$(UPLINK_C_DIR)" && CGO_ENABLED=1 GOOS=$(GO_OS) GOARCH=$(GO_ARCH) go build -buildmode=c-shared -o $(LIB_NAME)
170
+ $(call CP,$(UPLINK_C_DIR)/$(LIB_NAME),$(PLATFORM_DIR)/$(LIB_NAME))
171
+ @if [ -f "$(UPLINK_C_DIR)/libuplink.h" ]; then $(call CP,$(UPLINK_C_DIR)/libuplink.h,$(INCLUDE_DIR)/uplink.h); fi
172
+ @if [ -f "$(UPLINK_C_DIR)/uplink_definitions.h" ]; then $(call CP,$(UPLINK_C_DIR)/uplink_definitions.h,$(INCLUDE_DIR)/uplink_definitions.h); fi
173
+ @if [ -f "$(UPLINK_C_DIR)/uplink_compat.h" ]; then $(call CP,$(UPLINK_C_DIR)/uplink_compat.h,$(INCLUDE_DIR)/uplink_compat.h); fi
174
+ endif
175
+ @echo "Built and installed $(LIB_NAME) to $(PLATFORM_DIR)"
176
+ @echo "Headers installed to $(INCLUDE_DIR)"
177
+ @$(MAKE) fix-header-compat
178
+ @$(MAKE) generate-import-lib
179
+
180
+ # Copy uplink-c library from parent folder (if already built)
181
+ .PHONY: copy-uplink
182
+ copy-uplink: $(PLATFORM_DIR)
183
+ @echo "Copying uplink-c library from $(UPLINK_C_DIR)..."
184
+ ifdef WINDOWS_NATIVE
185
+ @if exist "$(subst /,\,$(UPLINK_C_DIR)/$(LIB_NAME))" ( \
186
+ $(call CP,$(UPLINK_C_DIR)/$(LIB_NAME),$(PLATFORM_DIR)/$(LIB_NAME)) && \
187
+ echo "Copied $(LIB_NAME) to $(PLATFORM_DIR)" \
188
+ ) else ( \
189
+ echo "Library not found. Run 'make build-uplink' first." && exit 1 \
190
+ )
191
+ @if exist "$(subst /,\,$(UPLINK_C_DIR)/libuplink.h)" ( \
192
+ $(call CP,$(UPLINK_C_DIR)/libuplink.h,$(INCLUDE_DIR)/uplink.h) && \
193
+ echo "Copied uplink.h to $(INCLUDE_DIR)" \
194
+ )
195
+ @if exist "$(subst /,\,$(UPLINK_C_DIR)/uplink_definitions.h)" ( \
196
+ $(call CP,$(UPLINK_C_DIR)/uplink_definitions.h,$(INCLUDE_DIR)/uplink_definitions.h) && \
197
+ echo "Copied uplink_definitions.h to $(INCLUDE_DIR)" \
198
+ )
199
+ @if exist "$(subst /,\,$(UPLINK_C_DIR)/uplink_compat.h)" ( \
200
+ $(call CP,$(UPLINK_C_DIR)/uplink_compat.h,$(INCLUDE_DIR)/uplink_compat.h) && \
201
+ echo "Copied uplink_compat.h to $(INCLUDE_DIR)" \
202
+ )
203
+ else
204
+ @if [ -f "$(UPLINK_C_DIR)/$(LIB_NAME)" ]; then \
205
+ $(call CP,$(UPLINK_C_DIR)/$(LIB_NAME),$(PLATFORM_DIR)/$(LIB_NAME)); \
206
+ echo "Copied $(LIB_NAME) to $(PLATFORM_DIR)"; \
207
+ else \
208
+ echo "Library not found at $(UPLINK_C_DIR)/$(LIB_NAME)"; \
209
+ echo "Run 'make build-uplink' first."; \
210
+ exit 1; \
211
+ fi
212
+ @if [ -f "$(UPLINK_C_DIR)/libuplink.h" ]; then \
213
+ $(call CP,$(UPLINK_C_DIR)/libuplink.h,$(INCLUDE_DIR)/uplink.h); \
214
+ echo "Copied uplink.h to $(INCLUDE_DIR)"; \
215
+ fi
216
+ @if [ -f "$(UPLINK_C_DIR)/uplink_definitions.h" ]; then \
217
+ $(call CP,$(UPLINK_C_DIR)/uplink_definitions.h,$(INCLUDE_DIR)/uplink_definitions.h); \
218
+ echo "Copied uplink_definitions.h to $(INCLUDE_DIR)"; \
219
+ fi
220
+ @if [ -f "$(UPLINK_C_DIR)/uplink_compat.h" ]; then \
221
+ $(call CP,$(UPLINK_C_DIR)/uplink_compat.h,$(INCLUDE_DIR)/uplink_compat.h); \
222
+ echo "Copied uplink_compat.h to $(INCLUDE_DIR)"; \
223
+ fi
224
+ endif
225
+ @$(MAKE) fix-header-compat
226
+
227
+ # Patch uplink_definitions.h for MSVC compatibility after copying upstream headers.
228
+ # MSVC (C mode) forbids empty structs (error C2016). The upstream header has three
229
+ # empty "options" structs that only GCC/Clang can handle via #pragma diagnostic.
230
+ # This target replaces those empty structs with an #ifdef _MSC_VER / #else block.
231
+ DEFS_HEADER := $(INCLUDE_DIR)/uplink_definitions.h
232
+ .PHONY: fix-header-compat
233
+ fix-header-compat:
234
+ @if [ -f "$(DEFS_HEADER)" ]; then \
235
+ if grep -q '_MSC_VER' "$(DEFS_HEADER)"; then \
236
+ echo " uplink_definitions.h already has MSVC compat — skipping"; \
237
+ else \
238
+ echo " Patching uplink_definitions.h for MSVC empty-struct compat..."; \
239
+ node -e " \
240
+ const fs = require('fs'); \
241
+ const f = process.argv[1]; \
242
+ let src = fs.readFileSync(f, 'utf8'); \
243
+ const marker = '// we need to suppress'; \
244
+ const idx = src.indexOf(marker); \
245
+ if (idx === -1) { console.log(' No empty structs found — skipping'); process.exit(0); } \
246
+ const before = src.slice(0, idx); \
247
+ const msvc = [ \
248
+ '#ifdef _MSC_VER', \
249
+ '', \
250
+ 'typedef struct UplinkMoveObjectOptions { char _reserved; } UplinkMoveObjectOptions;', \
251
+ 'typedef struct UplinkUploadObjectMetadataOptions { char _reserved; } UplinkUploadObjectMetadataOptions;', \
252
+ 'typedef struct UplinkCopyObjectOptions { char _reserved; } UplinkCopyObjectOptions;', \
253
+ '', \
254
+ '#else /* GCC / Clang */', \
255
+ '' \
256
+ ].join('\n'); \
257
+ const after = src.slice(idx); \
258
+ fs.writeFileSync(f, before + msvc + after + '\n#endif /* _MSC_VER */\n'); \
259
+ console.log(' ✓ Patched'); \
260
+ " "$(DEFS_HEADER)"; \
261
+ fi; \
262
+ fi
263
+
264
+ # Generate Windows import library (.lib) from the DLL.
265
+ # MSVC requires a .lib to link against a DLL at compile time.
266
+ # Go's -buildmode=c-shared does not produce one, so we generate it:
267
+ # 1. Extract exported symbols from uplink.h → .def file (via Node.js script)
268
+ # 2. Create uplink.lib from the .def file
269
+ # Tries MSVC lib.exe first (if available via ilammy/msvc-dev-cmd), falls back to
270
+ # dlltool (available in MSYS2/Git Bash on GitHub Actions Windows runners).
271
+ # This target is called automatically on Windows after building the DLL.
272
+ DEF_FILE = $(PLATFORM_DIR)/uplink.def
273
+ LIB_FILE = $(PLATFORM_DIR)/uplink.lib
274
+ .PHONY: generate-import-lib
275
+ generate-import-lib:
276
+ ifeq ($(DETECTED_OS),windows)
277
+ @echo " Generating Windows import library..."
278
+ $(Q)node "$(PROJECT_DIR)/scripts/gen-def.js" "$(INCLUDE_DIR)/uplink.h" "$(DEF_FILE)"
279
+ $(Q)if command -v lib.exe > /dev/null 2>&1; then \
280
+ echo " Using MSVC lib.exe"; \
281
+ lib.exe /def:"$(DEF_FILE)" /out:"$(LIB_FILE)" /machine:x64 /nologo; \
282
+ elif command -v dlltool > /dev/null 2>&1; then \
283
+ echo " Using dlltool"; \
284
+ dlltool -d "$(DEF_FILE)" -l "$(LIB_FILE)" -D libuplink.dll; \
285
+ else \
286
+ echo "ERROR: Neither lib.exe nor dlltool found. Cannot generate import library."; \
287
+ exit 1; \
288
+ fi
289
+ $(Q)echo " ✓ Generated $(LIB_FILE)"
290
+ endif
291
+
292
+ # Build TypeScript
293
+ .PHONY: build-ts
294
+ build-ts:
295
+ @echo "Building TypeScript..."
296
+ npm run build:ts
297
+
298
+ # Build native addon
299
+ .PHONY: build-native
300
+ build-native:
301
+ @echo "Building native addon..."
302
+ npm run build:native
303
+
304
+ # Build all
305
+ .PHONY: build
306
+ build: build-ts build-native
307
+ @echo "Build complete."
308
+
309
+ # Test C code
310
+ .PHONY: test-c
311
+ test-c:
312
+ @echo "Running C tests..."
313
+ npm run test:c
314
+
315
+ # Test JavaScript
316
+ .PHONY: test-js
317
+ test-js:
318
+ @echo "Running JavaScript tests..."
319
+ npm test
320
+
321
+ # Test all
322
+ .PHONY: test
323
+ test: test-c test-js
324
+ @echo "All tests complete."
325
+
326
+ # Check all build prerequisites
327
+ .PHONY: check
328
+ check: check-source-prereqs
329
+ @echo "All prerequisites available."
330
+
331
+ # Clean build artifacts
332
+ .PHONY: clean
333
+ clean:
334
+ @echo "Cleaning build artifacts..."
335
+ $(call RMDIR,$(BUILD_DIR))
336
+ $(call RMDIR,$(DIST_DIR))
337
+ $(call RMDIR,$(PROJECT_DIR)/node_modules/.cache)
338
+ @echo "Clean complete."
339
+
340
+ # Clean everything including prebuilds, downloads, and cloned sources
341
+ .PHONY: clean-all
342
+ clean-all: clean
343
+ @echo "Cleaning prebuilds..."
344
+ $(call RMDIR,$(PREBUILDS_DIR))
345
+ @echo "Cleaning downloads..."
346
+ $(call RMDIR,$(DOWNLOAD_DIR))
347
+ @echo "Cleaning cloned sources..."
348
+ $(call RMDIR,$(UPLINK_C_BUILD_DIR))
349
+ @echo "Clean all complete."
350
+
351
+ # Install dependencies
352
+ .PHONY: install
353
+ install:
354
+ npm install
355
+
356
+ # Lint
357
+ .PHONY: lint
358
+ lint:
359
+ npm run lint
360
+
361
+ # Format
362
+ .PHONY: format
363
+ format:
364
+ npm run format
365
+
366
+ # Verify uplink library is installed
367
+ .PHONY: verify
368
+ verify:
369
+ @echo "Verifying uplink-c installation..."
370
+ ifdef WINDOWS_NATIVE
371
+ @if exist "$(subst /,\,$(PLATFORM_DIR)/$(LIB_NAME))" ( \
372
+ echo "OK: $(LIB_NAME) found at $(PLATFORM_DIR)" \
373
+ ) else ( \
374
+ echo "ERROR: $(LIB_NAME) not found at $(PLATFORM_DIR)" && \
375
+ echo "Run 'make build-uplink' or 'make copy-uplink' first." && \
376
+ exit 1 \
377
+ )
378
+ else
379
+ @if [ -f "$(PLATFORM_DIR)/$(LIB_NAME)" ]; then \
380
+ echo "OK: $(LIB_NAME) found at $(PLATFORM_DIR)"; \
381
+ ls -la "$(PLATFORM_DIR)/$(LIB_NAME)"; \
382
+ else \
383
+ echo "ERROR: $(LIB_NAME) not found at $(PLATFORM_DIR)"; \
384
+ echo "Run 'make build-uplink' or 'make copy-uplink' first."; \
385
+ exit 1; \
386
+ fi
387
+ endif
388
+
389
+ # ==============================================================================
390
+ # SPRINT 13: BINARY DISTRIBUTION SYSTEM
391
+ # ==============================================================================
392
+
393
+ # ------------------------------------------------------------------------------
394
+ # Configuration
395
+ # ------------------------------------------------------------------------------
396
+
397
+ # Versions
398
+ UPLINK_C_VERSION ?= v1.14.0
399
+ ADDON_VERSION ?= $(shell node -p "require('./package.json').version" 2>/dev/null || echo "0.1.0")
400
+
401
+ # GitHub repository for prebuilt binaries
402
+ # Override with: make install-hybrid GITHUB_OWNER=your-username
403
+ GITHUB_OWNER ?= storj-thirdparty
404
+ GITHUB_REPO ?= uplink-nodejs
405
+
406
+ # Download URLs (pointing to your repository's releases)
407
+ # The prebuilt uplink-c library will be hosted on your repo
408
+ UPLINK_C_RELEASE_URL ?= https://github.com/$(GITHUB_OWNER)/$(GITHUB_REPO)/releases/download
409
+ ADDON_RELEASE_URL ?= https://github.com/$(GITHUB_OWNER)/$(GITHUB_REPO)/releases/download
410
+
411
+ # Archive names
412
+ UPLINK_C_ARCHIVE = uplink-c-$(UPLINK_C_VERSION)-$(PLATFORM).tar.gz
413
+ ADDON_ARCHIVE = uplink-nodejs-v$(ADDON_VERSION)-$(PLATFORM).tar.gz
414
+
415
+ # Node addon name
416
+ NODE_ADDON = uplink_native.node
417
+
418
+ # Directories
419
+ DOWNLOAD_DIR = $(PROJECT_DIR)/.downloads
420
+ UPLINK_C_BUILD_DIR ?= $(PROJECT_DIR)/.uplink-c-build
421
+
422
+ # Flags
423
+ VERBOSE ?= 0
424
+ FORCE_DOWNLOAD ?= 0
425
+ SKIP_VERIFY ?= 0
426
+
427
+ # Verbose output control
428
+ ifeq ($(VERBOSE),1)
429
+ Q =
430
+ CURL_QUIET =
431
+ ECHO_VERBOSE = @echo
432
+ else
433
+ Q = @
434
+ CURL_QUIET = -s
435
+ ECHO_VERBOSE = @true
436
+ endif
437
+
438
+ # ------------------------------------------------------------------------------
439
+ # Prerequisites Checks
440
+ # ------------------------------------------------------------------------------
441
+
442
+ .PHONY: check-node
443
+ check-node:
444
+ $(Q)echo "Checking Node.js..."
445
+ ifdef WINDOWS_NATIVE
446
+ $(Q)where node >nul 2>&1 || (echo "ERROR: Node.js not found. Install from https://nodejs.org" && exit 1)
447
+ else
448
+ $(Q)which node > /dev/null 2>&1 || (echo "ERROR: Node.js not found. Install from https://nodejs.org" && exit 1)
449
+ endif
450
+ $(Q)echo " ✓ Node.js $$(node --version)"
451
+
452
+ .PHONY: check-npm
453
+ check-npm: check-node
454
+ $(Q)echo "Checking npm..."
455
+ ifdef WINDOWS_NATIVE
456
+ $(Q)where npm >nul 2>&1 || (echo "ERROR: npm not found" && exit 1)
457
+ else
458
+ $(Q)which npm > /dev/null 2>&1 || (echo "ERROR: npm not found" && exit 1)
459
+ endif
460
+ $(Q)echo " ✓ npm v$$(npm --version)"
461
+
462
+ .PHONY: check-go
463
+ check-go:
464
+ $(Q)echo "Checking Go..."
465
+ ifdef WINDOWS_NATIVE
466
+ $(Q)where go >nul 2>&1 || (echo "ERROR: Go not found. Install from https://golang.org/dl/" && exit 1)
467
+ else
468
+ $(Q)which go > /dev/null 2>&1 || (echo "ERROR: Go not found. Install from https://golang.org/dl/" && exit 1)
469
+ endif
470
+ $(Q)echo " ✓ $$(go version | head -c 30)"
471
+
472
+ .PHONY: check-git
473
+ check-git:
474
+ $(Q)echo "Checking Git..."
475
+ ifdef WINDOWS_NATIVE
476
+ $(Q)where git >nul 2>&1 || (echo "ERROR: Git not found. Install from https://git-scm.com/" && exit 1)
477
+ else
478
+ $(Q)which git > /dev/null 2>&1 || (echo "ERROR: Git not found. Install from https://git-scm.com/" && exit 1)
479
+ endif
480
+ $(Q)echo " ✓ $$(git --version)"
481
+
482
+ .PHONY: check-compiler
483
+ check-compiler:
484
+ $(Q)echo "Checking C compiler..."
485
+ ifdef WINDOWS_NATIVE
486
+ $(Q)(where cl >nul 2>&1 || where gcc >nul 2>&1) || (echo "ERROR: No C compiler found. Install Visual Studio Build Tools" && exit 1)
487
+ else
488
+ $(Q)(which cc > /dev/null 2>&1 || which gcc > /dev/null 2>&1 || which clang > /dev/null 2>&1) || (echo "ERROR: No C compiler found" && exit 1)
489
+ endif
490
+ $(Q)echo " ✓ C compiler available"
491
+
492
+ .PHONY: check-python
493
+ check-python:
494
+ $(Q)echo "Checking Python (for node-gyp)..."
495
+ ifdef WINDOWS_NATIVE
496
+ $(Q)(where python >nul 2>&1 || where python3 >nul 2>&1) || (echo "ERROR: Python not found" && exit 1)
497
+ else
498
+ $(Q)(which python3 > /dev/null 2>&1 || which python > /dev/null 2>&1) || (echo "ERROR: Python not found" && exit 1)
499
+ endif
500
+ $(Q)echo " ✓ Python available"
501
+
502
+ .PHONY: check-curl
503
+ check-curl:
504
+ $(Q)echo "Checking curl..."
505
+ ifdef WINDOWS_NATIVE
506
+ $(Q)where curl >nul 2>&1 || (echo "ERROR: curl not found" && exit 1)
507
+ else
508
+ $(Q)which curl > /dev/null 2>&1 || (echo "ERROR: curl not found" && exit 1)
509
+ endif
510
+ $(Q)echo " ✓ curl available"
511
+
512
+ # Combined prerequisite checks
513
+ .PHONY: check-source-prereqs
514
+ check-source-prereqs: check-node check-npm check-go check-git check-compiler check-python
515
+ $(Q)echo ""
516
+ $(Q)echo "✓ All prerequisites for source build satisfied"
517
+
518
+ .PHONY: check-hybrid-prereqs
519
+ check-hybrid-prereqs: check-node check-npm check-compiler check-python check-curl
520
+ $(Q)echo ""
521
+ $(Q)echo "✓ All prerequisites for hybrid build satisfied"
522
+
523
+ .PHONY: check-prebuilt-prereqs
524
+ check-prebuilt-prereqs: check-node check-curl
525
+ $(Q)echo ""
526
+ $(Q)echo "✓ All prerequisites for prebuilt download satisfied"
527
+
528
+ # ------------------------------------------------------------------------------
529
+ # Download Targets
530
+ # ------------------------------------------------------------------------------
531
+
532
+ $(DOWNLOAD_DIR):
533
+ $(call MKDIR,$(DOWNLOAD_DIR))
534
+
535
+ # Download uplink-c library from GitHub releases
536
+ .PHONY: download-lib
537
+ download-lib: $(PLATFORM_DIR) $(DOWNLOAD_DIR) check-curl
538
+ $(Q)echo "══════════════════════════════════════════════════════════════"
539
+ $(Q)echo " Downloading uplink-c $(UPLINK_C_VERSION) for $(PLATFORM)"
540
+ $(Q)echo "══════════════════════════════════════════════════════════════"
541
+ ifeq ($(FORCE_DOWNLOAD),0)
542
+ ifdef WINDOWS_NATIVE
543
+ $(Q)if exist "$(subst /,\,$(PLATFORM_DIR)/$(LIB_NAME))" ( \
544
+ echo "Library already exists: $(PLATFORM_DIR)/$(LIB_NAME)" && \
545
+ echo "Use FORCE_DOWNLOAD=1 to re-download" && \
546
+ exit 0 \
547
+ )
548
+ else
549
+ $(Q)if [ -f "$(PLATFORM_DIR)/$(LIB_NAME)" ]; then \
550
+ echo "Library already exists: $(PLATFORM_DIR)/$(LIB_NAME)"; \
551
+ echo "Use FORCE_DOWNLOAD=1 to re-download"; \
552
+ exit 0; \
553
+ fi
554
+ endif
555
+ endif
556
+ $(Q)echo "URL: $(UPLINK_C_RELEASE_URL)/$(UPLINK_C_VERSION)/$(UPLINK_C_ARCHIVE)"
557
+ $(Q)curl $(CURL_QUIET) -L -f \
558
+ "$(UPLINK_C_RELEASE_URL)/$(UPLINK_C_VERSION)/$(UPLINK_C_ARCHIVE)" \
559
+ -o "$(DOWNLOAD_DIR)/$(UPLINK_C_ARCHIVE)" || \
560
+ (echo "ERROR: Download failed. Prebuilt may not be available for $(PLATFORM)" && \
561
+ echo "Try: make install-source" && exit 1)
562
+ $(Q)echo "Extracting to $(PLATFORM_DIR)..."
563
+ $(Q)tar -xzf "$(DOWNLOAD_DIR)/$(UPLINK_C_ARCHIVE)" -C "$(PLATFORM_DIR)"
564
+ $(Q)rm -f "$(DOWNLOAD_DIR)/$(UPLINK_C_ARCHIVE)"
565
+ $(Q)echo "✓ Downloaded $(LIB_NAME)"
566
+
567
+ # Download prebuilt Node addon from GitHub releases
568
+ .PHONY: download-addon
569
+ download-addon: $(PLATFORM_DIR) $(DOWNLOAD_DIR) check-curl
570
+ $(Q)echo "══════════════════════════════════════════════════════════════"
571
+ $(Q)echo " Downloading Node addon v$(ADDON_VERSION) for $(PLATFORM)"
572
+ $(Q)echo "══════════════════════════════════════════════════════════════"
573
+ ifeq ($(FORCE_DOWNLOAD),0)
574
+ ifdef WINDOWS_NATIVE
575
+ $(Q)if exist "$(subst /,\,$(PLATFORM_DIR)/$(NODE_ADDON))" ( \
576
+ echo "Addon already exists: $(PLATFORM_DIR)/$(NODE_ADDON)" && \
577
+ echo "Use FORCE_DOWNLOAD=1 to re-download" && \
578
+ exit 0 \
579
+ )
580
+ else
581
+ $(Q)if [ -f "$(PLATFORM_DIR)/$(NODE_ADDON)" ]; then \
582
+ echo "Addon already exists: $(PLATFORM_DIR)/$(NODE_ADDON)"; \
583
+ echo "Use FORCE_DOWNLOAD=1 to re-download"; \
584
+ exit 0; \
585
+ fi
586
+ endif
587
+ endif
588
+ $(Q)echo "URL: $(ADDON_RELEASE_URL)/v$(ADDON_VERSION)/$(ADDON_ARCHIVE)"
589
+ $(Q)curl $(CURL_QUIET) -L -f \
590
+ "$(ADDON_RELEASE_URL)/v$(ADDON_VERSION)/$(ADDON_ARCHIVE)" \
591
+ -o "$(DOWNLOAD_DIR)/$(ADDON_ARCHIVE)" || \
592
+ (echo "ERROR: Download failed. Prebuilt may not be available for $(PLATFORM)" && \
593
+ echo "Try: make install-hybrid" && exit 1)
594
+ $(Q)echo "Extracting to $(PLATFORM_DIR)..."
595
+ $(Q)tar -xzf "$(DOWNLOAD_DIR)/$(ADDON_ARCHIVE)" -C "$(PLATFORM_DIR)"
596
+ $(Q)rm -f "$(DOWNLOAD_DIR)/$(ADDON_ARCHIVE)"
597
+ $(Q)echo "✓ Downloaded $(NODE_ADDON)"
598
+
599
+ # ------------------------------------------------------------------------------
600
+ # Clone uplink-c from GitHub
601
+ # ------------------------------------------------------------------------------
602
+
603
+ .PHONY: clone-uplink
604
+ clone-uplink: check-git
605
+ $(Q)echo "══════════════════════════════════════════════════════════════"
606
+ $(Q)echo " Cloning uplink-c $(UPLINK_C_VERSION)"
607
+ $(Q)echo "══════════════════════════════════════════════════════════════"
608
+ ifdef WINDOWS_NATIVE
609
+ $(Q)if exist "$(subst /,\,$(UPLINK_C_BUILD_DIR))" ( \
610
+ echo "uplink-c source exists at $(UPLINK_C_BUILD_DIR)" && \
611
+ cd "$(UPLINK_C_BUILD_DIR)" && git pull origin main 2>nul || echo "Using existing source" \
612
+ ) else ( \
613
+ echo "Cloning from https://github.com/storj/uplink-c.git..." && \
614
+ git clone --depth 1 https://github.com/storj/uplink-c.git "$(UPLINK_C_BUILD_DIR)" \
615
+ )
616
+ else
617
+ $(Q)if [ -d "$(UPLINK_C_BUILD_DIR)" ]; then \
618
+ echo "uplink-c source exists at $(UPLINK_C_BUILD_DIR)"; \
619
+ cd "$(UPLINK_C_BUILD_DIR)" && git pull origin main 2>/dev/null || echo "Using existing source"; \
620
+ else \
621
+ echo "Cloning from https://github.com/storj/uplink-c.git..."; \
622
+ git clone --depth 1 https://github.com/storj/uplink-c.git "$(UPLINK_C_BUILD_DIR)"; \
623
+ fi
624
+ endif
625
+ $(Q)echo "✓ uplink-c source ready at $(UPLINK_C_BUILD_DIR)"
626
+
627
+ # Build from cloned uplink-c source
628
+ .PHONY: build-uplink-cloned
629
+ build-uplink-cloned: clone-uplink $(PLATFORM_DIR) check-go
630
+ $(Q)echo "══════════════════════════════════════════════════════════════"
631
+ $(Q)echo " Building uplink-c for $(PLATFORM)"
632
+ $(Q)echo "══════════════════════════════════════════════════════════════"
633
+ $(Q)echo "Source: $(UPLINK_C_BUILD_DIR)"
634
+ $(Q)echo "Target: $(PLATFORM_DIR)/$(LIB_NAME)"
635
+ ifdef WINDOWS_NATIVE
636
+ $(Q)cd "$(UPLINK_C_BUILD_DIR)" && set CGO_ENABLED=1 && set GOOS=$(GO_OS) && set GOARCH=$(GO_ARCH) && go build -buildmode=c-shared -o $(LIB_NAME)
637
+ else
638
+ $(Q)cd "$(UPLINK_C_BUILD_DIR)" && CGO_ENABLED=1 GOOS=$(GO_OS) GOARCH=$(GO_ARCH) go build -buildmode=c-shared -o $(LIB_NAME)
639
+ endif
640
+ $(Q)$(call CP,$(UPLINK_C_BUILD_DIR)/$(LIB_NAME),$(PLATFORM_DIR)/$(LIB_NAME))
641
+ ifdef WINDOWS_NATIVE
642
+ $(Q)if exist "$(subst /,\,$(UPLINK_C_BUILD_DIR)/libuplink.h)" $(call CP,$(UPLINK_C_BUILD_DIR)/libuplink.h,$(INCLUDE_DIR)/uplink.h)
643
+ else
644
+ $(Q)if [ -f "$(UPLINK_C_BUILD_DIR)/libuplink.h" ]; then $(call CP,$(UPLINK_C_BUILD_DIR)/libuplink.h,$(INCLUDE_DIR)/uplink.h); fi
645
+ endif
646
+ $(Q)echo "✓ Built $(LIB_NAME)"
647
+ $(Q)ls -lh "$(PLATFORM_DIR)/$(LIB_NAME)" 2>/dev/null || dir "$(PLATFORM_DIR)\$(LIB_NAME)"
648
+ @$(MAKE) generate-import-lib
649
+
650
+ # Copy built addon to prebuilds
651
+ .PHONY: copy-addon-to-prebuilds
652
+ copy-addon-to-prebuilds: $(PLATFORM_DIR)
653
+ $(Q)echo "Copying addon to prebuilds..."
654
+ ifdef WINDOWS_NATIVE
655
+ $(Q)if exist "$(subst /,\,$(BUILD_DIR)/Release/uplink_native.node)" ( \
656
+ $(call CP,$(BUILD_DIR)/Release/uplink_native.node,$(PLATFORM_DIR)/$(NODE_ADDON)) && \
657
+ echo "✓ Copied $(NODE_ADDON) to $(PLATFORM_DIR)" \
658
+ ) else ( \
659
+ echo "ERROR: Addon not found at $(BUILD_DIR)/Release/uplink_native.node" && exit 1 \
660
+ )
661
+ else
662
+ $(Q)if [ -f "$(BUILD_DIR)/Release/uplink_native.node" ]; then \
663
+ $(call CP,$(BUILD_DIR)/Release/uplink_native.node,$(PLATFORM_DIR)/$(NODE_ADDON)); \
664
+ echo "✓ Copied $(NODE_ADDON) to $(PLATFORM_DIR)"; \
665
+ else \
666
+ echo "ERROR: Addon not found at $(BUILD_DIR)/Release/uplink_native.node"; \
667
+ exit 1; \
668
+ fi
669
+ endif
670
+
671
+ # ------------------------------------------------------------------------------
672
+ # Installation Options
673
+ # ------------------------------------------------------------------------------
674
+
675
+ # OPTION 1: Full Source Build
676
+ # Builds both uplink-c library and Node addon from source
677
+ # Requirements: Go, Git, C compiler, Python, Node.js
678
+ .PHONY: install-source
679
+ install-source:
680
+ $(Q)echo ""
681
+ $(Q)echo "╔══════════════════════════════════════════════════════════════╗"
682
+ $(Q)echo "║ OPTION 1: Full Source Build ║"
683
+ $(Q)echo "║ Building uplink-c + Node addon from source ║"
684
+ $(Q)echo "╚══════════════════════════════════════════════════════════════╝"
685
+ $(Q)echo ""
686
+ $(Q)echo "Platform: $(PLATFORM)"
687
+ $(Q)echo "Output: $(PLATFORM_DIR)"
688
+ $(Q)echo ""
689
+ @$(MAKE) check-source-prereqs
690
+ $(Q)echo ""
691
+ $(Q)echo "[1/4] Preparing uplink-c source..."
692
+ ifdef WINDOWS_NATIVE
693
+ @if exist "$(subst /,\,$(UPLINK_C_DIR)/go.mod)" ( \
694
+ echo "Using existing uplink-c at $(UPLINK_C_DIR)" && \
695
+ $(MAKE) build-uplink \
696
+ ) else ( \
697
+ $(MAKE) build-uplink-cloned \
698
+ )
699
+ else
700
+ @if [ -f "$(UPLINK_C_DIR)/go.mod" ]; then \
701
+ echo "Using existing uplink-c at $(UPLINK_C_DIR)"; \
702
+ $(MAKE) build-uplink; \
703
+ else \
704
+ $(MAKE) build-uplink-cloned; \
705
+ fi
706
+ endif
707
+ $(Q)echo ""
708
+ $(Q)echo "[2/4] Building Node addon..."
709
+ @$(MAKE) build-native
710
+ $(Q)echo ""
711
+ $(Q)echo "[3/4] Copying addon to prebuilds..."
712
+ @$(MAKE) copy-addon-to-prebuilds
713
+ $(Q)echo ""
714
+ $(Q)echo "[4/4] Verifying installation..."
715
+ ifneq ($(SKIP_VERIFY),1)
716
+ @$(MAKE) verify-full
717
+ endif
718
+ $(Q)echo ""
719
+ $(Q)echo "╔══════════════════════════════════════════════════════════════╗"
720
+ $(Q)echo "║ ✓ Installation complete (Source Build) ║"
721
+ $(Q)echo "╚══════════════════════════════════════════════════════════════╝"
722
+ $(Q)echo ""
723
+
724
+ # OPTION 2: Hybrid Build (Default)
725
+ # Downloads prebuilt uplink-c library, builds Node addon locally
726
+ # Requirements: C compiler, Python, Node.js (NO Go needed)
727
+ .PHONY: install-hybrid
728
+ install-hybrid:
729
+ $(Q)echo ""
730
+ $(Q)echo "╔══════════════════════════════════════════════════════════════╗"
731
+ $(Q)echo "║ OPTION 2: Hybrid Build ║"
732
+ $(Q)echo "║ Download uplink-c library, build Node addon locally ║"
733
+ $(Q)echo "╚══════════════════════════════════════════════════════════════╝"
734
+ $(Q)echo ""
735
+ $(Q)echo "Platform: $(PLATFORM)"
736
+ $(Q)echo "Output: $(PLATFORM_DIR)"
737
+ $(Q)echo ""
738
+ @$(MAKE) check-hybrid-prereqs
739
+ $(Q)echo ""
740
+ $(Q)echo "[1/3] Downloading uplink-c library..."
741
+ @$(MAKE) download-lib
742
+ $(Q)echo ""
743
+ $(Q)echo "[2/3] Building Node addon..."
744
+ @$(MAKE) build-native
745
+ @$(MAKE) copy-addon-to-prebuilds
746
+ $(Q)echo ""
747
+ $(Q)echo "[3/3] Verifying installation..."
748
+ ifneq ($(SKIP_VERIFY),1)
749
+ @$(MAKE) verify-full
750
+ endif
751
+ $(Q)echo ""
752
+ $(Q)echo "╔══════════════════════════════════════════════════════════════╗"
753
+ $(Q)echo "║ ✓ Installation complete (Hybrid Build) ║"
754
+ $(Q)echo "╚══════════════════════════════════════════════════════════════╝"
755
+ $(Q)echo ""
756
+
757
+ # OPTION 3: Full Prebuilt
758
+ # Downloads both prebuilt uplink-c library AND Node addon
759
+ # Requirements: Node.js only (NO compilation)
760
+ .PHONY: install-prebuilt
761
+ install-prebuilt:
762
+ $(Q)echo ""
763
+ $(Q)echo "╔══════════════════════════════════════════════════════════════╗"
764
+ $(Q)echo "║ OPTION 3: Full Prebuilt ║"
765
+ $(Q)echo "║ Download everything - no compilation required ║"
766
+ $(Q)echo "╚══════════════════════════════════════════════════════════════╝"
767
+ $(Q)echo ""
768
+ $(Q)echo "Platform: $(PLATFORM)"
769
+ $(Q)echo "Output: $(PLATFORM_DIR)"
770
+ $(Q)echo ""
771
+ @$(MAKE) check-prebuilt-prereqs
772
+ $(Q)echo ""
773
+ $(Q)echo "[1/3] Downloading uplink-c library..."
774
+ @$(MAKE) download-lib
775
+ $(Q)echo ""
776
+ $(Q)echo "[2/3] Downloading Node addon..."
777
+ @$(MAKE) download-addon
778
+ $(Q)echo ""
779
+ $(Q)echo "[3/3] Verifying installation..."
780
+ ifneq ($(SKIP_VERIFY),1)
781
+ @$(MAKE) verify-full
782
+ endif
783
+ $(Q)echo ""
784
+ $(Q)echo "╔══════════════════════════════════════════════════════════════╗"
785
+ $(Q)echo "║ ✓ Installation complete (Prebuilt - No compilation!) ║"
786
+ $(Q)echo "╚══════════════════════════════════════════════════════════════╝"
787
+ $(Q)echo ""
788
+
789
+ # Default install - auto-detect best method
790
+ .PHONY: install-auto
791
+ install-auto:
792
+ $(Q)echo ""
793
+ $(Q)echo "╔══════════════════════════════════════════════════════════════╗"
794
+ $(Q)echo "║ Auto-detecting best installation method... ║"
795
+ $(Q)echo "╚══════════════════════════════════════════════════════════════╝"
796
+ $(Q)echo ""
797
+ @$(MAKE) install-hybrid || $(MAKE) install-source
798
+
799
+ # ------------------------------------------------------------------------------
800
+ # Verification
801
+ # ------------------------------------------------------------------------------
802
+
803
+ .PHONY: verify-full
804
+ verify-full:
805
+ $(Q)echo "Verifying installation..."
806
+ $(Q)echo ""
807
+ $(Q)echo "Files in $(PLATFORM_DIR):"
808
+ ifdef WINDOWS_NATIVE
809
+ $(Q)dir "$(subst /,\,$(PLATFORM_DIR))" 2>nul || echo " (directory not found)"
810
+ else
811
+ $(Q)ls -lh "$(PLATFORM_DIR)" 2>/dev/null || echo " (directory not found)"
812
+ endif
813
+ $(Q)echo ""
814
+ @# Check library
815
+ ifdef WINDOWS_NATIVE
816
+ $(Q)if exist "$(subst /,\,$(PLATFORM_DIR)/$(LIB_NAME))" ( \
817
+ echo "✓ $(LIB_NAME)" \
818
+ ) else ( \
819
+ echo "✗ $(LIB_NAME) - NOT FOUND" && exit 1 \
820
+ )
821
+ $(Q)if exist "$(subst /,\,$(PLATFORM_DIR)/$(NODE_ADDON))" ( \
822
+ echo "✓ $(NODE_ADDON)" \
823
+ ) else ( \
824
+ echo "✗ $(NODE_ADDON) - NOT FOUND" && exit 1 \
825
+ )
826
+ else
827
+ $(Q)if [ -f "$(PLATFORM_DIR)/$(LIB_NAME)" ]; then \
828
+ echo "✓ $(LIB_NAME) - $$(ls -lh $(PLATFORM_DIR)/$(LIB_NAME) | awk '{print $$5}')"; \
829
+ else \
830
+ echo "✗ $(LIB_NAME) - NOT FOUND" && exit 1; \
831
+ fi
832
+ $(Q)if [ -f "$(PLATFORM_DIR)/$(NODE_ADDON)" ]; then \
833
+ echo "✓ $(NODE_ADDON) - $$(ls -lh $(PLATFORM_DIR)/$(NODE_ADDON) | awk '{print $$5}')"; \
834
+ else \
835
+ echo "✗ $(NODE_ADDON) - NOT FOUND" && exit 1; \
836
+ fi
837
+ endif
838
+ $(Q)echo ""
839
+ $(Q)echo "Verification passed!"
840
+
841
+ # ------------------------------------------------------------------------------
842
+ # Clean Targets
843
+ # ------------------------------------------------------------------------------
844
+
845
+ .PHONY: clean-downloads
846
+ clean-downloads:
847
+ $(Q)echo "Cleaning downloads..."
848
+ $(call RMDIR,$(DOWNLOAD_DIR))
849
+ $(Q)echo "✓ Downloads cleaned"
850
+
851
+ .PHONY: clean-prebuilds
852
+ clean-prebuilds:
853
+ $(Q)echo "Cleaning prebuilds for $(PLATFORM)..."
854
+ $(call RMDIR,$(PLATFORM_DIR))
855
+ $(Q)echo "✓ Prebuilds cleaned"
856
+
857
+ .PHONY: clean-clone
858
+ clean-clone:
859
+ $(Q)echo "Cleaning cloned uplink-c..."
860
+ $(call RMDIR,$(UPLINK_C_BUILD_DIR))
861
+ $(Q)echo "✓ Cloned source cleaned"
862
+
863
+ .PHONY: clean-all-dist
864
+ clean-all-dist: clean clean-downloads clean-prebuilds clean-clone
865
+ $(Q)echo "✓ All distribution artifacts cleaned"
866
+
867
+ # ------------------------------------------------------------------------------
868
+ # Help (Updated)
869
+ # ------------------------------------------------------------------------------
870
+
871
+ .PHONY: help
872
+ help:
873
+ @echo ""
874
+ @echo "╔══════════════════════════════════════════════════════════════════╗"
875
+ @echo "║ uplink-nodejs Makefile ║"
876
+ @echo "╚══════════════════════════════════════════════════════════════════╝"
877
+ @echo ""
878
+ @echo " Platform: $(PLATFORM)"
879
+ @echo " Library: $(LIB_NAME)"
880
+ @echo ""
881
+ @echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
882
+ @echo " INSTALLATION OPTIONS"
883
+ @echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
884
+ @echo ""
885
+ @echo " make install-auto Auto-detect best method (hybrid → source)"
886
+ @echo " make install-source Build everything from source (needs Go)"
887
+ @echo " make install-hybrid Download lib, build addon (needs compiler)"
888
+ @echo " make install-prebuilt Download everything (Node.js only)"
889
+ @echo ""
890
+ @echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
891
+ @echo " BUILD TARGETS"
892
+ @echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
893
+ @echo ""
894
+ @echo " make build Build TypeScript + native addon"
895
+ @echo " make build-ts Build TypeScript only"
896
+ @echo " make build-native Build native addon only (node-gyp)"
897
+ @echo " make build-uplink Build uplink-c from ../uplink-c"
898
+ @echo " make clone-uplink Clone uplink-c from GitHub"
899
+ @echo ""
900
+ @echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
901
+ @echo " DOWNLOAD TARGETS"
902
+ @echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
903
+ @echo ""
904
+ @echo " make download-lib Download prebuilt uplink-c library"
905
+ @echo " make download-addon Download prebuilt Node addon"
906
+ @echo ""
907
+ @echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
908
+ @echo " TEST & VERIFY"
909
+ @echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
910
+ @echo ""
911
+ @echo " make test Run all tests"
912
+ @echo " make verify Verify uplink-c library"
913
+ @echo " make verify-full Verify library + addon"
914
+ @echo " make check Check all prerequisites"
915
+ @echo ""
916
+ @echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
917
+ @echo " CLEAN"
918
+ @echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
919
+ @echo ""
920
+ @echo " make clean Clean build artifacts"
921
+ @echo " make clean-downloads Clean downloaded files"
922
+ @echo " make clean-prebuilds Clean prebuilt binaries"
923
+ @echo " make clean-all Clean everything"
924
+ @echo ""
925
+ @echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
926
+ @echo " VARIABLES"
927
+ @echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
928
+ @echo ""
929
+ @echo " UPLINK_C_DIR Path to uplink-c source (default: ../uplink-c)"
930
+ @echo " UPLINK_C_VERSION Version to download/clone (default: $(UPLINK_C_VERSION))"
931
+ @echo " GITHUB_OWNER GitHub owner for prebuilt downloads (default: $(GITHUB_OWNER))"
932
+ @echo " GITHUB_REPO GitHub repo for prebuilt downloads (default: $(GITHUB_REPO))"
933
+ @echo " PLATFORM Target platform (default: $(PLATFORM))"
934
+ @echo " FORCE_DOWNLOAD=1 Force re-download even if exists"
935
+ @echo " VERBOSE=1 Enable verbose output"
936
+ @echo ""
937
+ @echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
938
+ @echo " EXAMPLES"
939
+ @echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
940
+ @echo ""
941
+ @echo " make install-prebuilt # Fastest, no compiler"
942
+ @echo " make install-hybrid VERBOSE=1 # With detailed output"
943
+ @echo " make install-source UPLINK_C_DIR=~/uplink-c"
944
+ @echo " make download-lib UPLINK_C_VERSION=v1.13.0"
945
+ @echo ""