lutaml-openapi 0.1.2 → 0.1.3
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/CHANGELOG.md +33 -0
- data/Rakefile +16 -1
- data/frontend/dist/app.iife.js +1 -23
- data/frontend/dist/style.css +2 -1
- data/frontend/package-lock.json +1186 -2641
- data/frontend/package.json +4 -3
- data/frontend/src/App.vue +25 -11
- data/frontend/src/__tests__/i18n.test.ts +102 -0
- data/frontend/src/components/OverviewView.vue +4 -3
- data/frontend/src/components/PathsView.vue +4 -3
- data/frontend/src/components/SchemasView.vue +6 -5
- data/frontend/src/i18n/index.ts +84 -0
- data/frontend/src/i18n/messages.ts +63 -0
- data/lib/lutaml/openapi/corpus_audit.rb +4 -3
- data/lib/lutaml/openapi/document.rb +13 -12
- data/lib/lutaml/openapi/oas30.rb +4 -34
- data/lib/lutaml/openapi/version.rb +1 -1
- data/lib/lutaml/openapi.rb +5 -5
- data/script/axe_audit +109 -0
- metadata +8 -4
data/script/axe_audit
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# axe-core accessibility audit of the generated SPA. Uses the axe-core
|
|
4
|
+
# copy vendored by the frontend's npm devDependencies (sovereign: no CDN
|
|
5
|
+
# fetch). Exits non-zero when violations are found; skips cleanly when
|
|
6
|
+
# no Chrome binary or no built frontend exists, so `rake` stays green on
|
|
7
|
+
# browser-less lanes (windows CI) while the browser-equipped lanes
|
|
8
|
+
# (ubuntu/macos) always run it.
|
|
9
|
+
|
|
10
|
+
require "json"
|
|
11
|
+
require "open3"
|
|
12
|
+
require "fileutils"
|
|
13
|
+
require "tmpdir"
|
|
14
|
+
require "lutaml/openapi"
|
|
15
|
+
|
|
16
|
+
CHROME_CANDIDATES = [
|
|
17
|
+
ENV.fetch("CHROME_BIN", nil),
|
|
18
|
+
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
|
19
|
+
"/usr/bin/chromium",
|
|
20
|
+
"/usr/bin/chromium-browser",
|
|
21
|
+
"/usr/bin/google-chrome",
|
|
22
|
+
].freeze
|
|
23
|
+
|
|
24
|
+
ROOT = File.expand_path("..", __dir__)
|
|
25
|
+
DOCUMENT = ARGV.first ||
|
|
26
|
+
File.join(ROOT, "spec", "fixtures", "ogcapi-features-1-oas31.yaml")
|
|
27
|
+
|
|
28
|
+
chrome = CHROME_CANDIDATES.find { |path| path && File.executable?(path) }
|
|
29
|
+
unless chrome
|
|
30
|
+
warn "axe audit: SKIP (no Chrome binary; set CHROME_BIN to enable)"
|
|
31
|
+
exit 0
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
dist = File.join(ROOT, "frontend", "dist")
|
|
35
|
+
unless File.exist?(File.join(dist, "app.iife.js"))
|
|
36
|
+
warn "axe audit: SKIP (frontend/dist missing; run `rake frontend:build`)"
|
|
37
|
+
exit 0
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
axe = File.join(ROOT, "frontend", "node_modules", "axe-core", "axe.min.js")
|
|
41
|
+
unless File.exist?(axe)
|
|
42
|
+
abort "axe audit: frontend/node_modules/axe-core missing; " \
|
|
43
|
+
"run `npm install` in frontend/"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
INJECT = <<~SCRIPT
|
|
47
|
+
<script src="file://#{axe}"></script>
|
|
48
|
+
<script>
|
|
49
|
+
window.addEventListener('load', () => setTimeout(() => {
|
|
50
|
+
axe.run().then((r) => {
|
|
51
|
+
document.body.setAttribute('data-axe', JSON.stringify({
|
|
52
|
+
violations: r.violations.map((v) => ({ id: v.id, impact: v.impact,
|
|
53
|
+
nodes: v.nodes.length,
|
|
54
|
+
targets: v.nodes.map((n) => n.target.join(' ')) })),
|
|
55
|
+
passes: r.passes.length,
|
|
56
|
+
}));
|
|
57
|
+
document.title = 'AXE-DONE';
|
|
58
|
+
}).catch((e) => {
|
|
59
|
+
document.body.setAttribute('data-axe', JSON.stringify({ error: String(e) }));
|
|
60
|
+
document.title = 'AXE-ERROR';
|
|
61
|
+
});
|
|
62
|
+
}, 4000));
|
|
63
|
+
</script>
|
|
64
|
+
SCRIPT
|
|
65
|
+
|
|
66
|
+
dir = Dir.mktmpdir("axe-audit")
|
|
67
|
+
document = Lutaml::Openapi.parse(File.read(DOCUMENT))
|
|
68
|
+
File.write(File.join(dir, "index.html"), Lutaml::Openapi::Spa.generate(document))
|
|
69
|
+
|
|
70
|
+
page = File.join(dir, "index.html")
|
|
71
|
+
File.write(File.join(dir, "audit.html"),
|
|
72
|
+
File.read(page).sub("</body>", "#{INJECT}\n</body>"))
|
|
73
|
+
|
|
74
|
+
# both locales gate: the default LTR render and the Arabic RTL render
|
|
75
|
+
# (the mirrored layout must stay accessible)
|
|
76
|
+
VARIANTS = [
|
|
77
|
+
{ label: "en", query: "" },
|
|
78
|
+
{ label: "ar (rtl)", query: "?locale=ar" },
|
|
79
|
+
].freeze
|
|
80
|
+
|
|
81
|
+
failed = false
|
|
82
|
+
|
|
83
|
+
VARIANTS.each do |variant|
|
|
84
|
+
dom, err, status = Open3.capture3(
|
|
85
|
+
chrome, "--headless=new", "--disable-gpu", "--virtual-time-budget=20000",
|
|
86
|
+
"--dump-dom", "file://#{File.join(dir, 'audit.html')}#{variant[:query]}"
|
|
87
|
+
)
|
|
88
|
+
abort "axe audit: Chrome failed: #{err[0, 400]}" unless status.success?
|
|
89
|
+
|
|
90
|
+
match = dom[/data-axe="([^"]*)"/, 1]
|
|
91
|
+
abort "axe audit (#{variant[:label]}): no result captured" unless match
|
|
92
|
+
|
|
93
|
+
result = JSON.parse(match.gsub(""", '"'))
|
|
94
|
+
abort "axe audit: axe failed: #{result['error']}" if result["error"]
|
|
95
|
+
|
|
96
|
+
if result["violations"].empty?
|
|
97
|
+
puts "axe audit (#{variant[:label]}): PASS (#{result['passes']} rule groups)"
|
|
98
|
+
else
|
|
99
|
+
failed = true
|
|
100
|
+
puts "axe audit (#{variant[:label]}): " \
|
|
101
|
+
"#{result['violations'].sum { |v| v['nodes'] }} violations"
|
|
102
|
+
result["violations"].each do |violation|
|
|
103
|
+
puts " [#{violation['impact']}] #{violation['id']} x#{violation['nodes']}"
|
|
104
|
+
violation["targets"].each { |target| puts " #{target}" }
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
exit 1 if failed
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lutaml-openapi
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-10-
|
|
11
|
+
date: 2026-10-31 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: json
|
|
@@ -58,14 +58,14 @@ dependencies:
|
|
|
58
58
|
requirements:
|
|
59
59
|
- - "~>"
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: 0.6.
|
|
61
|
+
version: 0.6.51
|
|
62
62
|
type: :runtime
|
|
63
63
|
prerelease: false
|
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
65
|
requirements:
|
|
66
66
|
- - "~>"
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: 0.6.
|
|
68
|
+
version: 0.6.51
|
|
69
69
|
description: Parse OpenAPI 3.0/3.1 documents into lossless LutaML model objects; the
|
|
70
70
|
model layer for model-based OpenAPI standards
|
|
71
71
|
email:
|
|
@@ -87,10 +87,13 @@ files:
|
|
|
87
87
|
- frontend/package-lock.json
|
|
88
88
|
- frontend/package.json
|
|
89
89
|
- frontend/src/App.vue
|
|
90
|
+
- frontend/src/__tests__/i18n.test.ts
|
|
90
91
|
- frontend/src/app.ts
|
|
91
92
|
- frontend/src/components/OverviewView.vue
|
|
92
93
|
- frontend/src/components/PathsView.vue
|
|
93
94
|
- frontend/src/components/SchemasView.vue
|
|
95
|
+
- frontend/src/i18n/index.ts
|
|
96
|
+
- frontend/src/i18n/messages.ts
|
|
94
97
|
- frontend/src/style.css
|
|
95
98
|
- frontend/tsconfig.json
|
|
96
99
|
- frontend/vite.config.ts
|
|
@@ -101,6 +104,7 @@ files:
|
|
|
101
104
|
- lib/lutaml/openapi/spa.rb
|
|
102
105
|
- lib/lutaml/openapi/version.rb
|
|
103
106
|
- rakelib/corpus.rake
|
|
107
|
+
- script/axe_audit
|
|
104
108
|
homepage: https://github.com/lutaml/lutaml-openapi
|
|
105
109
|
licenses:
|
|
106
110
|
- BSD-2-Clause
|