line-message-builder 0.4.0 → 0.6.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3bbeb0eeec944a0886b6e6dec3b171c88182c0097ad31c03cc16d7270f1eb471
4
- data.tar.gz: 8f08afeab2e40b152e8e4218b00f03f725be5f3cfa70b687ebaf20e7d1dd2d7e
3
+ metadata.gz: f3ed7258b9de88098b6e78ff9165c4ab4b07b5328a294106f78e3cbed16b0725
4
+ data.tar.gz: fee080b8a5c4799a9a0859cd12b42bbc32d9797ee7906b07d65a80bc882040ae
5
5
  SHA512:
6
- metadata.gz: 0afd2ab03e4bbe7df364ebc27764380e48b9fd00a0a78ba345655f9227b7ff1cac00831024fd4ca923d2df1fb195c7e3c4947e6290f530a3466d002b325af4f3
7
- data.tar.gz: 91455d81ccc9d6aa646e5a5851ad55baa19e89d4c427b4c9e4fa951676f6cf5d6e8005983d5a76610c05ced666a353d06f54ef7020516ad67250000cb4379ba7
6
+ metadata.gz: 5016cdac5849c4f6931b5e6810abfcbffec6ef337fecb3461c19a4af507b6bc7fbd4c8cc79ab8770183c9ecaa5403efd52686bbf4525d9c0996cf200d966acb5
7
+ data.tar.gz: 93da8212a3282dd64587679151f8b2a08d6523f60ecd32e765bb045ccae98b110ca92352402d5217d870a6405e05dd9c167b55707a47ccdef98dde2e604d469c
@@ -1 +1 @@
1
- {".":"0.4.0"}
1
+ {".":"0.6.0"}
data/.rspec CHANGED
@@ -1,3 +1,5 @@
1
1
  --format documentation
2
+ --format RspecJunitFormatter
3
+ --out junit.xml
2
4
  --color
3
5
  --require spec_helper
data/CHANGELOG.md CHANGED
@@ -1,5 +1,37 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.6.0](https://github.com/elct9620/line-message-builder/compare/v0.5.0...v0.6.0) (2025-04-07)
4
+
5
+
6
+ ### Features
7
+
8
+ * Add Flex carousel support for Line message builder ([757b16d](https://github.com/elct9620/line-message-builder/commit/757b16d2f71ff14cff39aa1990773851bc78192b))
9
+ * Add height and max_height options to flex box with validation ([932c743](https://github.com/elct9620/line-message-builder/commit/932c7435ea11a3dec7903ffa19c48a5987231e39))
10
+ * Add shrink-to-fit adjust mode for flex buttons and texts ([b3ce3a2](https://github.com/elct9620/line-message-builder/commit/b3ce3a29614514b3049d5b6ad718b3dbcd283898))
11
+ * Add width and max_width options to flex box builder ([3d20c98](https://github.com/elct9620/line-message-builder/commit/3d20c98e670f49fad3f35c93d88364fb7f14afc0))
12
+
13
+ ## [0.5.0](https://github.com/elct9620/line-message-builder/compare/v0.4.0...v0.5.0) (2025-04-07)
14
+
15
+
16
+ ### Features
17
+
18
+ * Add Actionable module for flex components with message and postback actions ([9ac4b4a](https://github.com/elct9620/line-message-builder/commit/9ac4b4af591450e8f1925814b5a57e893ffa15db))
19
+ * Add enum validator for flex text alignment options ([540c58d](https://github.com/elct9620/line-message-builder/commit/540c58d94731adfe91d30e006bb0ee6714755006))
20
+ * Add justify_content and align_items options to Flex Box builder ([6c2015f](https://github.com/elct9620/line-message-builder/commit/6c2015f0a75a0f541cb52fef647e0bff1a245a28))
21
+ * Add layout validation for flex box with enum validator ([b1ecba1](https://github.com/elct9620/line-message-builder/commit/b1ecba160db03f94aaebc83b82158e75292c94eb))
22
+ * Add margin support for flex components in Line message builder ([36043b8](https://github.com/elct9620/line-message-builder/commit/36043b8d7390cb13d60174759fc5906a70aa2507))
23
+ * Add offset positioning support for flex message components ([1e28336](https://github.com/elct9620/line-message-builder/commit/1e2833656083aa72b0cfffccd5636e80ae41ccc9))
24
+ * Add padding support for flex box components with validation ([9dcd9d2](https://github.com/elct9620/line-message-builder/commit/9dcd9d20a48aed023440a2abe24e8b44eea8b425))
25
+ * Add padding support for Line Flex buttons with validation ([ca25a11](https://github.com/elct9620/line-message-builder/commit/ca25a1192c0d611ae064f935fc9335640d123b2d))
26
+ * Add SimpleCov Cobertura formatter for CI coverage reporting ([bb5bfc8](https://github.com/elct9620/line-message-builder/commit/bb5bfc8344c1b448e61a2857aa36e1f6b5ce0425))
27
+ * Add validator for spacing option in flex box builder ([06e7b98](https://github.com/elct9620/line-message-builder/commit/06e7b9805f8243c51faaf9c13c264ffb1f35091c))
28
+ * Add vertical positioning support for Flex message components ([f9ce97b](https://github.com/elct9620/line-message-builder/commit/f9ce97b666cabe47717cdd916722121372cb9bf0))
29
+
30
+
31
+ ### Bug Fixes
32
+
33
+ * Correct indentation in GitHub Actions workflow file ([1c1cd2d](https://github.com/elct9620/line-message-builder/commit/1c1cd2dfe2e48bd937a04ac25f7b2b772e02e1a6))
34
+
3
35
  ## [0.4.0](https://github.com/elct9620/line-message-builder/compare/v0.3.0...v0.4.0) (2025-04-06)
4
36
 
5
37
 
data/README.md CHANGED
@@ -1,7 +1,16 @@
1
1
  # LINE Message Builder
2
2
 
3
+ [![.github/workflows/main.yml](https://github.com/elct9620/line-message-builder/actions/workflows/main.yml/badge.svg)](https://github.com/elct9620/line-message-builder/actions/workflows/main.yml)
4
+ [![codecov](https://codecov.io/gh/elct9620/line-message-builder/graph/badge.svg?token=9TJTSRIL0X)](https://codecov.io/gh/elct9620/line-message-builder)
5
+
3
6
  Build LINE messages using DSL (Domain Specific Language) in Ruby.
4
7
 
8
+ ## Features
9
+
10
+ - Build LINE messages using DSL
11
+ - Validation of properties
12
+ - RSpec matchers for testing
13
+
5
14
  ## Installation
6
15
 
7
16
  Install the gem and add to the application's Gemfile by executing:
@@ -193,7 +202,7 @@ end
193
202
  | Component | Supported |
194
203
  | --------- | --------- |
195
204
  | Bubble | 🚧 |
196
- | Carousel | |
205
+ | Carousel | |
197
206
  | Box | 🚧 |
198
207
  | Button | 🚧 |
199
208
  | Image | 🚧 |
@@ -6,26 +6,23 @@ module Line
6
6
  module Actions
7
7
  # The Message class is used to build message actions for quick replies.
8
8
  class Message < Line::Message::Builder::Base
9
- def initialize(text, label: nil, context: nil, &)
10
- @text = text
11
- @label = label
12
-
13
- super(context: context, &)
14
- end
9
+ attr_reader :text
15
10
 
16
- def label(label)
17
- @label = label
18
- end
11
+ option :label, default: nil
19
12
 
20
- def text(text)
13
+ def initialize(text, context: nil, **options, &)
21
14
  @text = text
15
+
16
+ super(context: context, **options, &)
22
17
  end
23
18
 
24
19
  def to_h
20
+ raise RequiredError, "text is required" if text.nil?
21
+
25
22
  {
26
23
  type: "message",
27
- label: @label,
28
- text: @text
24
+ label: label,
25
+ text: text
29
26
  }.compact
30
27
  end
31
28
  end
@@ -6,32 +6,25 @@ module Line
6
6
  module Actions
7
7
  # The Postback class is used to build postback actions for quick replies.
8
8
  class Postback < Line::Message::Builder::Base
9
- def initialize(data, label: nil, display_text: nil, context: nil, &)
10
- @data = data
11
- @label = label
12
- @display_text = display_text
13
-
14
- super(context: context, &)
15
- end
9
+ attr_reader :data
16
10
 
17
- def label(label)
18
- @label = label
19
- end
11
+ option :label, default: nil
12
+ option :display_text, default: nil
20
13
 
21
- def data(data)
14
+ def initialize(data, context: nil, **options, &)
22
15
  @data = data
23
- end
24
16
 
25
- def display_text(display_text)
26
- @display_text = display_text
17
+ super(context: context, **options, &)
27
18
  end
28
19
 
29
20
  def to_h
21
+ raise RequiredError, "data is required" if data.nil?
22
+
30
23
  {
31
24
  type: "postback",
32
- label: @label,
33
- data: @data,
34
- displayText: @display_text
25
+ label: label,
26
+ data: data,
27
+ displayText: display_text
35
28
  }.compact
36
29
  end
37
30
  end
@@ -18,13 +18,14 @@ module Line
18
18
  @options ||= []
19
19
  end
20
20
 
21
- def option(name, default: nil)
21
+ def option(name, default: nil, validator: nil)
22
22
  options << name
23
23
 
24
24
  define_method name do |*args|
25
25
  if args.empty?
26
26
  instance_variable_get("@#{name}") || default
27
27
  else
28
+ validator&.valid!(args.first)
28
29
  instance_variable_set("@#{name}", args.first)
29
30
  end
30
31
  end
@@ -38,7 +39,7 @@ module Line
38
39
  @quick_reply = nil
39
40
 
40
41
  self.class.options.each do |option|
41
- instance_variable_set("@#{option}", options[option]) if options.key?(option)
42
+ send(option, options[option]) if options.key?(option)
42
43
  end
43
44
 
44
45
  instance_eval(&block) if ::Kernel.block_given?
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Line
4
+ module Message
5
+ module Builder
6
+ module Flex
7
+ # The action DSL for flex components.
8
+ module Actionable
9
+ def self.included(base)
10
+ base.attr_reader :action
11
+ end
12
+
13
+ def message(text, **options, &)
14
+ @action = Actions::Message.new(text, context: context, **options, &)
15
+ end
16
+
17
+ def postback(data, **options, &)
18
+ @action = Actions::Postback.new(data, context: context, **options, &)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -6,11 +6,28 @@ module Line
6
6
  module Flex
7
7
  # The box is a component for the Flex message.
8
8
  class Box < Line::Message::Builder::Base
9
+ include Actionable
10
+ include Position::Padding
11
+ include Position::Margin
12
+ include Position::Offset
13
+ include Size::Flex
14
+
9
15
  attr_reader :contents
10
16
 
11
- option :layout, default: :horizontal
12
- option :spacing, default: nil
13
- option :flex, default: nil
17
+ option :layout, default: :horizontal, validator: Validators::Enum.new(
18
+ :horizontal, :vertical, :baseline
19
+ )
20
+ option :justify_content, default: nil, validator: Validators::Enum.new(
21
+ :flex_start, :center, :flex_end, :space_between, :space_around, :space_evenly
22
+ )
23
+ option :align_items, default: nil, validator: Validators::Enum.new(
24
+ :flex_start, :center, :flex_end
25
+ )
26
+ option :spacing, default: nil, validator: Validators::Size.new(:pixel, :keyword)
27
+ option :width, default: nil, validator: Validators::Size.new(:pixel, :percentage)
28
+ option :max_width, default: nil, validator: Validators::Size.new(:pixel, :percentage)
29
+ option :height, default: nil, validator: Validators::Size.new(:pixel, :percentage)
30
+ option :max_height, default: nil, validator: Validators::Size.new(:pixel, :percentage)
14
31
 
15
32
  def initialize(context: nil, **options, &)
16
33
  @contents = []
@@ -34,16 +51,39 @@ module Line
34
51
  @contents << Flex::Image.new(url, context: context, **options, &)
35
52
  end
36
53
 
37
- def to_h
54
+ def to_h # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
38
55
  raise RequiredError, "layout is required" if layout.nil?
39
- raise RequiredError, "contents is required" if contents.empty?
40
56
 
41
57
  {
42
58
  type: "box",
43
59
  layout: layout,
60
+ # Position
61
+ justifyContent: justify_content,
62
+ alignItems: align_items,
44
63
  spacing: spacing,
64
+ # Position::Padding
65
+ paddingAll: padding,
66
+ paddingTop: padding_top,
67
+ paddingBottom: padding_bottom,
68
+ paddingStart: padding_start,
69
+ paddingEnd: padding_end,
70
+ # Position::Margin
71
+ margin: margin,
72
+ # Position::Offset
73
+ position: position,
74
+ offsetTop: offset_top,
75
+ offsetBottom: offset_bottom,
76
+ offsetStart: offset_start,
77
+ offsetEnd: offset_end,
78
+ # Size
79
+ width: width,
80
+ maxWidth: max_width,
81
+ height: height,
82
+ maxHeight: max_height,
83
+ # Size::Flex
45
84
  flex: flex,
46
- contents: contents.map(&:to_h)
85
+ contents: contents.map(&:to_h),
86
+ action: action&.to_h
47
87
  }.compact
48
88
  end
49
89
  end
@@ -18,6 +18,10 @@ module Line
18
18
  @contents = Line::Message::Builder::Flex::Bubble.new(context: context, **options, &)
19
19
  end
20
20
 
21
+ def carousel(**options, &)
22
+ @contents = Line::Message::Builder::Flex::Carousel.new(context: context, **options, &)
23
+ end
24
+
21
25
  def to_h
22
26
  raise Error, "contents should be bubble or carousel" if @contents.nil?
23
27
 
@@ -6,37 +6,45 @@ module Line
6
6
  module Flex
7
7
  # The button is a component of the Flex message.
8
8
  class Button < Line::Message::Builder::Base
9
- attr_reader :action
9
+ include Actionable
10
+ include Position::Vertical
11
+ include Position::Padding
12
+ include Position::Margin
13
+ include Position::Offset
14
+ include Size::Flex
15
+ include Size::AdjustMode
10
16
 
11
- option :flex, default: nil
12
- option :margin, default: nil
13
17
  option :style, default: :link
14
- option :height, default: :md
18
+ option :height, default: :md, validator: Validators::Enum.new(:sm, :md)
15
19
 
16
- def initialize(context: nil, **options, &)
17
- @action = nil
18
-
19
- super
20
- end
21
-
22
- def message(text, label:, display_text: nil, &)
23
- @action = Actions::Message.new(text, label: label, display_text: display_text, &)
24
- end
25
-
26
- def postback(data, label: nil, display_text: nil, &)
27
- @action = Actions::Postback.new(data, label: label, display_text: display_text, &)
28
- end
29
-
30
- def to_h
20
+ def to_h # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
31
21
  raise RequiredError, "action is required" if action.nil?
32
22
 
33
23
  {
34
24
  type: "button",
35
25
  action: action.to_h,
36
- flex: flex,
26
+ height: height,
27
+ # Position
28
+ grivity: gravity,
29
+ # Position::Padding
30
+ paddingAll: padding,
31
+ paddingTop: padding_top,
32
+ paddingBottom: padding_bottom,
33
+ paddingStart: padding_start,
34
+ paddingEnd: padding_end,
35
+ # Position::Margin
37
36
  margin: margin,
38
- style: style,
39
- height: height
37
+ # Position::Offset
38
+ position: position,
39
+ offsetTop: offset_top,
40
+ offsetBottom: offset_bottom,
41
+ offsetStart: offset_start,
42
+ offsetEnd: offset_end,
43
+ # Size::Flex
44
+ flex: flex,
45
+ # Size::AdjustMode
46
+ adjustMode: adjust_mode,
47
+ style: style
40
48
  }.compact
41
49
  end
42
50
  end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Line
4
+ module Message
5
+ module Builder
6
+ module Flex
7
+ # The carousel is multiple bubbles in a single Flex message.
8
+ class Carousel < Line::Message::Builder::Base
9
+ def initialize(context: nil, **options, &)
10
+ @contents = []
11
+
12
+ super
13
+ end
14
+
15
+ def bubble(**options, &)
16
+ @contents << Line::Message::Builder::Flex::Bubble.new(context: context, **options, &)
17
+ end
18
+
19
+ def to_h
20
+ raise RequiredError, "contents should have at least 1 bubble" if @contents.empty?
21
+ raise ValidationError, "contents should have at most 12 bubbles" if @contents.size > 12
22
+
23
+ {
24
+ type: "carousel",
25
+ contents: @contents.map(&:to_h)
26
+ }.compact
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -6,14 +6,18 @@ module Line
6
6
  module Flex
7
7
  # The image is a component for the Flex message.
8
8
  class Image < Line::Message::Builder::Base
9
+ include Actionable
10
+ include Position::Horizontal
11
+ include Position::Vertical
12
+ include Position::Margin
13
+ include Position::Offset
14
+ include Size::Flex
15
+ include Size::Image
16
+
9
17
  attr_reader :url
10
18
 
11
- option :size, default: nil
12
19
  option :aspect_ratio, default: nil
13
20
  option :aspect_mode, default: nil
14
- option :flex, default: nil
15
- option :margin, default: nil
16
- option :align, default: nil
17
21
 
18
22
  def initialize(url, context: nil, **options, &)
19
23
  @url = url
@@ -21,18 +25,30 @@ module Line
21
25
  super(context: context, **options, &)
22
26
  end
23
27
 
24
- def to_h # rubocop:disable Metrics/MethodLength
28
+ def to_h # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
25
29
  raise RequiredError, "url is required" if url.nil?
26
30
 
27
31
  {
28
32
  type: "image",
29
33
  url: url,
30
- size: size,
31
- flex: flex,
32
- margin: margin,
34
+ # Position
33
35
  align: align,
36
+ gravity: gravity,
37
+ # Position::Margin
38
+ margin: margin,
39
+ # Position::Offset
40
+ position: position,
41
+ offsetTop: offset_top,
42
+ offsetBottom: offset_bottom,
43
+ offsetStart: offset_start,
44
+ offsetEnd: offset_end,
45
+ # Size::Flex
46
+ flex: flex,
47
+ # Size::Image
48
+ size: size,
34
49
  aspectRatio: aspect_ratio,
35
- aspectMode: aspect_mode
50
+ aspectMode: aspect_mode,
51
+ action: action&.to_h
36
52
  }.compact
37
53
  end
38
54
  end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Line
4
+ module Message
5
+ module Builder
6
+ module Flex
7
+ module Position
8
+ # The horizontal provides "align" options for flex components.
9
+ module Horizontal
10
+ def self.included(base)
11
+ base.option :align,
12
+ default: :nil,
13
+ validator: Validators::Enum.new(
14
+ :start, :center, :end
15
+ )
16
+ end
17
+ end
18
+
19
+ # The vertical provides "gatvity" options for flex components.
20
+ module Vertical
21
+ def self.included(base)
22
+ base.option :gravity,
23
+ default: :nil,
24
+ validator: Validators::Enum.new(
25
+ :top, :center, :bottom
26
+ )
27
+ end
28
+ end
29
+
30
+ # The padding provides "padding" options for flex components.
31
+ module Padding
32
+ def self.included(base)
33
+ %i[padding padding_top padding_bottom padding_start padding_end].each do |option|
34
+ base.option option,
35
+ default: :nil,
36
+ validator: Validators::Size.new(:pixel, :keyword, :percentage)
37
+ end
38
+ end
39
+ end
40
+
41
+ # The margin provides "margin" options for flex components.
42
+ module Margin
43
+ def self.included(base)
44
+ base.option :margin,
45
+ default: :nil,
46
+ validator: Validators::Size.new(:pixel, :keyword)
47
+ end
48
+ end
49
+
50
+ # The offset provides "offset" options for flex components.
51
+ module Offset
52
+ def self.included(base)
53
+ base.option :position,
54
+ default: :nil,
55
+ validator: Validators::Enum.new(:absolute, :relative)
56
+
57
+ %i[offset_top offset_bottom offset_start offset_end].each do |option|
58
+ base.option option,
59
+ default: :nil,
60
+ validator: Validators::Size.new(:pixel, :keyword)
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Line
4
+ module Message
5
+ module Builder
6
+ module Flex
7
+ module Size
8
+ # The flex size provides "flex" options for flex components.
9
+ module Flex
10
+ def self.included(base)
11
+ base.option :flex,
12
+ default: :nil
13
+ end
14
+ end
15
+
16
+ # The image provides "size" options for flex image component.
17
+ module Image
18
+ def self.included(base)
19
+ base.option :size,
20
+ default: :nil,
21
+ validator: Validators::Size.new(:pixel, :image, :percentage)
22
+ end
23
+ end
24
+
25
+ # The shared provides "size" options for flex components which is icon, text and span.
26
+ module Shared
27
+ def self.included(base)
28
+ base.option :size,
29
+ default: :nil,
30
+ validator: Validators::Size.new(:pixel, :keyword)
31
+ end
32
+ end
33
+
34
+ # The adjust mode provides "adjust mode" options for flex components.
35
+ module AdjustMode
36
+ def self.included(base)
37
+ base.option :adjust_mode,
38
+ default: :nil,
39
+ validator: Validators::Enum.new(
40
+ :"shrink-to-fit"
41
+ )
42
+ end
43
+
44
+ def shrink_to_fit!
45
+ @adjust_mode = :"shrink-to-fit"
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -6,15 +6,20 @@ module Line
6
6
  module Flex
7
7
  # The text is a component of the Flex message.
8
8
  class Text < Line::Message::Builder::Base
9
+ include Actionable
10
+ include Position::Horizontal
11
+ include Position::Vertical
12
+ include Position::Margin
13
+ include Position::Offset
14
+ include Size::Flex
15
+ include Size::Shared
16
+ include Size::AdjustMode
17
+
9
18
  attr_reader :text
10
19
 
11
- option :size, default: nil
12
20
  option :wrap, default: false
13
21
  option :line_spacing, default: nil
14
22
  option :color, default: nil
15
- option :align, default: nil
16
- option :flex, default: nil
17
- option :margin, default: nil
18
23
 
19
24
  def initialize(text, context: nil, **options, &)
20
25
  @text = text
@@ -26,19 +31,33 @@ module Line
26
31
  @wrap = true
27
32
  end
28
33
 
29
- def to_h # rubocop:disable Metrics/MethodLength
34
+ def to_h # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
30
35
  raise RequiredError, "text is required" if text.nil?
31
36
 
32
37
  {
33
38
  type: "text",
34
39
  text: text,
35
40
  wrap: wrap,
36
- lineSpacing: line_spacing,
37
- color: color,
38
- size: size,
41
+ # Position
39
42
  align: align,
43
+ gravity: gravity,
44
+ # Position::Margin
40
45
  margin: margin,
41
- flex: flex
46
+ # Position::Offset
47
+ position: position,
48
+ offsetTop: offset_top,
49
+ offsetBottom: offset_bottom,
50
+ offsetStart: offset_start,
51
+ offsetEnd: offset_end,
52
+ # Size::Flex
53
+ flex: flex,
54
+ # Size::Shared
55
+ size: size,
56
+ # Size::AdjustMode
57
+ adjustMode: adjust_mode,
58
+ lineSpacing: line_spacing,
59
+ color: color,
60
+ action: action&.to_h
42
61
  }.compact
43
62
  end
44
63
  end
@@ -6,9 +6,13 @@ module Line
6
6
  # The Flex module allows to build Flex messages.
7
7
  module Flex
8
8
  require_relative "flex/builder"
9
+ require_relative "flex/actionable"
10
+ require_relative "flex/position"
11
+ require_relative "flex/size"
9
12
 
10
13
  # Container
11
14
  require_relative "flex/bubble"
15
+ require_relative "flex/carousel"
12
16
 
13
17
  # Components
14
18
  require_relative "flex/box"
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Line
4
+ module Message
5
+ module Builder
6
+ module Validators
7
+ # Validate values against a set of allowed values.
8
+ class Enum
9
+ attr_reader :allowed_values
10
+
11
+ def initialize(*allowed_values)
12
+ @allowed_values = allowed_values
13
+ end
14
+
15
+ def valid!(value)
16
+ return if allowed_values.include?(value.to_sym)
17
+
18
+ raise ValidationError, "Invalid value: #{value}. Allowed values are: #{allowed_values.join(", ")}"
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Line
4
+ module Message
5
+ module Builder
6
+ module Validators
7
+ # Validate size values for LINE messages.
8
+ class Size
9
+ VARIANTS = %i[pixel keyword image percentage].freeze
10
+ KEYWORDS = %i[none xs sm md lg xl xxl].freeze
11
+ IMAGE_KEYWORDS = %i[xxs xs sm md lg xl xxl 3xl 4xl 5xl full].freeze
12
+ PIXEL_REGEX = /^\d+px$/
13
+ PERCENTAGE_REGEX = /^\f+%$/
14
+
15
+ def initialize(*variants)
16
+ @variants = variants & VARIANTS
17
+ end
18
+
19
+ def valid?(value)
20
+ @variants.any? do |variant|
21
+ send("#{variant}?", value)
22
+ end
23
+ end
24
+
25
+ def pixel?(value)
26
+ value.to_s.match?(PIXEL_REGEX)
27
+ end
28
+
29
+ def keyword?(value)
30
+ KEYWORDS.include?(value.to_sym)
31
+ end
32
+
33
+ def image?(value)
34
+ IMAGE_KEYWORDS.include?(value.to_sym)
35
+ end
36
+
37
+ def percentage?(value)
38
+ value.to_s.match?(PERCENTAGE_REGEX)
39
+ end
40
+
41
+ def valid!(value)
42
+ return if valid?(value)
43
+
44
+ raise ValidationError,
45
+ "Invalid value: #{value}. " \
46
+ "Expected one of: #{VARIANTS.join(", ")}"
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Line
4
+ module Message
5
+ module Builder
6
+ # :nodoc:
7
+ module Validators
8
+ require_relative "validators/enum"
9
+ require_relative "validators/size"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -3,7 +3,7 @@
3
3
  module Line
4
4
  module Message
5
5
  module Builder
6
- VERSION = "0.4.0"
6
+ VERSION = "0.6.0"
7
7
  end
8
8
  end
9
9
  end
@@ -8,8 +8,10 @@ module Line
8
8
  module Builder
9
9
  class Error < StandardError; end
10
10
  class RequiredError < Error; end
11
+ class ValidationError < Error; end
11
12
 
12
13
  require_relative "builder/base"
14
+ require_relative "builder/validators"
13
15
  require_relative "builder/actions"
14
16
  require_relative "builder/quick_reply"
15
17
  require_relative "builder/container"
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: line-message-builder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aotokitsuruya
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2025-04-06 00:00:00.000000000 Z
10
+ date: 2025-04-07 00:00:00.000000000 Z
12
11
  dependencies: []
13
12
  description: The LINE Messaging API message builder.
14
13
  email:
@@ -32,14 +31,21 @@ files:
32
31
  - lib/line/message/builder/base.rb
33
32
  - lib/line/message/builder/container.rb
34
33
  - lib/line/message/builder/flex.rb
34
+ - lib/line/message/builder/flex/actionable.rb
35
35
  - lib/line/message/builder/flex/box.rb
36
36
  - lib/line/message/builder/flex/bubble.rb
37
37
  - lib/line/message/builder/flex/builder.rb
38
38
  - lib/line/message/builder/flex/button.rb
39
+ - lib/line/message/builder/flex/carousel.rb
39
40
  - lib/line/message/builder/flex/image.rb
41
+ - lib/line/message/builder/flex/position.rb
42
+ - lib/line/message/builder/flex/size.rb
40
43
  - lib/line/message/builder/flex/text.rb
41
44
  - lib/line/message/builder/quick_reply.rb
42
45
  - lib/line/message/builder/text.rb
46
+ - lib/line/message/builder/validators.rb
47
+ - lib/line/message/builder/validators/enum.rb
48
+ - lib/line/message/builder/validators/size.rb
43
49
  - lib/line/message/builder/version.rb
44
50
  - lib/line/message/rspec.rb
45
51
  - lib/line/message/rspec/matchers.rb
@@ -59,7 +65,6 @@ metadata:
59
65
  source_code_uri: https://github.com/elct9620/line-message-builder/tree/main
60
66
  changelog_uri: https://github.com/elct9620/line-message-builder/blob/main/CHANGELOG.md
61
67
  rubygems_mfa_required: 'true'
62
- post_install_message:
63
68
  rdoc_options: []
64
69
  require_paths:
65
70
  - lib
@@ -74,8 +79,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
74
79
  - !ruby/object:Gem::Version
75
80
  version: '0'
76
81
  requirements: []
77
- rubygems_version: 3.5.22
78
- signing_key:
82
+ rubygems_version: 3.6.2
79
83
  specification_version: 4
80
84
  summary: The LINE Messaging API message builder.
81
85
  test_files: []