devcenter-parser 2.3.0 → 2.5.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/.github/dependabot.yml +11 -0
- data/.github/workflows/sync_component_metadata.yml +25 -0
- data/.gitignore +1 -0
- data/.heroku/components-inventory/devcenter-parser.json +32 -0
- data/CODEOWNERS +6 -0
- data/Gemfile.lock +8 -8
- data/README.md +1 -1
- data/devcenter-parser.gemspec +2 -2
- data/lib/devcenter-parser/github_parser.rb +5 -3
- data/lib/devcenter-parser/version.rb +1 -1
- data/lib/devcenter-parser.rb +6 -4
- data/test/devcenter-parser_test.rb +47 -3
- metadata +15 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c4c53f614ec9479adb0fb78be87cdd30515834c467d1451515ab13abe121f4ac
|
|
4
|
+
data.tar.gz: 055c8a01895dc7b4646feab0727e71506b3caa4a4b6a48ae61f8abf2bffdbd52
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 38d174aaf87c2b54b14b4b17ad9b4145a86b9eb276b1edcff4ab691aee8acb812adcf692c15365f6f6ca22997fb3807f016254c96191485bf780d3c6c62e3fe4
|
|
7
|
+
data.tar.gz: 6bf94117132dde0e04fa438cf1e0c9fb851ec89db9960b0ffb6db8e3dbd21d0d750cdb7713835c1c0df07657c23e2e1426d3facb892a5d7f10a60501f3cdd5a5
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# To get started with Dependabot version updates, you'll need to specify which
|
|
2
|
+
# package ecosystems to update and where the package manifests are located.
|
|
3
|
+
# Please see the documentation for all configuration options:
|
|
4
|
+
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
|
5
|
+
|
|
6
|
+
version: 2
|
|
7
|
+
updates:
|
|
8
|
+
- package-ecosystem: "bundler"
|
|
9
|
+
directory: "/"
|
|
10
|
+
schedule:
|
|
11
|
+
interval: "weekly"
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
name: "Send data to Components Inventory"
|
|
2
|
+
on:
|
|
3
|
+
workflow_dispatch:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- "main"
|
|
7
|
+
paths:
|
|
8
|
+
- ".heroku/components-inventory/*.json"
|
|
9
|
+
pull_request:
|
|
10
|
+
types:
|
|
11
|
+
- opened
|
|
12
|
+
- synchronize
|
|
13
|
+
paths:
|
|
14
|
+
- ".heroku/components-inventory/*.json"
|
|
15
|
+
jobs:
|
|
16
|
+
action:
|
|
17
|
+
runs-on: sfdc-hk-ubuntu-latest
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v3
|
|
20
|
+
- name: Send data to Components Inventory
|
|
21
|
+
uses: heroku/components-action@main
|
|
22
|
+
with:
|
|
23
|
+
COMPONENTS_GHA_APP_ID: ${{ secrets.COMPONENTS_GHA_APP_ID}}
|
|
24
|
+
COMPONENTS_GHA_APP_PRIVATE_KEY: ${{ secrets.COMPONENTS_GHA_APP_PRIVATE_KEY}}
|
|
25
|
+
COMPONENTS_GHA_JSON_TOKEN: ${{ secrets.COMPONENTS_GHA_JSON_TOKEN}}
|
data/.gitignore
CHANGED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"slug": "devcenter-parser",
|
|
3
|
+
"name": "DevCenter Parser",
|
|
4
|
+
"description": "Markdown parser used on Heroku Dev Center",
|
|
5
|
+
"language": "Ruby",
|
|
6
|
+
"lifecycle_status": "Production",
|
|
7
|
+
"pipeline_uuid": null,
|
|
8
|
+
"repository_url": "https://github.com/heroku/devcenter-parser",
|
|
9
|
+
"stack": "Platform",
|
|
10
|
+
"stack_type": "Service",
|
|
11
|
+
"documentation_url": "https://github.com/heroku/devcenter-parser",
|
|
12
|
+
"metrics_url": null,
|
|
13
|
+
"sox": false,
|
|
14
|
+
"soc2": false,
|
|
15
|
+
"customer_facing": false,
|
|
16
|
+
"pager_duty_service_code": null,
|
|
17
|
+
"component_tier": "4",
|
|
18
|
+
"github_actions": true,
|
|
19
|
+
"github_release": false,
|
|
20
|
+
"github_actions_ci_workflow": null,
|
|
21
|
+
"authentication": null,
|
|
22
|
+
"platform": null,
|
|
23
|
+
"team_name": "Marketing Web Ops",
|
|
24
|
+
"planned_maintenance_severity": null,
|
|
25
|
+
"gus_team": "https://gus.lightning.force.com/lightning/r/ADM_Scrum_Team__c/a00B000000Bbl1zIAB/view",
|
|
26
|
+
"pci_tier": "TBD",
|
|
27
|
+
"consumer_type": "N/A",
|
|
28
|
+
"content_cacheable": "N/A",
|
|
29
|
+
"blast_radius": "Internal",
|
|
30
|
+
"audit_findings_url": null,
|
|
31
|
+
"last_audit": null
|
|
32
|
+
}
|
data/CODEOWNERS
ADDED
data/Gemfile.lock
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
devcenter-parser (2.
|
|
5
|
-
nokogiri (
|
|
4
|
+
devcenter-parser (2.5.1)
|
|
5
|
+
nokogiri (~> 1.16)
|
|
6
6
|
redcarpet (= 3.6.0)
|
|
7
7
|
sanitize (~> 6.0.2)
|
|
8
8
|
|
|
@@ -10,13 +10,13 @@ GEM
|
|
|
10
10
|
remote: http://rubygems.org/
|
|
11
11
|
specs:
|
|
12
12
|
crass (1.0.6)
|
|
13
|
-
mini_portile2 (2.8.
|
|
13
|
+
mini_portile2 (2.8.5)
|
|
14
14
|
minitest (5.19.0)
|
|
15
|
-
nokogiri (1.
|
|
15
|
+
nokogiri (1.16.2)
|
|
16
16
|
mini_portile2 (~> 2.8.2)
|
|
17
17
|
racc (~> 1.4)
|
|
18
|
-
racc (1.7.
|
|
19
|
-
rake (13.0
|
|
18
|
+
racc (1.7.3)
|
|
19
|
+
rake (13.1.0)
|
|
20
20
|
redcarpet (3.6.0)
|
|
21
21
|
sanitize (6.0.2)
|
|
22
22
|
crass (~> 1.0.2)
|
|
@@ -28,7 +28,7 @@ PLATFORMS
|
|
|
28
28
|
DEPENDENCIES
|
|
29
29
|
devcenter-parser!
|
|
30
30
|
minitest (~> 5.19.0)
|
|
31
|
-
rake
|
|
31
|
+
rake (~> 13.1.0)
|
|
32
32
|
|
|
33
33
|
BUNDLED WITH
|
|
34
|
-
2.
|
|
34
|
+
2.5.6
|
data/README.md
CHANGED
data/devcenter-parser.gemspec
CHANGED
|
@@ -16,10 +16,10 @@ Gem::Specification.new do |gem|
|
|
|
16
16
|
|
|
17
17
|
gem.required_ruby_version = '>= 3.0.0'
|
|
18
18
|
|
|
19
|
-
gem.add_runtime_dependency 'nokogiri', '
|
|
19
|
+
gem.add_runtime_dependency 'nokogiri', '~> 1.16'
|
|
20
20
|
gem.add_runtime_dependency 'redcarpet', '3.6.0'
|
|
21
21
|
gem.add_runtime_dependency 'sanitize', '~> 6.0.2'
|
|
22
22
|
|
|
23
23
|
gem.add_development_dependency 'minitest', '~> 5.19.0'
|
|
24
|
-
gem.add_development_dependency 'rake'
|
|
24
|
+
gem.add_development_dependency 'rake', '~>13.1.0'
|
|
25
25
|
end
|
|
@@ -47,11 +47,13 @@ module GitHubParser
|
|
|
47
47
|
|
|
48
48
|
def self.special_blocks(doc)
|
|
49
49
|
doc.css('blockquote>p:first').each do |node|
|
|
50
|
-
if match = node.inner_html.match(/\A\W*(callout|warning|note)\W/)
|
|
50
|
+
if match = node.inner_html.match(/\A\W*(callout|warning|note)\W|\[\!(callout|warning|note)\]\W/i)
|
|
51
51
|
node.parent.name = 'div'
|
|
52
|
-
node.parent['class'] = match[1]
|
|
52
|
+
node.parent['class'] = match[1].downcase
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
# This expression is slightly different because we want to remove the newline (\n) in this swap, compared to the
|
|
55
|
+
# match above that doesn't care about the newline.
|
|
56
|
+
new_html = node.inner_html.gsub(/\A\s*(callout|warning|note)\s*|\[\!(callout|warning|note)\]\s*/i, '')
|
|
55
57
|
|
|
56
58
|
# Assigning inner_html directly causes encoding issues in old libxml versions,
|
|
57
59
|
# workaround from https://github.com/sparklemotion/nokogiri/issues/458#issuecomment-3136620
|
data/lib/devcenter-parser.rb
CHANGED
|
@@ -33,7 +33,7 @@ module DevcenterParser
|
|
|
33
33
|
convert_to_article_links_all_relative_links_with_missing_initial_slashes(doc, options)
|
|
34
34
|
html = doc.to_html(:encoding => 'utf-8')
|
|
35
35
|
verify_raw_html(html)
|
|
36
|
-
html
|
|
36
|
+
html
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def self.normalize_markdown(markdown)
|
|
@@ -71,12 +71,12 @@ module DevcenterParser
|
|
|
71
71
|
return @@sanitize_config if defined?(@@sanitize_config)
|
|
72
72
|
frozen_config = Sanitize::Config::RELAXED
|
|
73
73
|
config = Marshal.load(Marshal.dump(frozen_config))
|
|
74
|
-
config[:attributes][:all] += %w{ id class style name width height border align data-next-message data-step-title }
|
|
74
|
+
config[:attributes][:all] += %w{ id class style name width height border align data-next-message data-step-title data-uuid data-type data-v }
|
|
75
75
|
config[:attributes]['a'] += %w{ target }
|
|
76
76
|
config[:elements] += %w{ div span hr tt }
|
|
77
77
|
|
|
78
78
|
# embedded videos
|
|
79
|
-
config[:attributes][:all] += %w{ value src type allowscriptaccess allowfullscreen webkitallowfullscreen mozallowfullscreen frameborder }
|
|
79
|
+
config[:attributes][:all] += %w{ value src type allowscriptaccess allowfullscreen webkitallowfullscreen mozallowfullscreen frameborder allow }
|
|
80
80
|
config[:elements] += %w{ object param embed iframe }
|
|
81
81
|
config[:add_attributes] = {
|
|
82
82
|
'object' => {'allowscriptaccess' => 'never'},
|
|
@@ -121,9 +121,11 @@ module DevcenterParser
|
|
|
121
121
|
def self.sanitize_node_with_invalid_src
|
|
122
122
|
lambda do |env|
|
|
123
123
|
return unless env[:node].attributes['src']
|
|
124
|
+
# convert youtube.com to youtube-nocookies.com
|
|
125
|
+
env[:node].attributes['src'].value = env[:node].attributes['src'].value.sub('youtube.com', 'youtube-nocookie.com')
|
|
124
126
|
# disallow javascript in src for all attributes
|
|
125
127
|
env[:node].unlink if env[:node].attributes['src'].value =~ /\Ajavascript:/i
|
|
126
|
-
# allow iframes if they have src that is from vimeo
|
|
128
|
+
# allow iframes only if they have src that is from vimeo, YouTube (no-cookies version)
|
|
127
129
|
env[:node].unlink if iframe?(env[:node]) && iframe_has_invalid_src?(env[:node])
|
|
128
130
|
end
|
|
129
131
|
end
|
|
@@ -60,9 +60,15 @@ describe 'DevcenterParser' do
|
|
|
60
60
|
assert_parsing_result src, src
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
-
it '
|
|
64
|
-
src = '<iframe width="560" height="315" src="https://www.youtube.com/embed/123456ABCDEF" frameborder="0" allowfullscreen=""></iframe>'
|
|
65
|
-
assert_parsing_result src,
|
|
63
|
+
it 'allows embedding youtube videos from its no-cookies domain with allow attribute' do
|
|
64
|
+
src = '<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/123456ABCDEF" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen=""></iframe>'
|
|
65
|
+
assert_parsing_result src, src
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'converts youtube videos embedded from the with-cookies domain to the no-cookies domain' do
|
|
69
|
+
src = '<iframe width="560" height="315" src="https://www.youtube.com/embed/123456ABCDEF" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen=""></iframe>'
|
|
70
|
+
src_result = '<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/123456ABCDEF" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen=""></iframe>'
|
|
71
|
+
assert_parsing_result src, src_result
|
|
66
72
|
end
|
|
67
73
|
|
|
68
74
|
it 'does not allow embedding vimeo videos when their do-no-track param is set to something different than true' do
|
|
@@ -75,6 +81,11 @@ describe 'DevcenterParser' do
|
|
|
75
81
|
assert_parsing_result src, ''
|
|
76
82
|
end
|
|
77
83
|
|
|
84
|
+
it 'allows embedding vidyard videos with data attributes' do
|
|
85
|
+
src = '<p><img style="width: 100%; margin: auto; display: block;" class="vidyard-player-embed" src="https://play.vidyard.com/123456ABCDEFG.jpg" data-uuid="123456ABCDEFG" data-v="4" data-type="inline"></p>'
|
|
86
|
+
assert_parsing_result src, src
|
|
87
|
+
end
|
|
88
|
+
|
|
78
89
|
it 'allows images' do
|
|
79
90
|
src = '<p><img src="http://nav.heroku.com/images/logos/logo.png" alt="image"></p>'
|
|
80
91
|
assert_parsing_result src, src
|
|
@@ -408,6 +419,35 @@ HTML
|
|
|
408
419
|
assert_parsing_result md, html
|
|
409
420
|
end
|
|
410
421
|
|
|
422
|
+
it 'generates blockquotes for GitHub-style callouts in uppercase format' do
|
|
423
|
+
md = <<-MARKDOWN
|
|
424
|
+
> [!WARNING]
|
|
425
|
+
> This is a warning
|
|
426
|
+
MARKDOWN
|
|
427
|
+
|
|
428
|
+
expected = <<-HTML
|
|
429
|
+
<div class="warning">
|
|
430
|
+
<p>This is a warning</p>
|
|
431
|
+
</div>
|
|
432
|
+
HTML
|
|
433
|
+
|
|
434
|
+
assert_parsing_result md, expected
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
it 'generates blockquotes for GitHub-style callouts in lowercase format' do
|
|
438
|
+
md = <<-MARKDOWN
|
|
439
|
+
> [!warning]
|
|
440
|
+
> This is a warning
|
|
441
|
+
MARKDOWN
|
|
442
|
+
|
|
443
|
+
expected = <<-HTML
|
|
444
|
+
<div class="warning">
|
|
445
|
+
<p>This is a warning</p>
|
|
446
|
+
</div>
|
|
447
|
+
HTML
|
|
448
|
+
|
|
449
|
+
assert_parsing_result md, expected
|
|
450
|
+
end
|
|
411
451
|
|
|
412
452
|
it 'generates separate blockquotes from blockquotes separated by empty lines' do
|
|
413
453
|
md = <<-MARKDOWN
|
|
@@ -488,4 +528,8 @@ HTML
|
|
|
488
528
|
assert DevcenterParser.to_html(md).include?("<#{header} id=\"#{id}\">"), "GitHub does not generate a #{header} with id #{id}"
|
|
489
529
|
end
|
|
490
530
|
|
|
531
|
+
def assert_contains(md, contains)
|
|
532
|
+
assert DevcenterParser.to_html(md).include?(contains), "Failed when parsing #{md}\n.\n\nDid not contain: #{contains}\n\n"
|
|
533
|
+
end
|
|
534
|
+
|
|
491
535
|
end
|
metadata
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: devcenter-parser
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.5.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Heroku
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2024-03-15 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: nokogiri
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- - "
|
|
17
|
+
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: 1.
|
|
19
|
+
version: '1.16'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
|
-
- - "
|
|
24
|
+
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: 1.
|
|
26
|
+
version: '1.16'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: redcarpet
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -70,16 +70,16 @@ dependencies:
|
|
|
70
70
|
name: rake
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
72
72
|
requirements:
|
|
73
|
-
- - "
|
|
73
|
+
- - "~>"
|
|
74
74
|
- !ruby/object:Gem::Version
|
|
75
|
-
version:
|
|
75
|
+
version: 13.1.0
|
|
76
76
|
type: :development
|
|
77
77
|
prerelease: false
|
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
79
|
requirements:
|
|
80
|
-
- - "
|
|
80
|
+
- - "~>"
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
|
-
version:
|
|
82
|
+
version: 13.1.0
|
|
83
83
|
description: Parser for Heroku Dev Center's content
|
|
84
84
|
email:
|
|
85
85
|
- heroku-front-end@salesforce.com
|
|
@@ -87,7 +87,11 @@ executables: []
|
|
|
87
87
|
extensions: []
|
|
88
88
|
extra_rdoc_files: []
|
|
89
89
|
files:
|
|
90
|
+
- ".github/dependabot.yml"
|
|
91
|
+
- ".github/workflows/sync_component_metadata.yml"
|
|
90
92
|
- ".gitignore"
|
|
93
|
+
- ".heroku/components-inventory/devcenter-parser.json"
|
|
94
|
+
- CODEOWNERS
|
|
91
95
|
- Gemfile
|
|
92
96
|
- Gemfile.lock
|
|
93
97
|
- LICENSE
|
|
@@ -118,7 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
118
122
|
- !ruby/object:Gem::Version
|
|
119
123
|
version: '0'
|
|
120
124
|
requirements: []
|
|
121
|
-
rubygems_version: 3.
|
|
125
|
+
rubygems_version: 3.3.7
|
|
122
126
|
signing_key:
|
|
123
127
|
specification_version: 4
|
|
124
128
|
summary: Parser for Heroku Dev Center's content
|