cocoapods-lynx-library 4.0.1 → 4.0.2.pre.alpha.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.
- checksums.yaml +4 -4
- data/lib/lynx/library/autolink.rb +173 -6
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6be5d0eb274376666a18c12b050b7fe962b50363d1a09d64c797002443ed3764
|
|
4
|
+
data.tar.gz: f6efdd409ec96cd26028ee64e710ba0a9ace426c055d1d0c441a4603afb9d5fa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 770228d8fdf4bf28bb606e29bd9e0d5b36d57417852eebd4861b97fabbec8202329709384e71d1c8da0609364bb05b74b0506c2539ba2730a4527979b61065dd
|
|
7
|
+
data.tar.gz: 15b13513e55f83aa3032c204a53d2651bcd2ae8ef2e38a7d9d959066d1e444487a4566867ad79cba6efedb106ff9e607b0c3e0ca8ecc7ec8a942d3ffd75adf72
|
|
@@ -7,20 +7,29 @@ require 'json'
|
|
|
7
7
|
|
|
8
8
|
module Lynx
|
|
9
9
|
module Library
|
|
10
|
-
LibraryInfo = Struct.new(
|
|
10
|
+
LibraryInfo = Struct.new(
|
|
11
|
+
:npm_name, :package_dir, :manifest_file, :source_dir, :podspec_path, :node_api_addons)
|
|
11
12
|
ComponentInfo = Struct.new(:kind, :name, :class_name)
|
|
13
|
+
NodeApiAddonInfo = Struct.new(
|
|
14
|
+
:name, :pod_name, :podspec_path, :addon_use_header, :required)
|
|
12
15
|
|
|
13
16
|
class Autolink
|
|
14
17
|
REGISTRY_CLASS_NAME = 'LynxGeneratedLibraryRegistry'
|
|
18
|
+
ADDON_USE_SOURCE_NAME = 'LynxGeneratedNodeAPIAddonUse.mm'
|
|
19
|
+
ADDON_NAME_PATTERN = /\A[A-Za-z_][A-Za-z0-9_]*\z/
|
|
15
20
|
|
|
16
21
|
class << self
|
|
17
22
|
def install!(podfile, options = {})
|
|
18
23
|
start_dir = File.expand_path(options[:root] || Dir.pwd)
|
|
19
24
|
output_dir = File.expand_path(options[:output_dir] || 'generated/lynx-library', start_dir)
|
|
20
25
|
libraries = scan(start_dir)
|
|
26
|
+
added_pods = []
|
|
21
27
|
libraries.each do |library|
|
|
22
28
|
pod_name = pod_name_from_podspec(library.podspec_path)
|
|
23
|
-
podfile
|
|
29
|
+
add_pod_once(podfile, added_pods, pod_name, File.dirname(library.podspec_path))
|
|
30
|
+
library.node_api_addons.each do |addon|
|
|
31
|
+
add_pod_once(podfile, added_pods, addon.pod_name, File.dirname(addon.podspec_path))
|
|
32
|
+
end
|
|
24
33
|
end
|
|
25
34
|
generate_registry(output_dir, libraries)
|
|
26
35
|
podfile.pod 'LynxLibraryRegistry', :path => output_dir
|
|
@@ -36,10 +45,13 @@ module Lynx
|
|
|
36
45
|
def generate_registry(output_dir, libraries)
|
|
37
46
|
FileUtils.mkdir_p(output_dir)
|
|
38
47
|
components = libraries.flat_map { |library| scan_components(library.source_dir) }
|
|
48
|
+
node_api_addons = libraries.flat_map(&:node_api_addons)
|
|
39
49
|
File.write(File.join(output_dir, "#{REGISTRY_CLASS_NAME}.h"), header_source)
|
|
40
50
|
File.write(File.join(output_dir, "#{REGISTRY_CLASS_NAME}.m"),
|
|
41
51
|
implementation_source(components))
|
|
42
|
-
File.write(File.join(output_dir,
|
|
52
|
+
File.write(File.join(output_dir, ADDON_USE_SOURCE_NAME), addon_use_source(node_api_addons))
|
|
53
|
+
File.write(File.join(output_dir, 'LynxLibraryRegistry.podspec'),
|
|
54
|
+
podspec_source(node_api_addons))
|
|
43
55
|
components
|
|
44
56
|
end
|
|
45
57
|
|
|
@@ -106,14 +118,79 @@ module Lynx
|
|
|
106
118
|
raise "No iOS podspec found for #{manifest_file}" unless
|
|
107
119
|
podspec_path && File.file?(podspec_path)
|
|
108
120
|
|
|
121
|
+
node_api_addons = parse_node_api_addons(ios['nodeApiAddons'], package_realpath,
|
|
122
|
+
podspec_path, manifest_file)
|
|
123
|
+
|
|
109
124
|
npm_name = File.basename(package_dir)
|
|
110
125
|
parent_name = File.basename(File.dirname(package_dir))
|
|
111
126
|
npm_name = "#{parent_name}/#{npm_name}" if parent_name.start_with?('@')
|
|
112
|
-
LibraryInfo.new(npm_name, package_dir, manifest_file, source_dir, podspec_path
|
|
127
|
+
LibraryInfo.new(npm_name, package_dir, manifest_file, source_dir, podspec_path,
|
|
128
|
+
node_api_addons)
|
|
113
129
|
rescue JSON::ParserError => e
|
|
114
130
|
raise "Failed to parse #{manifest_file}: #{e.message}"
|
|
115
131
|
end
|
|
116
132
|
|
|
133
|
+
def add_pod_once(podfile, added_pods, pod_name, pod_path)
|
|
134
|
+
key = [pod_name, pod_path]
|
|
135
|
+
return if added_pods.include?(key)
|
|
136
|
+
|
|
137
|
+
podfile.pod pod_name, :path => pod_path
|
|
138
|
+
added_pods << key
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def parse_node_api_addons(addons, package_realpath, default_podspec_path, manifest_file)
|
|
142
|
+
return [] if addons.nil?
|
|
143
|
+
raise "platforms.ios.nodeApiAddons in #{manifest_file} must be an array" unless
|
|
144
|
+
addons.is_a?(Array)
|
|
145
|
+
|
|
146
|
+
addons.each_with_index.map do |addon, index|
|
|
147
|
+
raise "platforms.ios.nodeApiAddons[#{index}] in #{manifest_file} must be an object" unless
|
|
148
|
+
addon.is_a?(Hash)
|
|
149
|
+
|
|
150
|
+
name = addon['name']
|
|
151
|
+
validate_addon_name(name, "platforms.ios.nodeApiAddons[#{index}].name", manifest_file)
|
|
152
|
+
addon_podspec_path = if addon['podspecPath']
|
|
153
|
+
resolve_package_path(package_realpath, addon['podspecPath'],
|
|
154
|
+
manifest_file,
|
|
155
|
+
"nodeApiAddons[#{index}].podspecPath")
|
|
156
|
+
else
|
|
157
|
+
default_podspec_path
|
|
158
|
+
end
|
|
159
|
+
raise "No iOS Node-API addon podspec found for #{manifest_file}" unless
|
|
160
|
+
addon_podspec_path && File.file?(addon_podspec_path)
|
|
161
|
+
|
|
162
|
+
pod_name = addon['podName'] || pod_name_from_podspec(addon_podspec_path)
|
|
163
|
+
addon_use_header = addon['addonUseHeader'] || 'addon_use.h'
|
|
164
|
+
validate_addon_use_header(addon_use_header,
|
|
165
|
+
"platforms.ios.nodeApiAddons[#{index}].addonUseHeader",
|
|
166
|
+
manifest_file)
|
|
167
|
+
required = addon.key?('required') ? !!addon['required'] : true
|
|
168
|
+
NodeApiAddonInfo.new(name.strip, pod_name, addon_podspec_path, addon_use_header,
|
|
169
|
+
required)
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def validate_addon_name(name, field_name, manifest_file)
|
|
174
|
+
raise "Missing #{field_name} in #{manifest_file}" if name.nil? || name.strip.empty?
|
|
175
|
+
|
|
176
|
+
normalized = name.strip
|
|
177
|
+
return if normalized.length <= 128 && !normalized.include?('..') &&
|
|
178
|
+
normalized.match?(ADDON_NAME_PATTERN)
|
|
179
|
+
|
|
180
|
+
raise "Invalid #{field_name} '#{name}' in #{manifest_file}; " \
|
|
181
|
+
'expected a C identifier matching [A-Za-z_][A-Za-z0-9_]*'
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def validate_addon_use_header(header, field_name, manifest_file)
|
|
185
|
+
raise "Missing #{field_name} in #{manifest_file}" if header.nil? || header.strip.empty?
|
|
186
|
+
|
|
187
|
+
normalized = header.strip
|
|
188
|
+
return if !normalized.start_with?('/') && !normalized.include?('..') &&
|
|
189
|
+
normalized.match?(/\A[A-Za-z0-9_\.\/-]+\z/)
|
|
190
|
+
|
|
191
|
+
raise "Invalid #{field_name} '#{header}' in #{manifest_file}"
|
|
192
|
+
end
|
|
193
|
+
|
|
117
194
|
def pod_name_from_podspec(podspec_path)
|
|
118
195
|
content = File.read(podspec_path)
|
|
119
196
|
match = content.match(/\.name\s*=\s*['"]([^'"]+)['"]/)
|
|
@@ -223,8 +300,11 @@ module Lynx
|
|
|
223
300
|
#import "#{REGISTRY_CLASS_NAME}.h"
|
|
224
301
|
#import <Lynx/LynxConfig.h>
|
|
225
302
|
|
|
303
|
+
extern void LynxGeneratedNodeAPIAddonUse(void);
|
|
304
|
+
|
|
226
305
|
@implementation #{REGISTRY_CLASS_NAME}
|
|
227
306
|
- (void)setup:(LynxConfig *)config {
|
|
307
|
+
LynxGeneratedNodeAPIAddonUse();
|
|
228
308
|
if (config == nil) {
|
|
229
309
|
return;
|
|
230
310
|
}
|
|
@@ -234,7 +314,91 @@ module Lynx
|
|
|
234
314
|
IMPL
|
|
235
315
|
end
|
|
236
316
|
|
|
237
|
-
def
|
|
317
|
+
def addon_use_source(node_api_addons)
|
|
318
|
+
includes = node_api_addons.uniq { |addon| [addon.pod_name, addon.addon_use_header] }
|
|
319
|
+
.map do |addon|
|
|
320
|
+
header = "#{addon.pod_name}/#{addon.addon_use_header}"
|
|
321
|
+
<<~INCLUDE.chomp
|
|
322
|
+
#if __has_include(<#{header}>)
|
|
323
|
+
#include <#{header}>
|
|
324
|
+
#endif
|
|
325
|
+
INCLUDE
|
|
326
|
+
end.join("\n\n")
|
|
327
|
+
addon_register_declarations = node_api_addons.map(&:name).uniq.map do |name|
|
|
328
|
+
"extern void _napi_register_xx_#{name}(void);"
|
|
329
|
+
end.join("\n")
|
|
330
|
+
addon_register_calls = node_api_addons.map(&:name).uniq.map do |name|
|
|
331
|
+
" _napi_register_xx_#{name}();"
|
|
332
|
+
end.join("\n")
|
|
333
|
+
bridge_setup = if node_api_addons.empty?
|
|
334
|
+
''
|
|
335
|
+
else
|
|
336
|
+
<<~SETUP.chomp
|
|
337
|
+
#include <mutex>
|
|
338
|
+
#include <LynxWeakNodeAPI/primjs_weak_node_api_installer.h>
|
|
339
|
+
#include <PrimJS/primjs_weak_node_api_provider.h>
|
|
340
|
+
|
|
341
|
+
namespace {
|
|
342
|
+
extern "C" {
|
|
343
|
+
#{addon_register_declarations}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
void LynxSetupWeakNodeAPI() {
|
|
347
|
+
static std::once_flag once;
|
|
348
|
+
std::call_once(once, []() {
|
|
349
|
+
PrimJSInstallWeakNodeApiRawPtrHostProvider(
|
|
350
|
+
PrimJSGetWeakNodeApiRawPtrHost);
|
|
351
|
+
SetupWeakNodeApiEnv();
|
|
352
|
+
#{addon_register_calls}
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
} // namespace
|
|
356
|
+
SETUP
|
|
357
|
+
end
|
|
358
|
+
setup_call = node_api_addons.empty? ? '' : ' LynxSetupWeakNodeAPI();'
|
|
359
|
+
|
|
360
|
+
<<~SOURCE
|
|
361
|
+
// Generated by cocoapods-lynx-library. Do not edit.
|
|
362
|
+
#{bridge_setup}
|
|
363
|
+
|
|
364
|
+
#{includes}
|
|
365
|
+
|
|
366
|
+
#ifdef __cplusplus
|
|
367
|
+
extern "C" {
|
|
368
|
+
#endif
|
|
369
|
+
void LynxGeneratedNodeAPIAddonUse(void) {
|
|
370
|
+
#{setup_call}
|
|
371
|
+
}
|
|
372
|
+
#ifdef __cplusplus
|
|
373
|
+
}
|
|
374
|
+
#endif
|
|
375
|
+
SOURCE
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
def podspec_source(node_api_addons = [])
|
|
379
|
+
addon_pod_names = node_api_addons.map(&:pod_name).uniq
|
|
380
|
+
addon_dependencies = addon_pod_names.map { |pod_name| " s.dependency '#{pod_name}'" }
|
|
381
|
+
.join("\n")
|
|
382
|
+
node_api_dependencies = if node_api_addons.empty?
|
|
383
|
+
[]
|
|
384
|
+
else
|
|
385
|
+
[
|
|
386
|
+
'LynxWeakNodeAPI/primjs_bridge',
|
|
387
|
+
'PrimJS/napi/adapter'
|
|
388
|
+
]
|
|
389
|
+
end
|
|
390
|
+
node_api_dependency_lines = node_api_dependencies.map do |pod_name|
|
|
391
|
+
" s.dependency '#{pod_name}'"
|
|
392
|
+
end.join("\n")
|
|
393
|
+
node_api_xcconfig = if node_api_addons.empty?
|
|
394
|
+
''
|
|
395
|
+
else
|
|
396
|
+
[
|
|
397
|
+
' s.pod_target_xcconfig = {',
|
|
398
|
+
' \'HEADER_SEARCH_PATHS\' => \'$(inherited) "${PODS_ROOT}/LynxWeakNodeAPI/packages/weak-node-api/headers"\'',
|
|
399
|
+
' }'
|
|
400
|
+
].join("\n")
|
|
401
|
+
end
|
|
238
402
|
<<~PODSPEC
|
|
239
403
|
Pod::Spec.new do |s|
|
|
240
404
|
s.name = 'LynxLibraryRegistry'
|
|
@@ -244,8 +408,11 @@ module Lynx
|
|
|
244
408
|
s.license = 'Apache-2.0'
|
|
245
409
|
s.author = 'Lynx'
|
|
246
410
|
s.source = { :path => '.' }
|
|
247
|
-
s.source_files = '#{REGISTRY_CLASS_NAME}.{h,m}'
|
|
411
|
+
s.source_files = '#{REGISTRY_CLASS_NAME}.{h,m}', '#{ADDON_USE_SOURCE_NAME}'
|
|
248
412
|
s.dependency 'Lynx'
|
|
413
|
+
#{node_api_dependency_lines}
|
|
414
|
+
#{addon_dependencies}
|
|
415
|
+
#{node_api_xcconfig}
|
|
249
416
|
s.requires_arc = true
|
|
250
417
|
end
|
|
251
418
|
PODSPEC
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cocoapods-lynx-library
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.0.1
|
|
4
|
+
version: 4.0.2.pre.alpha.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Lynx Authors
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-08-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: cocoapods
|
|
@@ -48,9 +48,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
48
48
|
version: '0'
|
|
49
49
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
50
50
|
requirements:
|
|
51
|
-
- - "
|
|
51
|
+
- - ">"
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version:
|
|
53
|
+
version: 1.3.1
|
|
54
54
|
requirements: []
|
|
55
55
|
rubygems_version: 3.3.27
|
|
56
56
|
signing_key:
|