jekyll-tsc 0.0.2
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 +7 -0
- data/lib/jekyll/typescript/config.rb +35 -0
- data/lib/jekyll/typescript/converter.rb +25 -0
- data/lib/jekyll/typescript/generator.rb +35 -0
- data/lib/jekyll/typescript/manager.rb +160 -0
- data/lib/jekyll/typescript/tsconfig.rb +64 -0
- data/lib/jekyll/typescript/version.rb +7 -0
- data/lib/jekyll_tsc.rb +5 -0
- metadata +93 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3ea5560f47a48dbde778b57ec1f170b9c3570b3554e2babef0a19e581a0f34e3
|
4
|
+
data.tar.gz: 1a671aac61e08773b3e963451a0eb1f62e5bf6590dd3959f11049b72510780c5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 00e3916c10baad4f0a2704b6faad9ba93f6228b79f42bb0ea3ede0c4b10e0367a36188956b9e7151519eee97a9e4abda6e4f83966e51da5aea8b5261005ef2d3
|
7
|
+
data.tar.gz: bcda3a7c08938c2641505609183589ddb2f69ab5e471765d461725dcea0652b19ef1d175e0e443918f83e4346447c5734e7ebafd3ad29eff6126c1515843aa99
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jekyll
|
4
|
+
module Typescript
|
5
|
+
# module adding methods to access the config variables for this
|
6
|
+
# plugin from the users _config.yml.
|
7
|
+
#
|
8
|
+
# these methods are also expected to attach the default values for
|
9
|
+
# these options should they be unassigned.
|
10
|
+
#
|
11
|
+
module Config
|
12
|
+
def ts_extensions
|
13
|
+
@ts_extensions ||= Array(config['extensions']) || %w[.ts .tsx]
|
14
|
+
end
|
15
|
+
|
16
|
+
def copy_extensions
|
17
|
+
@copy_extensions ||= Array(config['copy_ext']) || []
|
18
|
+
end
|
19
|
+
|
20
|
+
def temp_dir
|
21
|
+
@temp_dir ||= config['temp_dir'] || '.typescript'
|
22
|
+
end
|
23
|
+
|
24
|
+
def tsc_command
|
25
|
+
@tsc_command ||= Array(config['command']) || ['tsc']
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def config
|
31
|
+
@config ||= site.config['typescript']
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jekyll
|
4
|
+
module Typescript
|
5
|
+
# This class just makes jekyll change the extensions of any typescript
|
6
|
+
# files to .js.
|
7
|
+
#
|
8
|
+
# To see where the actual conversion takes place, see ./manager.rb
|
9
|
+
class TypescriptConverter < Jekyll::Converter
|
10
|
+
priority :low
|
11
|
+
|
12
|
+
def matches(ext)
|
13
|
+
Manager.instance.typescript_ext?(ext)
|
14
|
+
end
|
15
|
+
|
16
|
+
def output_ext(_)
|
17
|
+
'.js'
|
18
|
+
end
|
19
|
+
|
20
|
+
def convert(content)
|
21
|
+
content
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jekyll
|
4
|
+
module Typescript
|
5
|
+
# Generator to ensure Manager is aware of any typescript (or related)
|
6
|
+
# files it may need to process. This in affect forces typescript files
|
7
|
+
# to be processed, even when they lack front matter.
|
8
|
+
#
|
9
|
+
class TypescriptGenerator < Jekyll::Generator
|
10
|
+
def generate(site)
|
11
|
+
@site = site
|
12
|
+
Manager.instance.site ||= site
|
13
|
+
Manager.instance.static_files.clear
|
14
|
+
|
15
|
+
ts_files = []
|
16
|
+
site.static_files.each do |file|
|
17
|
+
if Manager.instance.typescript_file?(file)
|
18
|
+
ts_files << file
|
19
|
+
elsif Manager.instance.copy_file?(file)
|
20
|
+
Manager.instance.static_files << file
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# turn any needed typescript files into regular pages.
|
25
|
+
site.static_files -= ts_files
|
26
|
+
site.pages += ts_files.map do |static_file|
|
27
|
+
base = static_file.instance_variable_get('@base')
|
28
|
+
dir = static_file.instance_variable_get('@dir')
|
29
|
+
name = static_file.instance_variable_get('@name')
|
30
|
+
Jekyll::Page.new(@site, base, dir, name)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'singleton'
|
4
|
+
require 'fileutils'
|
5
|
+
require 'shellwords'
|
6
|
+
require_relative './config'
|
7
|
+
require_relative './tsconfig'
|
8
|
+
|
9
|
+
module Jekyll
|
10
|
+
module Typescript
|
11
|
+
# manages typescript
|
12
|
+
class Manager
|
13
|
+
SyntaxError = Class.new(ArgumentError)
|
14
|
+
|
15
|
+
include ::Singleton
|
16
|
+
include Config
|
17
|
+
include TSConfig
|
18
|
+
|
19
|
+
# whether :ext is associated with a typescript extension.
|
20
|
+
#
|
21
|
+
def typescript_ext?(ext)
|
22
|
+
ts_extensions.include? ext
|
23
|
+
end
|
24
|
+
|
25
|
+
# whether :ext is associated with an extension tsc will need
|
26
|
+
# in the compilation directory, eg. .js
|
27
|
+
#
|
28
|
+
def copy_ext?(ext)
|
29
|
+
typescript_ext?(ext) || copy_extensions.include?(ext)
|
30
|
+
end
|
31
|
+
|
32
|
+
# whether :page has a typescript extension.
|
33
|
+
#
|
34
|
+
def typescript_file?(page)
|
35
|
+
typescript_ext? File.extname(page.name).downcase
|
36
|
+
end
|
37
|
+
|
38
|
+
# whether :page has a copy_file extension.
|
39
|
+
#
|
40
|
+
def copy_file?(page)
|
41
|
+
copy_ext? File.extname(page.name).downcase
|
42
|
+
end
|
43
|
+
|
44
|
+
def setup
|
45
|
+
unless @setup
|
46
|
+
FileUtils.mkdir_p(temp_dir)
|
47
|
+
@setup = true
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def static_files
|
52
|
+
@static_files ||= []
|
53
|
+
end
|
54
|
+
|
55
|
+
attr_accessor :site, :pages
|
56
|
+
|
57
|
+
# Typescript hook run before the site is rendered. This is used to reset
|
58
|
+
# the typescript pages array and to assign the site instance used for the
|
59
|
+
# compilation.
|
60
|
+
#
|
61
|
+
def pre_render(site, _)
|
62
|
+
self.site = site
|
63
|
+
@pages = []
|
64
|
+
Jekyll.logger.debug('Typescript', 'clearing out temporary build directory.')
|
65
|
+
FileUtils.rm_rf(Dir.glob(File.join(temp_dir, '*')))
|
66
|
+
end
|
67
|
+
|
68
|
+
# Typescript hook run after a page has been rendered. This is used to add a
|
69
|
+
# a page to typescripts memory if that page is needed for typescript
|
70
|
+
# compilation.
|
71
|
+
#
|
72
|
+
def add_page(page)
|
73
|
+
@pages << page if copy_ext? page.ext
|
74
|
+
end
|
75
|
+
|
76
|
+
# Once all the site files have been processed, compile and replace the content
|
77
|
+
# of any typescript files.
|
78
|
+
#
|
79
|
+
def post_render(*args)
|
80
|
+
setup
|
81
|
+
|
82
|
+
populate_temp_dir
|
83
|
+
@pages.each do |page|
|
84
|
+
next unless typescript_ext? page.ext
|
85
|
+
|
86
|
+
# change the output extension. it's a hack... but it works so good enough.
|
87
|
+
page.send(:_renderer).instance_variable_set(:@output_ext, '.js')
|
88
|
+
|
89
|
+
command = compile_command(in_temp_dir(page.relative_path))
|
90
|
+
Jekyll.logger.debug('Typescript') {
|
91
|
+
"running compile command: #{Shellwords.join(command[1..])}" }
|
92
|
+
compile_output = IO.popen(command, &:read).chomp # spawn a cmd & read process output.
|
93
|
+
|
94
|
+
unless $?.success?
|
95
|
+
raise SyntaxError, "typescript failed to convert: #{page.path}\n" + compile_output
|
96
|
+
end
|
97
|
+
|
98
|
+
output_file = File.join(temp_dir,
|
99
|
+
File.dirname(page.relative_path),
|
100
|
+
File.basename(page.relative_path, '.*') + '.js')
|
101
|
+
|
102
|
+
page.output = File.open(output_file, 'r', &:read)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
# return :path but from the typescript temporary directory.
|
109
|
+
#
|
110
|
+
def in_temp_dir(path)
|
111
|
+
File.join(temp_dir, path)
|
112
|
+
end
|
113
|
+
|
114
|
+
# copy all of the pages in pages to this plugins temporary directory.
|
115
|
+
#
|
116
|
+
def populate_temp_dir
|
117
|
+
Dir.chdir(temp_dir) do
|
118
|
+
(@pages + static_files).each do |page|
|
119
|
+
|
120
|
+
if page.is_a?(StaticFile)
|
121
|
+
FileUtils.mkdir_p('./' + page.instance_variable_get(:@dir))
|
122
|
+
FileUtils.copy(site.in_source_dir(page.relative_path),
|
123
|
+
'./' + page.relative_path)
|
124
|
+
else
|
125
|
+
FileUtils.mkdir_p('./' + page.dir) # make temp container for file
|
126
|
+
File.open(page.relative_path, 'w') { |fd| fd.write(page.content) }
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# get a tsc compile command for use with popen, append :args to the end of it.
|
133
|
+
#
|
134
|
+
def compile_command(*args)
|
135
|
+
[ENV, *tsc_command, '--pretty', '--rootDir', temp_dir, *tsconfig_args, *args]
|
136
|
+
end
|
137
|
+
|
138
|
+
# value of the tsconfig.json file as an array of command flags.
|
139
|
+
#
|
140
|
+
def tsconfig_args
|
141
|
+
unless @tsconfig_args
|
142
|
+
config_file = 'tsconfig.json'
|
143
|
+
|
144
|
+
@tsconfig_args = if File.exists?(config_file)
|
145
|
+
parse_tsconfig(dumb_read_json(config_file))
|
146
|
+
else
|
147
|
+
Jekyll.logger.warn('Typescript', "no config file found at #{config_file}")
|
148
|
+
[]
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
@tsconfig_args
|
153
|
+
end
|
154
|
+
|
155
|
+
Jekyll::Hooks.register(:site, :pre_render, &instance.method(:pre_render))
|
156
|
+
Jekyll::Hooks.register(:pages, :post_render, &instance.method(:add_page))
|
157
|
+
Jekyll::Hooks.register(:site, :post_render, &instance.method(:post_render))
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jekyll
|
4
|
+
module Typescript
|
5
|
+
# Module providing methods to aid in the parsing of tsconfig.json files.
|
6
|
+
#
|
7
|
+
# WARN, some of this file is basically me ranting about how absurd tsc
|
8
|
+
# and some of the general web app standards are, as a Unix lover.
|
9
|
+
#
|
10
|
+
module TSConfig
|
11
|
+
# Parse a tsconfig.json JSON object into an array of equivalent commands
|
12
|
+
# line flags.
|
13
|
+
#
|
14
|
+
# For some dumb reason, tsc just outright ignores your tsconfig.json file
|
15
|
+
# when you're compiling a single file, instead of a project. See issue
|
16
|
+
# 6591 on Microsoft/Typescript.
|
17
|
+
#
|
18
|
+
def parse_tsconfig(json)
|
19
|
+
args = []
|
20
|
+
json['compilerOptions'].each_pair do |option, value|
|
21
|
+
flag = "--#{option}"
|
22
|
+
|
23
|
+
case value
|
24
|
+
when TrueClass, FalseClass
|
25
|
+
args << flag if value
|
26
|
+
when String
|
27
|
+
args << flag
|
28
|
+
args << value
|
29
|
+
when Array
|
30
|
+
args << flag
|
31
|
+
args << value.join(',')
|
32
|
+
else
|
33
|
+
Jekyll.logger.warn('Typescript',
|
34
|
+
"unknown option type for #{option} of type #{value.class}")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
args
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
# read a json file at :path, but allow for comments in the file.
|
43
|
+
#
|
44
|
+
# RANT
|
45
|
+
# Why in the great stallmans name does everyone use JSON as a config
|
46
|
+
# format when it doesn't support comments?
|
47
|
+
#
|
48
|
+
# RANT
|
49
|
+
# Why in gods name does JSON forbid comments when their pretty much
|
50
|
+
# ubiquotous?
|
51
|
+
#
|
52
|
+
# Adding an option to most parsers to allow comments doesn't seem too
|
53
|
+
# unreasonable, I mean it's not like JSON is solely used as a web
|
54
|
+
# interchange format anymore.
|
55
|
+
#
|
56
|
+
def dumb_read_json(path)
|
57
|
+
File.open(path, 'r') do |file|
|
58
|
+
# regxp partially sourced from https://stackoverflow.com/questions/19910002/remove-comments-from-json-data
|
59
|
+
JSON.parse(file.read.gsub(/(?:\/\/[^\n]+$)|(?:\/\*(?:[^*]+|\*+(?!\/))*\*\/)/m, ''))
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/jekyll_tsc.rb
ADDED
metadata
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jekyll-tsc
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mohsin Kaleem
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-02-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: jekyll
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.8'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.8'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.17.2
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.17.2
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.9'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.9'
|
55
|
+
description: |
|
56
|
+
provides automatic compilation of typescript files to javascript
|
57
|
+
files for your jekyll blog.
|
58
|
+
email: mohkalsin@gmail.com
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- lib/jekyll/typescript/config.rb
|
64
|
+
- lib/jekyll/typescript/converter.rb
|
65
|
+
- lib/jekyll/typescript/generator.rb
|
66
|
+
- lib/jekyll/typescript/manager.rb
|
67
|
+
- lib/jekyll/typescript/tsconfig.rb
|
68
|
+
- lib/jekyll/typescript/version.rb
|
69
|
+
- lib/jekyll_tsc.rb
|
70
|
+
homepage:
|
71
|
+
licenses:
|
72
|
+
- MIT
|
73
|
+
metadata: {}
|
74
|
+
post_install_message:
|
75
|
+
rdoc_options: []
|
76
|
+
require_paths:
|
77
|
+
- lib
|
78
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
requirements: []
|
89
|
+
rubygems_version: 3.0.3
|
90
|
+
signing_key:
|
91
|
+
specification_version: 4
|
92
|
+
summary: compile typescript files on your jekyll blog.
|
93
|
+
test_files: []
|