openc3 5.8.1 → 5.9.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 (104) hide show
  1. checksums.yaml +4 -4
  2. data/ext/openc3/ext/crc/crc.c +1 -1
  3. data/lib/openc3/api/cmd_api.rb +1 -1
  4. data/lib/openc3/microservices/decom_microservice.rb +10 -2
  5. data/lib/openc3/microservices/reaction_microservice.rb +152 -81
  6. data/lib/openc3/microservices/timeline_microservice.rb +1 -1
  7. data/lib/openc3/microservices/trigger_group_microservice.rb +188 -118
  8. data/lib/openc3/migrations/20230615000000_autonomic.rb +86 -0
  9. data/lib/openc3/models/activity_model.rb +2 -4
  10. data/lib/openc3/models/microservice_model.rb +6 -2
  11. data/lib/openc3/models/model.rb +1 -3
  12. data/lib/openc3/models/reaction_model.rb +124 -119
  13. data/lib/openc3/models/scope_model.rb +15 -3
  14. data/lib/openc3/models/timeline_model.rb +1 -3
  15. data/lib/openc3/models/trigger_group_model.rb +16 -50
  16. data/lib/openc3/models/trigger_model.rb +86 -123
  17. data/lib/openc3/packets/json_packet.rb +2 -3
  18. data/lib/openc3/script/commands.rb +10 -0
  19. data/lib/openc3/script/script.rb +1 -0
  20. data/lib/openc3/top_level.rb +0 -12
  21. data/lib/openc3/utilities/authorization.rb +1 -1
  22. data/lib/openc3/utilities/bucket_require.rb +5 -1
  23. data/lib/openc3/utilities/bucket_utilities.rb +4 -1
  24. data/lib/openc3/utilities/cli_generator.rb +56 -4
  25. data/lib/openc3/utilities/ruby_lex_utils.rb +4 -0
  26. data/lib/openc3/version.rb +6 -6
  27. data/templates/plugin/README.md +54 -4
  28. data/templates/plugin/Rakefile +31 -3
  29. data/templates/tool_angular/.editorconfig +16 -0
  30. data/templates/tool_angular/.gitignore +44 -0
  31. data/templates/tool_angular/.vscode/extensions.json +4 -0
  32. data/templates/tool_angular/.vscode/launch.json +20 -0
  33. data/templates/tool_angular/.vscode/tasks.json +42 -0
  34. data/templates/tool_angular/angular.json +111 -0
  35. data/templates/tool_angular/extra-webpack.config.js +8 -0
  36. data/templates/tool_angular/package.json +47 -0
  37. data/templates/tool_angular/src/app/app-routing.module.ts +15 -0
  38. data/templates/tool_angular/src/app/app.component.html +31 -0
  39. data/templates/tool_angular/src/app/app.component.scss +26 -0
  40. data/templates/tool_angular/src/app/app.component.spec.ts +29 -0
  41. data/templates/tool_angular/src/app/app.component.ts +51 -0
  42. data/templates/tool_angular/src/app/app.module.ts +30 -0
  43. data/templates/tool_angular/src/app/custom-overlay-container.ts +17 -0
  44. data/templates/tool_angular/src/app/empty-route/empty-route.component.ts +7 -0
  45. data/templates/tool_angular/src/app/openc3-api.d.ts +1 -0
  46. data/templates/tool_angular/src/assets/.gitkeep +0 -0
  47. data/templates/tool_angular/src/environments/environment.prod.ts +3 -0
  48. data/templates/tool_angular/src/environments/environment.ts +16 -0
  49. data/templates/tool_angular/src/favicon.ico +0 -0
  50. data/templates/tool_angular/src/index.html +13 -0
  51. data/templates/tool_angular/src/main.single-spa.ts +40 -0
  52. data/templates/tool_angular/src/single-spa/asset-url.ts +12 -0
  53. data/templates/tool_angular/src/single-spa/single-spa-props.ts +8 -0
  54. data/templates/tool_angular/src/styles.scss +1 -0
  55. data/templates/tool_angular/tsconfig.app.json +13 -0
  56. data/templates/tool_angular/tsconfig.json +33 -0
  57. data/templates/tool_angular/tsconfig.spec.json +14 -0
  58. data/templates/tool_angular/yarn.lock +8080 -0
  59. data/templates/tool_react/.eslintrc +7 -0
  60. data/templates/tool_react/.gitignore +72 -0
  61. data/templates/tool_react/.prettierignore +8 -0
  62. data/templates/tool_react/babel.config.json +29 -0
  63. data/templates/tool_react/jest.config.js +12 -0
  64. data/templates/tool_react/package.json +53 -0
  65. data/templates/tool_react/src/openc3-tool_name.js +24 -0
  66. data/templates/tool_react/src/root.component.js +88 -0
  67. data/templates/tool_react/src/root.component.test.js +9 -0
  68. data/templates/tool_react/webpack.config.js +27 -0
  69. data/templates/tool_react/yarn.lock +6854 -0
  70. data/templates/tool_svelte/.gitignore +72 -0
  71. data/templates/tool_svelte/.prettierignore +8 -0
  72. data/templates/tool_svelte/babel.config.js +12 -0
  73. data/templates/tool_svelte/build/smui.css +5 -0
  74. data/templates/tool_svelte/jest.config.js +9 -0
  75. data/templates/tool_svelte/package.json +46 -0
  76. data/templates/tool_svelte/rollup.config.js +72 -0
  77. data/templates/tool_svelte/src/App.svelte +42 -0
  78. data/templates/tool_svelte/src/App.test.js +9 -0
  79. data/templates/tool_svelte/src/services/api.js +92 -0
  80. data/templates/tool_svelte/src/services/axios.js +85 -0
  81. data/templates/tool_svelte/src/services/cable.js +65 -0
  82. data/templates/tool_svelte/src/services/config-parser.js +199 -0
  83. data/templates/tool_svelte/src/services/openc3-api.js +647 -0
  84. data/templates/tool_svelte/src/theme/_smui-theme.scss +25 -0
  85. data/templates/tool_svelte/src/tool_name.js +17 -0
  86. data/templates/tool_svelte/yarn.lock +5052 -0
  87. data/templates/tool_vue/.browserslistrc +16 -0
  88. data/templates/tool_vue/.env.standalone +1 -0
  89. data/templates/tool_vue/.eslintrc.js +43 -0
  90. data/templates/tool_vue/.gitignore +2 -0
  91. data/templates/tool_vue/.nycrc +3 -0
  92. data/templates/tool_vue/.prettierrc.js +5 -0
  93. data/templates/tool_vue/babel.config.json +11 -0
  94. data/templates/tool_vue/jsconfig.json +6 -0
  95. data/templates/tool_vue/package.json +52 -0
  96. data/templates/tool_vue/src/App.vue +15 -0
  97. data/templates/tool_vue/src/main.js +38 -0
  98. data/templates/tool_vue/src/router.js +29 -0
  99. data/templates/tool_vue/src/tools/tool_name/tool_name.vue +63 -0
  100. data/templates/tool_vue/vue.config.js +30 -0
  101. data/templates/tool_vue/yarn.lock +9145 -0
  102. data/templates/widget/package.json +9 -9
  103. data/templates/widget/yarn.lock +77 -73
  104. metadata +76 -2
@@ -0,0 +1,92 @@
1
+ /*
2
+ # Copyright 2022 Ball Aerospace & Technologies Corp.
3
+ # All Rights Reserved.
4
+ #
5
+ # This program is free software; you can modify and/or redistribute it
6
+ # under the terms of the GNU Affero General Public License
7
+ # as published by the Free Software Foundation; version 3 with
8
+ # attribution addendums as found in the LICENSE.txt
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Affero General Public License for more details.
14
+
15
+ # Modified by OpenC3, Inc.
16
+ # All changes Copyright 2022, OpenC3, Inc.
17
+ # All Rights Reserved
18
+ #
19
+ # This file may also be used under the terms of a commercial license
20
+ # if purchased from OpenC3, Inc.
21
+ */
22
+
23
+ import axios from './axios.js'
24
+
25
+ const request = async function (
26
+ method,
27
+ url,
28
+ { data, params = {}, headers, noAuth = false, noScope = false } = {}
29
+ ) {
30
+ if (!noAuth) {
31
+ try {
32
+ let refreshed = await OpenC3Auth.updateToken(
33
+ OpenC3Auth.defaultMinValidity
34
+ )
35
+ if (refreshed) {
36
+ OpenC3Auth.setTokens()
37
+ }
38
+ } catch (error) {
39
+ OpenC3Auth.login()
40
+ }
41
+ headers['Authorization'] = localStorage.openc3Token
42
+ }
43
+ if (!noScope && !params['scope']) {
44
+ params['scope'] = window.openc3Scope
45
+ }
46
+ return axios({
47
+ method,
48
+ url,
49
+ data,
50
+ params,
51
+ headers,
52
+ })
53
+ }
54
+
55
+ const acceptOnlyDefaultHeaders = {
56
+ Accept: 'application/json',
57
+ }
58
+
59
+ const fullDefaultHeaders = {
60
+ ...acceptOnlyDefaultHeaders,
61
+ 'Content-Type': 'application/json',
62
+ }
63
+
64
+ export default {
65
+ get: function (
66
+ path,
67
+ { params, headers = acceptOnlyDefaultHeaders, noScope, noAuth } = {}
68
+ ) {
69
+ return request('get', path, { params, headers, noScope, noAuth })
70
+ },
71
+
72
+ put: function (
73
+ path,
74
+ { data, params, headers = fullDefaultHeaders, noScope, noAuth } = {}
75
+ ) {
76
+ return request('put', path, { data, params, headers, noScope, noAuth })
77
+ },
78
+
79
+ post: function (
80
+ path,
81
+ { data, params, headers = fullDefaultHeaders, noScope, noAuth } = {}
82
+ ) {
83
+ return request('post', path, { data, params, headers, noScope, noAuth })
84
+ },
85
+
86
+ delete: function (
87
+ path,
88
+ { params, headers = acceptOnlyDefaultHeaders, noScope, noAuth } = {}
89
+ ) {
90
+ return request('delete', path, { params, headers, noScope, noAuth })
91
+ },
92
+ }
@@ -0,0 +1,85 @@
1
+ /*
2
+ # Copyright 2022 Ball Aerospace & Technologies Corp.
3
+ # All Rights Reserved.
4
+ #
5
+ # This program is free software; you can modify and/or redistribute it
6
+ # under the terms of the GNU Affero General Public License
7
+ # as published by the Free Software Foundation; version 3 with
8
+ # attribution addendums as found in the LICENSE.txt
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Affero General Public License for more details.
14
+
15
+ # Modified by OpenC3, Inc.
16
+ # All changes Copyright 2022, OpenC3, Inc.
17
+ # All Rights Reserved
18
+ #
19
+ # This file may also be used under the terms of a commercial license
20
+ # if purchased from OpenC3, Inc.
21
+ */
22
+
23
+ import axios from 'axios'
24
+
25
+ const axiosInstance = axios.create({
26
+ baseURL: location.origin,
27
+ timeout: 60000,
28
+ params: {},
29
+ })
30
+
31
+ axiosInstance.interceptors.response.use(
32
+ (response) => response,
33
+ (error) => {
34
+ if (error.response) {
35
+ if (error.response.status === 401) {
36
+ OpenC3Auth.updateToken(OpenC3Auth.defaultMinValidity, true).then(
37
+ function (refreshed) {
38
+ if (refreshed) {
39
+ OpenC3Auth.setTokens()
40
+ }
41
+ }
42
+ )
43
+ }
44
+ // Individual tools can set 'Ignore-Errors' to an error code
45
+ // they potentially expect, e.g. '500', in which case we ignore it
46
+ // For example in CommandSender.vue:
47
+ // obs = this.api.cmd(targetName, commandName, paramList, {
48
+ // 'Ignore-Errors': '500',
49
+ // })
50
+ if (
51
+ error.response.headers['ignore-errors'] &&
52
+ error.response.headers['ignore-errors'].includes(
53
+ error.response.status.toString()
54
+ )
55
+ ) {
56
+ return Promise.reject(error)
57
+ }
58
+ let body = `HTTP ${error.response.status} - `
59
+ if (error.response?.statusText) {
60
+ body += `${error.response.statusText} `
61
+ }
62
+ if (error.response?.config?.data) {
63
+ body += `${error.response.config.data} `
64
+ }
65
+ if (error.response?.data?.message) {
66
+ body += `${error.response.data.message}`
67
+ } else if (error.response?.data?.exception) {
68
+ body += `${error.response.data.exception}`
69
+ } else if (error.response?.data?.error?.message) {
70
+ if (error.response.data.error.class) {
71
+ body += `${error.response.data.error.class} `
72
+ }
73
+ body += `${error.response.data.error.message}`
74
+ } else {
75
+ body += `${error.response?.data}`
76
+ }
77
+ alert(`Network error: ${body}`)
78
+ throw error
79
+ } else {
80
+ throw error
81
+ }
82
+ }
83
+ )
84
+
85
+ export default axiosInstance
@@ -0,0 +1,65 @@
1
+ /*
2
+ # Copyright 2022 Ball Aerospace & Technologies Corp.
3
+ # All Rights Reserved.
4
+ #
5
+ # This program is free software; you can modify and/or redistribute it
6
+ # under the terms of the GNU Affero General Public License
7
+ # as published by the Free Software Foundation; version 3 with
8
+ # attribution addendums as found in the LICENSE.txt
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Affero General Public License for more details.
14
+
15
+ # Modified by OpenC3, Inc.
16
+ # All changes Copyright 2022, OpenC3, Inc.
17
+ # All Rights Reserved
18
+ #
19
+ # This file may also be used under the terms of a commercial license
20
+ # if purchased from OpenC3, Inc.
21
+ */
22
+
23
+ import * as ActionCable from '@rails/actioncable'
24
+ //ActionCable.logger.enabled = true
25
+ ActionCable.ConnectionMonitor.staleThreshold = 10
26
+
27
+ export default class Cable {
28
+ constructor(url = '/openc3-api/cable') {
29
+ this._cable = null
30
+ this._url = url
31
+ }
32
+ disconnect() {
33
+ if (this._cable) {
34
+ this._cable.disconnect()
35
+ }
36
+ }
37
+ createSubscription(channel, scope, callbacks = {}, additionalOptions = {}) {
38
+ return OpenC3Auth.updateToken(OpenC3Auth.defaultMinValidity).then(
39
+ (refreshed) => {
40
+ if (refreshed) {
41
+ OpenC3Auth.setTokens()
42
+ }
43
+ if (this._cable == null) {
44
+ let final_url =
45
+ this._url +
46
+ '?scope=' +
47
+ window.openc3Scope +
48
+ '&authorization=' +
49
+ localStorage.openc3Token
50
+ this._cable = ActionCable.createConsumer(final_url)
51
+ }
52
+ return this._cable.subscriptions.create(
53
+ {
54
+ channel,
55
+ ...additionalOptions,
56
+ },
57
+ callbacks
58
+ )
59
+ }
60
+ )
61
+ }
62
+ recordPing() {
63
+ this._cable.connection.monitor.recordPing()
64
+ }
65
+ }
@@ -0,0 +1,199 @@
1
+ /*
2
+ # Copyright 2022 Ball Aerospace & Technologies Corp.
3
+ # All Rights Reserved.
4
+ #
5
+ # This program is free software; you can modify and/or redistribute it
6
+ # under the terms of the GNU Affero General Public License
7
+ # as published by the Free Software Foundation; version 3 with
8
+ # attribution addendums as found in the LICENSE.txt
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Affero General Public License for more details.
14
+
15
+ # Modified by OpenC3, Inc.
16
+ # All changes Copyright 2022, OpenC3, Inc.
17
+ # All Rights Reserved
18
+ #
19
+ # This file may also be used under the terms of a commercial license
20
+ # if purchased from OpenC3, Inc.
21
+ */
22
+
23
+ export class ConfigParserError {
24
+ constructor(config_parser, message, usage = '', url = '') {
25
+ this.keyword = config_parser.keyword
26
+ this.parameters = config_parser.parameters
27
+ this.filename = config_parser.filename
28
+ this.line = config_parser.line
29
+ this.lineNumber = config_parser.lineNumber
30
+ this.message = message
31
+ this.usage = usage
32
+ this.url = url
33
+ }
34
+ }
35
+
36
+ export class ConfigParserService {
37
+ keyword = null
38
+ parameters = []
39
+ filename = ''
40
+ line = ''
41
+ lineNumber = 0
42
+ url = 'https://openc3.com/docs/v5'
43
+
44
+ constructor() {}
45
+
46
+ verify_num_parameters(min_num_params, max_num_params, usage = '') {
47
+ // This syntax works with 0 because each doesn't return any values
48
+ // for a backwards range
49
+ for (let index = 1; index <= min_num_params; index++) {
50
+ // If the parameter is nil (0 based) then we have a problem
51
+ if (this.parameters[index - 1] === undefined) {
52
+ throw new ConfigParserError(
53
+ this,
54
+ `Not enough parameters for ${this.keyword}.`,
55
+ usage,
56
+ this.url
57
+ )
58
+ }
59
+ }
60
+ // If they pass null for max_params we don't check for a maximum number
61
+ if (max_num_params && !this.parameters[max_num_params] === undefined) {
62
+ throw new ConfigParserError(
63
+ this,
64
+ `Too many parameters for ${this.keyword}.`,
65
+ usage,
66
+ this.url
67
+ )
68
+ }
69
+ }
70
+
71
+ remove_quotes(string) {
72
+ if (string.length < 2) {
73
+ return string
74
+ }
75
+ let first_char = string.charAt(0)
76
+ if (first_char !== '"' && first_char !== "'") {
77
+ return string
78
+ }
79
+ let last_char = string.charAt(string.length - 1)
80
+ if (first_char !== last_char) {
81
+ return string
82
+ }
83
+ return string.substring(1, string.length - 1)
84
+ }
85
+
86
+ scan_string(string, rx) {
87
+ if (!rx.global) throw "rx must have 'global' flag set"
88
+ let r = []
89
+ string.replace(rx, function (match) {
90
+ r.push(match)
91
+ return match
92
+ })
93
+ return r
94
+ }
95
+
96
+ parse_string(
97
+ input_string,
98
+ original_filename,
99
+ yield_non_keyword_lines,
100
+ remove_quotes,
101
+ handler
102
+ ) {
103
+ let string_concat = false
104
+ this.line = ''
105
+ this.keyword = null
106
+ this.parameters = []
107
+ this.filename = original_filename
108
+
109
+ // Break string into lines
110
+ let lines = input_string.split('\n')
111
+ let numLines = lines.length
112
+
113
+ for (let i = 0; i < numLines; i++) {
114
+ this.lineNumber = i + 1
115
+ let line = lines[i].trim()
116
+ // Ensure the line length is not 0
117
+ if (line.length === 0) {
118
+ continue
119
+ }
120
+
121
+ if (string_concat === true) {
122
+ // Skip comment lines after a string concatenation
123
+ if (line[0] === '#') {
124
+ continue
125
+ }
126
+ // Remove the opening quote if we're continuing the line
127
+ line = line.substring(1, line.length)
128
+ }
129
+
130
+ // Check for string continuation
131
+ let last_char = line.charAt(line.length - 1)
132
+ let newline = false
133
+ switch (last_char) {
134
+ case '+': // String concatenation with newlines
135
+ newline = true
136
+ // Deliberate fall through
137
+ case '\\': // String concatenation
138
+ // Trim off the concat character plus any spaces, e.g. "line" \
139
+ let trim = line.substring(0, line.length - 1).trim()
140
+ // Now trim off the last quote so it will flow into the next line
141
+ this.line += trim.substring(0, trim.length - 1)
142
+ if (newline) {
143
+ this.line += '\n'
144
+ }
145
+ string_concat = true
146
+ continue
147
+ case '&': // Line continuation
148
+ this.line += line.substring(0, line.length - 1)
149
+ continue
150
+ default:
151
+ this.line += line
152
+ }
153
+ string_concat = false
154
+
155
+ let rx = /("([^\\"]|\\.)*")|('([^\\']|\\.)*')|\S+/g
156
+ let data = this.scan_string(this.line, rx)
157
+ let first_item = ''
158
+ if (data.length > 0) {
159
+ first_item = first_item + data[0]
160
+ }
161
+
162
+ if (first_item.length === 0 || first_item.charAt(0) === '#') {
163
+ this.keyword = null
164
+ } else {
165
+ this.keyword = first_item.toUpperCase()
166
+ }
167
+ this.parameters = []
168
+
169
+ // Ignore lines without keywords: comments and blank lines
170
+ if (this.keyword === null) {
171
+ if (yield_non_keyword_lines) {
172
+ handler(this.keyword, this.parameters, this.line, this.lineNumber)
173
+ }
174
+ this.line = ''
175
+ continue
176
+ }
177
+
178
+ let length = data.length
179
+ if (length > 1) {
180
+ for (let index = 1; index < length; index++) {
181
+ let string = data[index]
182
+
183
+ // Don't process trailing comments such as:
184
+ // KEYWORD PARAM #This is a comment
185
+ if (string.length > 0 && string.charAt(0) === '#') {
186
+ break
187
+ }
188
+ if (remove_quotes) {
189
+ this.parameters.push(this.remove_quotes(string))
190
+ } else {
191
+ this.parameters.push(string)
192
+ }
193
+ }
194
+ }
195
+ handler(this.keyword, this.parameters, this.line, this.lineNumber)
196
+ this.line = ''
197
+ } // for all the lines
198
+ } // parse_string
199
+ } // class ConfigParserService