MuranoCLI 2.0.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.
Files changed (151) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +28 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +21 -0
  5. data/Gemfile +27 -0
  6. data/LICENSE.txt +19 -0
  7. data/MuranoCLI.gemspec +50 -0
  8. data/MuranoCLI.iss +50 -0
  9. data/README.markdown +208 -0
  10. data/Rakefile +188 -0
  11. data/TODO.taskpaper +122 -0
  12. data/bin/mr +8 -0
  13. data/bin/murano +84 -0
  14. data/docs/demo.md +109 -0
  15. data/lib/MrMurano/Account.rb +211 -0
  16. data/lib/MrMurano/Config-Migrate.rb +47 -0
  17. data/lib/MrMurano/Config.rb +286 -0
  18. data/lib/MrMurano/Mock.rb +63 -0
  19. data/lib/MrMurano/Product-1P-Device.rb +145 -0
  20. data/lib/MrMurano/Product-Resources.rb +195 -0
  21. data/lib/MrMurano/Product.rb +358 -0
  22. data/lib/MrMurano/ProjectFile.rb +349 -0
  23. data/lib/MrMurano/Solution-Cors.rb +46 -0
  24. data/lib/MrMurano/Solution-Endpoint.rb +177 -0
  25. data/lib/MrMurano/Solution-File.rb +150 -0
  26. data/lib/MrMurano/Solution-ServiceConfig.rb +140 -0
  27. data/lib/MrMurano/Solution-Services.rb +326 -0
  28. data/lib/MrMurano/Solution-Users.rb +129 -0
  29. data/lib/MrMurano/Solution.rb +59 -0
  30. data/lib/MrMurano/SubCmdGroupContext.rb +49 -0
  31. data/lib/MrMurano/SyncUpDown.rb +565 -0
  32. data/lib/MrMurano/commands/assign.rb +57 -0
  33. data/lib/MrMurano/commands/businessList.rb +45 -0
  34. data/lib/MrMurano/commands/completion.rb +152 -0
  35. data/lib/MrMurano/commands/config.rb +67 -0
  36. data/lib/MrMurano/commands/content.rb +130 -0
  37. data/lib/MrMurano/commands/cors.rb +30 -0
  38. data/lib/MrMurano/commands/domain.rb +17 -0
  39. data/lib/MrMurano/commands/gb.rb +33 -0
  40. data/lib/MrMurano/commands/init.rb +138 -0
  41. data/lib/MrMurano/commands/keystore.rb +157 -0
  42. data/lib/MrMurano/commands/logs.rb +78 -0
  43. data/lib/MrMurano/commands/mock.rb +63 -0
  44. data/lib/MrMurano/commands/password.rb +88 -0
  45. data/lib/MrMurano/commands/postgresql.rb +41 -0
  46. data/lib/MrMurano/commands/product.rb +14 -0
  47. data/lib/MrMurano/commands/productCreate.rb +39 -0
  48. data/lib/MrMurano/commands/productDelete.rb +33 -0
  49. data/lib/MrMurano/commands/productDevice.rb +84 -0
  50. data/lib/MrMurano/commands/productDeviceIdCmds.rb +86 -0
  51. data/lib/MrMurano/commands/productList.rb +45 -0
  52. data/lib/MrMurano/commands/productWrite.rb +27 -0
  53. data/lib/MrMurano/commands/show.rb +80 -0
  54. data/lib/MrMurano/commands/solution.rb +14 -0
  55. data/lib/MrMurano/commands/solutionCreate.rb +39 -0
  56. data/lib/MrMurano/commands/solutionDelete.rb +34 -0
  57. data/lib/MrMurano/commands/solutionList.rb +45 -0
  58. data/lib/MrMurano/commands/status.rb +92 -0
  59. data/lib/MrMurano/commands/sync.rb +60 -0
  60. data/lib/MrMurano/commands/timeseries.rb +115 -0
  61. data/lib/MrMurano/commands/tsdb.rb +271 -0
  62. data/lib/MrMurano/commands/usage.rb +23 -0
  63. data/lib/MrMurano/commands/zshcomplete.erb +112 -0
  64. data/lib/MrMurano/commands.rb +32 -0
  65. data/lib/MrMurano/hash.rb +20 -0
  66. data/lib/MrMurano/http.rb +153 -0
  67. data/lib/MrMurano/makePretty.rb +75 -0
  68. data/lib/MrMurano/schema/pf-v1.0.0.yaml +114 -0
  69. data/lib/MrMurano/schema/sf-v0.2.0.yaml +77 -0
  70. data/lib/MrMurano/schema/sf-v0.3.0.yaml +78 -0
  71. data/lib/MrMurano/template/mock.erb +9 -0
  72. data/lib/MrMurano/template/projectFile.murano.erb +81 -0
  73. data/lib/MrMurano/verbosing.rb +99 -0
  74. data/lib/MrMurano/version.rb +4 -0
  75. data/lib/MrMurano.rb +20 -0
  76. data/spec/Account-Passwords_spec.rb +242 -0
  77. data/spec/Account_spec.rb +272 -0
  78. data/spec/ConfigFile_spec.rb +50 -0
  79. data/spec/ConfigMigrate_spec.rb +89 -0
  80. data/spec/Config_spec.rb +409 -0
  81. data/spec/Http_spec.rb +204 -0
  82. data/spec/MakePretties_spec.rb +118 -0
  83. data/spec/Mock_spec.rb +53 -0
  84. data/spec/ProductBase_spec.rb +113 -0
  85. data/spec/ProductContent_spec.rb +162 -0
  86. data/spec/ProductResources_spec.rb +329 -0
  87. data/spec/Product_1P_Device_spec.rb +202 -0
  88. data/spec/Product_1P_RPC_spec.rb +175 -0
  89. data/spec/Product_spec.rb +153 -0
  90. data/spec/ProjectFile_spec.rb +324 -0
  91. data/spec/Solution-Cors_spec.rb +164 -0
  92. data/spec/Solution-Endpoint_spec.rb +581 -0
  93. data/spec/Solution-File_spec.rb +212 -0
  94. data/spec/Solution-ServiceConfig_spec.rb +202 -0
  95. data/spec/Solution-ServiceDevice_spec.rb +176 -0
  96. data/spec/Solution-ServiceEventHandler_spec.rb +385 -0
  97. data/spec/Solution-ServiceModules_spec.rb +465 -0
  98. data/spec/Solution-UsersRoles_spec.rb +207 -0
  99. data/spec/Solution_spec.rb +92 -0
  100. data/spec/SyncRoot_spec.rb +83 -0
  101. data/spec/SyncUpDown_spec.rb +495 -0
  102. data/spec/Verbosing_spec.rb +279 -0
  103. data/spec/_workspace.rb +27 -0
  104. data/spec/cmd_assign_spec.rb +51 -0
  105. data/spec/cmd_business_spec.rb +59 -0
  106. data/spec/cmd_common.rb +72 -0
  107. data/spec/cmd_config_spec.rb +68 -0
  108. data/spec/cmd_content_spec.rb +71 -0
  109. data/spec/cmd_cors_spec.rb +50 -0
  110. data/spec/cmd_device_spec.rb +96 -0
  111. data/spec/cmd_domain_spec.rb +32 -0
  112. data/spec/cmd_init_spec.rb +30 -0
  113. data/spec/cmd_keystore_spec.rb +97 -0
  114. data/spec/cmd_password_spec.rb +62 -0
  115. data/spec/cmd_status_spec.rb +239 -0
  116. data/spec/cmd_syncdown_spec.rb +86 -0
  117. data/spec/cmd_syncup_spec.rb +62 -0
  118. data/spec/cmd_usage_spec.rb +36 -0
  119. data/spec/fixtures/.mrmuranorc +9 -0
  120. data/spec/fixtures/ProjectFiles/invalid.yaml +9 -0
  121. data/spec/fixtures/ProjectFiles/only_meta.yaml +24 -0
  122. data/spec/fixtures/ProjectFiles/with_routes.yaml +27 -0
  123. data/spec/fixtures/SolutionFiles/0.2.0.json +20 -0
  124. data/spec/fixtures/SolutionFiles/0.2.0_invalid.json +18 -0
  125. data/spec/fixtures/SolutionFiles/0.2.json +21 -0
  126. data/spec/fixtures/SolutionFiles/0.3.0.json +20 -0
  127. data/spec/fixtures/SolutionFiles/0.3.0_invalid.json +19 -0
  128. data/spec/fixtures/SolutionFiles/0.3.json +20 -0
  129. data/spec/fixtures/SolutionFiles/basic.json +20 -0
  130. data/spec/fixtures/SolutionFiles/secret.json +6 -0
  131. data/spec/fixtures/configfile +9 -0
  132. data/spec/fixtures/dumped_config +42 -0
  133. data/spec/fixtures/mrmuranorc_deleted_bob +8 -0
  134. data/spec/fixtures/mrmuranorc_tool_bob +3 -0
  135. data/spec/fixtures/product_spec_files/example.exoline.spec.yaml +116 -0
  136. data/spec/fixtures/product_spec_files/example.murano.spec.yaml +14 -0
  137. data/spec/fixtures/product_spec_files/gwe.exoline.spec.yaml +21 -0
  138. data/spec/fixtures/product_spec_files/gwe.murano.spec.yaml +16 -0
  139. data/spec/fixtures/product_spec_files/lightbulb-no-state.yaml +11 -0
  140. data/spec/fixtures/product_spec_files/lightbulb.yaml +14 -0
  141. data/spec/fixtures/roles-three.yaml +11 -0
  142. data/spec/fixtures/syncable_content/assets/icon.png +0 -0
  143. data/spec/fixtures/syncable_content/assets/index.html +0 -0
  144. data/spec/fixtures/syncable_content/assets/js/script.js +0 -0
  145. data/spec/fixtures/syncable_content/modules/table_util.lua +58 -0
  146. data/spec/fixtures/syncable_content/routes/manyRoutes.lua +11 -0
  147. data/spec/fixtures/syncable_content/routes/singleRoute.lua +5 -0
  148. data/spec/fixtures/syncable_content/services/devdata.lua +18 -0
  149. data/spec/fixtures/syncable_content/services/timers.lua +4 -0
  150. data/spec/spec_helper.rb +119 -0
  151. metadata +498 -0
@@ -0,0 +1,32 @@
1
+ require 'MrMurano/commands/assign'
2
+ require 'MrMurano/commands/businessList'
3
+ require 'MrMurano/commands/config'
4
+ require 'MrMurano/commands/content'
5
+ require 'MrMurano/commands/cors'
6
+ require 'MrMurano/commands/domain'
7
+ require 'MrMurano/commands/init'
8
+ require 'MrMurano/commands/keystore'
9
+ require 'MrMurano/commands/logs'
10
+ require 'MrMurano/commands/mock'
11
+ require 'MrMurano/commands/postgresql'
12
+ require 'MrMurano/commands/password'
13
+ require 'MrMurano/commands/product'
14
+ require 'MrMurano/commands/productCreate'
15
+ require 'MrMurano/commands/productDelete'
16
+ require 'MrMurano/commands/productDevice'
17
+ require 'MrMurano/commands/productDeviceIdCmds'
18
+ require 'MrMurano/commands/productList'
19
+ require 'MrMurano/commands/productWrite'
20
+ require 'MrMurano/commands/show'
21
+ require 'MrMurano/commands/solution'
22
+ require 'MrMurano/commands/solutionCreate'
23
+ require 'MrMurano/commands/solutionDelete'
24
+ require 'MrMurano/commands/solutionList'
25
+ require 'MrMurano/commands/status'
26
+ require 'MrMurano/commands/sync'
27
+ require 'MrMurano/commands/timeseries'
28
+ require 'MrMurano/commands/tsdb'
29
+ require 'MrMurano/commands/usage'
30
+
31
+ require 'MrMurano/commands/completion'
32
+
@@ -0,0 +1,20 @@
1
+
2
+ # from: http://www.any-where.de/blog/ruby-hash-convert-string-keys-to-symbols/
3
+ class Hash
4
+ #take keys of hash and transform those to a symbols
5
+ def self.transform_keys_to_symbols(value)
6
+ return value.map{|v| Hash.transform_keys_to_symbols(v)} if value.is_a?(Array)
7
+ return value if not value.is_a?(Hash)
8
+ hash = value.inject({}){|memo,(k,v)| memo[k.to_sym] = Hash.transform_keys_to_symbols(v); memo}
9
+ return hash
10
+ end
11
+ #take keys of hash and transform those to strings
12
+ def self.transform_keys_to_strings(value)
13
+ return value.map{|v| Hash.transform_keys_to_strings(v)} if value.is_a?(Array)
14
+ return value if not value.is_a?(Hash)
15
+ hash = value.inject({}){|memo,(k,v)| memo[k.to_s] = Hash.transform_keys_to_strings(v); memo}
16
+ return hash
17
+ end
18
+ end
19
+
20
+ # vim: set ai et sw=2 ts=2 :
@@ -0,0 +1,153 @@
1
+ require 'uri'
2
+ require 'net/http'
3
+ require 'json'
4
+ require('certified') if Gem.win_platform?
5
+
6
+ module MrMurano
7
+ module Http
8
+ def token
9
+ return @token unless @token.nil?
10
+ @token = Account.new.token
11
+ raise "Not logged in!" if @token.nil?
12
+ @token
13
+ end
14
+
15
+ def json_opts
16
+ return @json_opts unless not defined?(@json_opts) or @json_opts.nil?
17
+ @json_opts = {
18
+ :allow_nan => true,
19
+ :symbolize_names => true,
20
+ :create_additions => false
21
+ }
22
+ end
23
+
24
+ def curldebug(request)
25
+ if $cfg['tool.curldebug'] then
26
+ a = []
27
+ a << %{curl -s }
28
+ if request.key?('Authorization') then
29
+ a << %{-H 'Authorization: #{request['Authorization']}'}
30
+ end
31
+ a << %{-H 'User-Agent: #{request['User-Agent']}'}
32
+ a << %{-H 'Content-Type: #{request.content_type}'}
33
+ a << %{-X #{request.method}}
34
+ a << %{'#{request.uri.to_s}'}
35
+ a << %{-d '#{request.body}'} unless request.body.nil?
36
+ puts a.join(' ')
37
+ end
38
+ end
39
+
40
+ def http
41
+ uri = URI('https://' + $cfg['net.host'])
42
+ if not defined?(@http) or @http.nil? then
43
+ @http = Net::HTTP.new(uri.host, uri.port)
44
+ @http.use_ssl = true
45
+ @http.start
46
+ end
47
+ @http
48
+ end
49
+ def http_reset
50
+ @http = nil
51
+ end
52
+
53
+ def set_def_headers(request)
54
+ request.content_type = 'application/json'
55
+ request['Authorization'] = 'token ' + token
56
+ request['User-Agent'] = "MrMurano/#{MrMurano::VERSION}"
57
+ request
58
+ end
59
+
60
+ def isJSON(data)
61
+ begin
62
+ return true, JSON.parse(data, json_opts)
63
+ rescue
64
+ return false, data
65
+ end
66
+ end
67
+
68
+ def showHttpError(request, response)
69
+ if $cfg['tool.debug'] then
70
+ puts "Sent #{request.method} #{request.uri.to_s}"
71
+ request.each_capitalized{|k,v| puts "> #{k}: #{v}"}
72
+ if request.body.nil? then
73
+ else
74
+ puts ">> #{request.body[0..156]}"
75
+ end
76
+ puts "Got #{response.code} #{response.message}"
77
+ response.each_capitalized{|k,v| puts "< #{k}: #{v}"}
78
+ end
79
+ isj, jsn = isJSON(response.body)
80
+ resp = "Request Failed: #{response.code}: "
81
+ if isj then
82
+ if $cfg['tool.fullerror'] then
83
+ resp << JSON.pretty_generate(jsn)
84
+ else
85
+ resp << "[#{jsn[:statusCode]}] " if jsn.has_key? :statusCode
86
+ resp << jsn[:message] if jsn.has_key? :message
87
+ end
88
+ else
89
+ resp << jsn
90
+ end
91
+ # assuming verbosing was included.
92
+ error resp
93
+ end
94
+
95
+ def workit(request, &block)
96
+ curldebug(request)
97
+ if block_given? then
98
+ return yield request, http()
99
+ else
100
+ response = http().request(request)
101
+ case response
102
+ when Net::HTTPSuccess
103
+ return {} if response.body.nil?
104
+ begin
105
+ return JSON.parse(response.body, json_opts)
106
+ rescue
107
+ return response.body
108
+ end
109
+ else
110
+ showHttpError(request, response)
111
+ end
112
+ end
113
+ end
114
+
115
+ def get(path='', query=nil, &block)
116
+ uri = endPoint(path)
117
+ uri.query = URI.encode_www_form(query) unless query.nil?
118
+ workit(set_def_headers(Net::HTTP::Get.new(uri)), &block)
119
+ end
120
+
121
+ def post(path='', body={}, &block)
122
+ uri = endPoint(path)
123
+ req = Net::HTTP::Post.new(uri)
124
+ set_def_headers(req)
125
+ req.body = JSON.generate(body)
126
+ workit(req, &block)
127
+ end
128
+
129
+ def postf(path='', form={}, &block)
130
+ uri = endPoint(path)
131
+ req = Net::HTTP::Post.new(uri)
132
+ set_def_headers(req)
133
+ req.content_type = 'application/x-www-form-urlencoded; charset=utf-8'
134
+ req.form_data = form
135
+ workit(req, &block)
136
+ end
137
+
138
+ def put(path='', body={}, &block)
139
+ uri = endPoint(path)
140
+ req = Net::HTTP::Put.new(uri)
141
+ set_def_headers(req)
142
+ req.body = JSON.generate(body)
143
+ workit(req, &block)
144
+ end
145
+
146
+ def delete(path='', &block)
147
+ uri = endPoint(path)
148
+ workit(set_def_headers(Net::HTTP::Delete.new(uri)), &block)
149
+ end
150
+
151
+ end
152
+ end
153
+ # vim: set ai et sw=2 ts=2 :
@@ -0,0 +1,75 @@
1
+ require 'date'
2
+ require 'json'
3
+ require 'highline'
4
+
5
+ module MrMurano
6
+ module Pretties
7
+
8
+ HighLine::Style.new(:name=>:on_aliceblue, :code=>"\e[48;5;231m", :rgb=>[240, 248, 255])
9
+ PRETTIES_COLORSCHEME = HighLine::ColorScheme.new do |cs|
10
+ cs[:subject] = [:red, :on_aliceblue]
11
+ cs[:timestamp] = [:blue]
12
+ cs[:json] = [:magenta]
13
+ end
14
+ HighLine.color_scheme = PRETTIES_COLORSCHEME
15
+
16
+ def self.makeJsonPretty(data, options)
17
+ if options.pretty then
18
+ ret = JSON.pretty_generate(data).to_s
19
+ ret[0] = HighLine.color(ret[0], :json)
20
+ ret[-1] = HighLine.color(ret[-1], :json)
21
+ ret
22
+ else
23
+ data.to_json
24
+ end
25
+ end
26
+
27
+ def self.makePretty(line, options)
28
+ out=''
29
+ out << HighLine.color("#{line[:type] || '--'} ".upcase, :subject)
30
+ out << HighLine.color("[#{line[:subject] || ''}]", :subject)
31
+ out << " "
32
+ if line.has_key?(:timestamp) then
33
+ if line[:timestamp].kind_of? Numeric then
34
+ if options.localtime then
35
+ curtime = Time.at(line[:timestamp]).localtime.to_datetime.iso8601(3)
36
+ else
37
+ curtime = Time.at(line[:timestamp]).gmtime.to_datetime.iso8601(3)
38
+ end
39
+ else
40
+ curtime = line[:timestamp]
41
+ end
42
+ else
43
+ curtime = "<no timestamp>"
44
+ end
45
+ out << HighLine.color(curtime, :timestamp)
46
+ out << ":\n"
47
+ if line.has_key?(:data) then
48
+ data = line[:data]
49
+
50
+ if data.kind_of?(Hash) then
51
+ if data.has_key?(:request) and data.has_key?(:response) then
52
+ out << "---------\nrequest:"
53
+ out << makeJsonPretty(data[:request], options)
54
+
55
+ out << "\n---------\nresponse:"
56
+ out << makeJsonPretty(data[:response], options)
57
+ else
58
+ out << makeJsonPretty(data, options)
59
+ end
60
+ else
61
+ out << data.to_s
62
+ end
63
+
64
+ else
65
+ line.delete :type
66
+ line.delete :timestamp
67
+ line.delete :subject
68
+ out << makeJsonPretty(line, options)
69
+ end
70
+ out
71
+ end
72
+
73
+ end
74
+ end
75
+ # vim: set ai et sw=2 ts=2 :
@@ -0,0 +1,114 @@
1
+ ---
2
+ type: object
3
+ description: |-
4
+ A Project File. "*.murano"
5
+ This describes all of the bits and bobs that go into a Murano Solution.
6
+
7
+ additionalProperties: false
8
+ required: [info, formatversion]
9
+ properties:
10
+ formatversion:
11
+ type: string
12
+ description: The version of the format of this file
13
+ pattern: '1.0.0'
14
+
15
+ info:
16
+ type: object
17
+ description: Meta data about this Project.
18
+ properties:
19
+ name:
20
+ type: string
21
+ pattern: '^([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$'
22
+ description: |-
23
+ The name of this Project. This needs to be domain name safe, since it
24
+ will be used to construct the the app domain.
25
+ summary:
26
+ type: string
27
+ description: Short, one line descript of this project
28
+ description:
29
+ type: string
30
+ description: A longer, multiple paragraph explaination of this project
31
+ authors:
32
+ type: array
33
+ description: Who contributed to building this project.
34
+ minItems: 1
35
+ items:
36
+ type: string
37
+ version:
38
+ type: string
39
+ description: Version of this project. Use Semantic Versioning. http://semver.org/
40
+ pattern: '^(\d+\.)?(\d+\.)?(\*|\d+)$'
41
+ required:
42
+ - name
43
+ - summary
44
+ - description
45
+ - authors
46
+ additionalProperties: false
47
+
48
+ assets:
49
+ type: object
50
+ description: How to find the static assests for this project.
51
+ properties:
52
+ default_page:
53
+ type: string
54
+ "$ref": "#/definitions/common"
55
+
56
+ modules:
57
+ type: object
58
+ description: How to find the modules for this project.
59
+ properties:
60
+ "$ref": "#/definitions/common"
61
+
62
+ routes:
63
+ type: object
64
+ description: How to find the endpoint routes for this project.
65
+ properties:
66
+ "$ref": "#/definitions/common"
67
+ cors:
68
+ oneOf:
69
+ - type: string
70
+ - type: object
71
+ properties:
72
+ origin:
73
+ type: array
74
+ methods:
75
+ type: array
76
+ headers:
77
+ type: array
78
+ credentials:
79
+ type: boolean
80
+
81
+ services:
82
+ type: object
83
+ description: How to find the service event handlers for this project.
84
+ properties:
85
+ "$ref": "#/definitions/common"
86
+
87
+ resources:
88
+ type: object
89
+ description: Which aliases will exist on connected devices.
90
+ properties:
91
+ "$ref": "#/definitions/common"
92
+
93
+ definitions:
94
+ globSet:
95
+ anyOf:
96
+ - type: null
97
+ - type: string
98
+ - type: array
99
+ items:
100
+ type: string
101
+
102
+ common:
103
+ include:
104
+ description: Glob patterns to specify which files to include
105
+ "$ref": "#/definitions/globSet"
106
+ exclude:
107
+ description: Glob pattern to remove files from the included list
108
+ "$ref": "#/definitions/globSet"
109
+ location:
110
+ description: Directory prefix all include globs with
111
+ type: string
112
+
113
+
114
+ # vim: set et sw=2 ts=2 :
@@ -0,0 +1,77 @@
1
+ ---
2
+ type: object
3
+ description: |
4
+ A Solutionfile.json
5
+ This describes all of the bits and bobs that go into a Murano Solution.
6
+
7
+ properties:
8
+ version:
9
+ type: string
10
+ pattern: "0\\.2(\\.0)?"
11
+ description: Version format of the config
12
+
13
+ default_page:
14
+ type: string
15
+ description: The local file name to upload as /
16
+
17
+ file_dir:
18
+ type: string
19
+ description: Relative path to directory of static assets
20
+
21
+ custom_api:
22
+ type: string
23
+ description: Relative path of file containing endpoints (or routes)
24
+
25
+ custom_api_hook:
26
+ type: string
27
+ description: URL path to call at end of deploy
28
+
29
+ modules:
30
+ type: object
31
+ description: Additional lua chunks to load with endpoints and event handlers
32
+ patternProperties:
33
+ "[a-z]+":
34
+ type: string
35
+ description: Relative path to module script
36
+
37
+ event_handler:
38
+ type: object
39
+ description: Event handler scripts
40
+ properties:
41
+ device:
42
+ type: object
43
+ description: Device (Product) event handlers
44
+ properties:
45
+ datapoint:
46
+ type: string
47
+ description: Relative path to device.datapoint event script
48
+ required: [datapoint]
49
+ timer:
50
+ type: object
51
+ description: Timer event handlers
52
+ properties:
53
+ timer:
54
+ type: string
55
+ description: Relative path to timer.timer event script
56
+ required: [timer]
57
+ additionalProperties: false
58
+
59
+ cors:
60
+ type: object
61
+ properties:
62
+ origin:
63
+ type: array
64
+ methods:
65
+ type: array
66
+ headers:
67
+ type: array
68
+ credentials:
69
+ type: boolean
70
+
71
+ required:
72
+ - default_page
73
+ - file_dir
74
+ - custom_api
75
+ - event_handler
76
+ additionalProperties: false
77
+