openc3 6.3.0 → 6.4.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 +4 -4
- data/bin/openc3cli +1 -11
- data/data/config/interface_modifiers.yaml +1 -1
- data/data/config/microservice.yaml +1 -1
- data/data/config/plugins.yaml +1 -1
- data/data/config/tool.yaml +1 -1
- data/ext/openc3/ext/burst_protocol/burst_protocol.c +5 -1
- data/lib/openc3/api/api.rb +7 -1
- data/lib/openc3/interfaces/file_interface.rb +36 -7
- data/lib/openc3/interfaces/protocols/burst_protocol.rb +3 -3
- data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +20 -26
- data/lib/openc3/interfaces.rb +4 -3
- data/lib/openc3/logs/log_writer.rb +11 -8
- data/lib/openc3/logs/packet_log_reader.rb +2 -2
- data/lib/openc3/logs/packet_log_writer.rb +1 -1
- data/lib/openc3/microservices/interface_microservice.rb +1 -1
- data/lib/openc3/microservices/microservice.rb +2 -1
- data/lib/openc3/models/model.rb +6 -2
- data/lib/openc3/models/script_status_model.rb +242 -0
- data/lib/openc3/script/api_shared.rb +4 -0
- data/lib/openc3/script/script_runner.rb +22 -7
- data/lib/openc3/utilities/authentication.rb +1 -1
- data/lib/openc3/utilities/cosmos_rails_formatter.rb +1 -1
- data/lib/openc3/utilities/message_log.rb +2 -0
- data/lib/openc3/utilities/metric.rb +1 -1
- data/lib/openc3/version.rb +5 -5
- data/templates/tool_angular/package.json +2 -2
- data/templates/tool_react/package.json +1 -1
- data/templates/tool_svelte/package.json +1 -1
- data/templates/tool_vue/eslint.config.mjs +17 -41
- data/templates/tool_vue/package.json +3 -3
- data/templates/widget/package.json +2 -2
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c408df49ec8cf1fbcf88e8c05207ac1c65274d56dbee94986c4f56308bc52b23
|
4
|
+
data.tar.gz: 8e8897d618e69898470fcd8a201ba968688fbe598c4ecb46d1a375da14282490
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c37180a0814a4ceb79b6503d52a83e10cba964351f07841db692e44bdb5a619f95b7a955283982f73218dc5f6670bef113654b917fc92ed99a9c71ff8e000e36
|
7
|
+
data.tar.gz: fa11395f5c24e207e6e6eb6f74b2b8f53c882222572f39cf7d6a6e95668dd99c5ad24015e832df937fb5f12800c92e3c7f55319716a46fc6a07cdbb99abc2e52
|
data/bin/openc3cli
CHANGED
@@ -592,28 +592,18 @@ def cli_script_monitor(script_id)
|
|
592
592
|
while (resp = api.read) do
|
593
593
|
# see ScriptRunner.vue for types and states
|
594
594
|
case resp['type']
|
595
|
-
when 'error', 'fatal'
|
596
|
-
$script_interrupt_text = ''
|
597
|
-
puts 'script failed'
|
598
|
-
break
|
599
595
|
when 'file'
|
600
596
|
puts "Filename #{resp['filename']} scope #{resp['scope']}"
|
601
597
|
when 'line'
|
602
598
|
fn = resp['filename'].nil? ? '<no file>' : resp['filename']
|
603
599
|
puts "At [#{fn}:#{resp['line_no']}] state [#{resp['state']}]"
|
604
|
-
if resp['state'] == 'error'
|
600
|
+
if resp['state'] == 'error' or resp['state'] == 'crashed'
|
605
601
|
$script_interrupt_text = ''
|
606
602
|
puts 'script failed'
|
607
603
|
break
|
608
604
|
end
|
609
605
|
when 'output'
|
610
606
|
puts resp['line']
|
611
|
-
when 'paused'
|
612
|
-
if resp['state'] == 'fatal'
|
613
|
-
$script_interrupt_text = ''
|
614
|
-
puts 'script failed'
|
615
|
-
break
|
616
|
-
end
|
617
607
|
when 'complete'
|
618
608
|
$script_interrupt_text = ''
|
619
609
|
puts 'script complete'
|
@@ -240,7 +240,7 @@ CMD:
|
|
240
240
|
python_example: CMD python interface_microservice.py DEFAULT__INTERFACE__INT1
|
241
241
|
CONTAINER:
|
242
242
|
summary: Docker Container
|
243
|
-
description: Container to execute and run the microservice in. Only used in COSMOS Enterprise
|
243
|
+
description: Container to execute and run the microservice in. Only used in COSMOS Enterprise.
|
244
244
|
since: 5.7.0
|
245
245
|
parameters:
|
246
246
|
- name: Args
|
@@ -107,7 +107,7 @@ MICROSERVICE:
|
|
107
107
|
values: .+
|
108
108
|
CONTAINER:
|
109
109
|
summary: Docker Container
|
110
|
-
description: Container to execute and run the microservice in. Only used in COSMOS Enterprise
|
110
|
+
description: Container to execute and run the microservice in. Only used in COSMOS Enterprise.
|
111
111
|
parameters:
|
112
112
|
- name: Args
|
113
113
|
required: false
|
data/data/config/plugins.yaml
CHANGED
@@ -16,7 +16,7 @@ VARIABLE:
|
|
16
16
|
NEEDS_DEPENDENCIES:
|
17
17
|
summary: Indicates the plugin needs dependencies and sets the GEM_HOME environment variable
|
18
18
|
description: If the plugin has a top level lib folder or lists runtime dependencies in the gemspec,
|
19
|
-
NEEDS_DEPENDENCIES is effectively already set. Note that in Enterprise
|
19
|
+
NEEDS_DEPENDENCIES is effectively already set. Note that in Enterprise, having
|
20
20
|
NEEDS_DEPENDENCIES adds the NFS volume mount to the Kubernetes pod.
|
21
21
|
since: 5.5.0
|
22
22
|
INTERFACE:
|
data/data/config/tool.yaml
CHANGED
@@ -66,7 +66,7 @@ TOOL:
|
|
66
66
|
description:
|
67
67
|
Position of the tool starting at 2 (1 is reserved for Admin Console).
|
68
68
|
Tools without a position are appended to the end as they are installed.
|
69
|
-
All COSMOS
|
69
|
+
All COSMOS Core tools have consecutive integer values for position.
|
70
70
|
since: 5.0.8
|
71
71
|
parameters:
|
72
72
|
- name: Position
|
@@ -81,7 +81,11 @@ static VALUE burst_protocol_read_data(int argc, VALUE *argv, VALUE self)
|
|
81
81
|
};
|
82
82
|
|
83
83
|
rb_str_concat(rb_ivar_get(self, id_ivar_data), data);
|
84
|
-
|
84
|
+
|
85
|
+
/* Maintain extra from last read read_data */
|
86
|
+
if (!((RSTRING_LEN(data) == 0) && (!(RTEST(extra))))) {
|
87
|
+
rb_ivar_set(self, id_ivar_extra, extra);
|
88
|
+
}
|
85
89
|
|
86
90
|
while (1)
|
87
91
|
{
|
data/lib/openc3/api/api.rb
CHANGED
@@ -14,7 +14,7 @@
|
|
14
14
|
# GNU Affero General Public License for more details.
|
15
15
|
|
16
16
|
# Modified by OpenC3, Inc.
|
17
|
-
# All changes Copyright
|
17
|
+
# All changes Copyright 2025, OpenC3, Inc.
|
18
18
|
# All Rights Reserved
|
19
19
|
#
|
20
20
|
# This file may also be used under the terms of a commercial license
|
@@ -35,6 +35,12 @@ require 'openc3/api/target_api'
|
|
35
35
|
require 'openc3/api/tlm_api'
|
36
36
|
require 'openc3/utilities/authorization'
|
37
37
|
require 'openc3/topics/topic'
|
38
|
+
begin
|
39
|
+
require 'openc3-enterprise/api/cmd_authority_api'
|
40
|
+
rescue LoadError
|
41
|
+
# LoadError expected for Open Source Edition
|
42
|
+
end
|
43
|
+
|
38
44
|
|
39
45
|
module OpenC3
|
40
46
|
module Api
|
@@ -18,12 +18,16 @@
|
|
18
18
|
|
19
19
|
require 'openc3/interfaces/interface'
|
20
20
|
require 'openc3/config/config_parser'
|
21
|
+
require 'openc3/utilities/logger'
|
21
22
|
require 'thread'
|
22
23
|
require 'listen'
|
23
24
|
require 'fileutils'
|
25
|
+
require 'zlib'
|
24
26
|
|
25
27
|
module OpenC3
|
26
28
|
class FileInterface < Interface
|
29
|
+
attr_reader :filename
|
30
|
+
|
27
31
|
# @param command_write_folder [String] Folder to write command files to - Set to nil to disallow writes
|
28
32
|
# @param telemetry_read_folder [String] Folder to read telemetry files from - Set to nil to disallow reads
|
29
33
|
# @param telemetry_archive_folder [String] Folder to move read telemetry files to - Set to DELETE to delete files
|
@@ -62,6 +66,7 @@ module OpenC3
|
|
62
66
|
@write_raw_allowed = false unless @command_write_folder
|
63
67
|
|
64
68
|
@file = nil
|
69
|
+
@filename = ''
|
65
70
|
@listener = nil
|
66
71
|
@connected = false
|
67
72
|
@extension = ".bin"
|
@@ -69,6 +74,9 @@ module OpenC3
|
|
69
74
|
@queue = Queue.new
|
70
75
|
@polling = false
|
71
76
|
@recursive = false
|
77
|
+
@throttle = nil
|
78
|
+
@discard_file_header_bytes = nil
|
79
|
+
@sleeper = nil
|
72
80
|
end
|
73
81
|
|
74
82
|
def connect
|
@@ -90,6 +98,7 @@ module OpenC3
|
|
90
98
|
def disconnect
|
91
99
|
@file.close if @file and not @file.closed?
|
92
100
|
@file = nil
|
101
|
+
@sleeper.cancel if @sleeper
|
93
102
|
@listener.stop if @listener
|
94
103
|
@listener = nil
|
95
104
|
@queue << nil
|
@@ -102,6 +111,10 @@ module OpenC3
|
|
102
111
|
if @file
|
103
112
|
# Read more data from existing file
|
104
113
|
data = @file.read(@file_read_size)
|
114
|
+
# Throttle after each read size
|
115
|
+
if @throttle and @sleeper.sleep(@throttle)
|
116
|
+
return nil, nil
|
117
|
+
end
|
105
118
|
if data and data.length > 0
|
106
119
|
read_interface_base(data, nil)
|
107
120
|
return data, nil
|
@@ -111,9 +124,16 @@ module OpenC3
|
|
111
124
|
end
|
112
125
|
|
113
126
|
# Find the next file to read
|
114
|
-
|
115
|
-
if
|
116
|
-
|
127
|
+
@filename = get_next_telemetry_file()
|
128
|
+
if @filename
|
129
|
+
if File.extname(@filename) == ".gz"
|
130
|
+
@file = Zlib::GzipReader.open(@filename)
|
131
|
+
else
|
132
|
+
@file = File.open(@filename, "rb")
|
133
|
+
end
|
134
|
+
if @discard_file_header_bytes
|
135
|
+
@file.read(@discard_file_header_bytes)
|
136
|
+
end
|
117
137
|
next
|
118
138
|
end
|
119
139
|
|
@@ -135,8 +155,8 @@ module OpenC3
|
|
135
155
|
|
136
156
|
def convert_data_to_packet(data, extra = nil)
|
137
157
|
packet = super(data, extra)
|
138
|
-
if packet
|
139
|
-
packet.stored =
|
158
|
+
if packet
|
159
|
+
packet.stored = @stored
|
140
160
|
end
|
141
161
|
return packet
|
142
162
|
end
|
@@ -156,6 +176,11 @@ module OpenC3
|
|
156
176
|
@polling = ConfigParser.handle_true_false(option_values[0])
|
157
177
|
when 'RECURSIVE'
|
158
178
|
@recursive = ConfigParser.handle_true_false(option_values[0])
|
179
|
+
when 'THROTTLE'
|
180
|
+
@throttle = Float(option_values[0])
|
181
|
+
@sleeper = Sleeper.new
|
182
|
+
when 'DISCARD_FILE_HEADER_BYTES'
|
183
|
+
@discard_file_header_bytes = Integer(option_values[0])
|
159
184
|
end
|
160
185
|
end
|
161
186
|
|
@@ -173,11 +198,15 @@ module OpenC3
|
|
173
198
|
end
|
174
199
|
|
175
200
|
def get_next_telemetry_file
|
201
|
+
files = []
|
176
202
|
if @recursive
|
177
|
-
|
203
|
+
files = Dir.glob("#{@telemetry_read_folder}/**/*")
|
178
204
|
else
|
179
|
-
|
205
|
+
files = Dir.glob("#{@telemetry_read_folder}/*")
|
180
206
|
end
|
207
|
+
# Dir.glob includes directories, so filter them out
|
208
|
+
files = files.sort.select { |fn| File.file?(fn) }
|
209
|
+
return files[0]
|
181
210
|
end
|
182
211
|
|
183
212
|
def create_unique_filename
|
@@ -14,7 +14,7 @@
|
|
14
14
|
# GNU Affero General Public License for more details.
|
15
15
|
|
16
16
|
# Modified by OpenC3, Inc.
|
17
|
-
# All changes Copyright
|
17
|
+
# All changes Copyright 2025, OpenC3, Inc.
|
18
18
|
# All Rights Reserved
|
19
19
|
#
|
20
20
|
# This file may also be used under the terms of a commercial license
|
@@ -37,7 +37,7 @@ module OpenC3
|
|
37
37
|
# @param fill_fields [Boolean] Fill any required fields when writing packets
|
38
38
|
# @param allow_empty_data [true/false/nil] See Protocol#initialize
|
39
39
|
def initialize(discard_leading_bytes = 0, sync_pattern = nil, fill_fields = false, allow_empty_data = nil)
|
40
|
-
super(allow_empty_data)
|
40
|
+
super(allow_empty_data) # Calls reset()
|
41
41
|
@discard_leading_bytes = discard_leading_bytes.to_i
|
42
42
|
@sync_pattern = ConfigParser.handle_nil(sync_pattern)
|
43
43
|
@sync_pattern = @sync_pattern.hex_to_byte_string if @sync_pattern
|
@@ -65,7 +65,7 @@ module OpenC3
|
|
65
65
|
# @return [String|nil] Data for a packet consisting of the bytes read
|
66
66
|
def read_data(data, extra = nil)
|
67
67
|
@data << data
|
68
|
-
@extra = extra
|
68
|
+
@extra = extra unless (data.length == 0 and extra.nil?) # Maintain extra from last read read_data
|
69
69
|
|
70
70
|
while true
|
71
71
|
control = handle_sync_pattern()
|
@@ -14,7 +14,7 @@
|
|
14
14
|
# GNU Affero General Public License for more details.
|
15
15
|
|
16
16
|
# Modified by OpenC3, Inc.
|
17
|
-
# All changes Copyright
|
17
|
+
# All changes Copyright 2025, OpenC3, Inc.
|
18
18
|
# All Rights Reserved
|
19
19
|
#
|
20
20
|
# This file may also be used under the terms of a commercial license
|
@@ -30,12 +30,12 @@ module OpenC3
|
|
30
30
|
|
31
31
|
# @param sync_pattern (see BurstProtocol#initialize)
|
32
32
|
# @param max_length [Integer] The maximum allowed value of the length field
|
33
|
+
# @param _unused [Integer] Legacy version number - unused
|
33
34
|
# @param allow_empty_data [true/false/nil] See Protocol#initialize
|
34
|
-
def initialize(sync_pattern = nil, max_length = nil,
|
35
|
+
def initialize(sync_pattern = nil, max_length = nil, _unused = nil, allow_empty_data = nil)
|
35
36
|
super(0, sync_pattern, false, allow_empty_data)
|
36
37
|
@max_length = ConfigParser.handle_nil(max_length)
|
37
38
|
@max_length = Integer(@max_length) if @max_length
|
38
|
-
@mode = Integer(mode)
|
39
39
|
end
|
40
40
|
|
41
41
|
def reset
|
@@ -47,13 +47,11 @@ module OpenC3
|
|
47
47
|
packet.received_time = @read_received_time
|
48
48
|
packet.target_name = @read_target_name
|
49
49
|
packet.packet_name = @read_packet_name
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
packet.extra = @read_extra
|
56
|
-
end
|
50
|
+
packet.stored = @read_stored
|
51
|
+
if packet.extra and @read_extra
|
52
|
+
packet.extra.merge(@read_extra)
|
53
|
+
else
|
54
|
+
packet.extra = @read_extra
|
57
55
|
end
|
58
56
|
return packet
|
59
57
|
end
|
@@ -67,14 +65,12 @@ module OpenC3
|
|
67
65
|
@write_target_name = 'UNKNOWN' unless @write_target_name
|
68
66
|
@write_packet_name = packet.packet_name
|
69
67
|
@write_packet_name = 'UNKNOWN' unless @write_packet_name
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
@write_extra = packet.extra.as_json(:allow_nan => true).to_json(:allow_nan => true)
|
77
|
-
end
|
68
|
+
@write_flags = 0
|
69
|
+
@write_flags |= COSMOS4_STORED_FLAG_MASK if packet.stored
|
70
|
+
@write_extra = nil
|
71
|
+
if packet.extra
|
72
|
+
@write_flags |= COSMOS4_EXTRA_FLAG_MASK
|
73
|
+
@write_extra = packet.extra.as_json(:allow_nan => true).to_json(:allow_nan => true)
|
78
74
|
end
|
79
75
|
return packet
|
80
76
|
end
|
@@ -83,12 +79,10 @@ module OpenC3
|
|
83
79
|
data_length = [data.length].pack('N') # UINT32
|
84
80
|
data_to_send = ''
|
85
81
|
data_to_send << @sync_pattern if @sync_pattern
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
data_to_send << @write_extra
|
91
|
-
end
|
82
|
+
data_to_send << @write_flags
|
83
|
+
if @write_extra
|
84
|
+
data_to_send << [@write_extra.length].pack('N')
|
85
|
+
data_to_send << @write_extra
|
92
86
|
end
|
93
87
|
data_to_send << @write_time_seconds
|
94
88
|
data_to_send << @write_time_microseconds
|
@@ -146,7 +140,7 @@ module OpenC3
|
|
146
140
|
@reduction_state = :SYNC_REMOVED
|
147
141
|
end
|
148
142
|
|
149
|
-
if @reduction_state == :SYNC_REMOVED
|
143
|
+
if @reduction_state == :SYNC_REMOVED
|
150
144
|
# Read and remove flags
|
151
145
|
return :STOP if @data.length < 1
|
152
146
|
|
@@ -171,7 +165,7 @@ module OpenC3
|
|
171
165
|
@reduction_state = :FLAGS_REMOVED
|
172
166
|
end
|
173
167
|
|
174
|
-
if @reduction_state == :FLAGS_REMOVED
|
168
|
+
if @reduction_state == :FLAGS_REMOVED
|
175
169
|
# Read and remove packet received time
|
176
170
|
return :STOP if @data.length < 8
|
177
171
|
|
data/lib/openc3/interfaces.rb
CHANGED
@@ -14,21 +14,22 @@
|
|
14
14
|
# GNU Affero General Public License for more details.
|
15
15
|
|
16
16
|
# Modified by OpenC3, Inc.
|
17
|
-
# All changes Copyright
|
17
|
+
# All changes Copyright 2025, OpenC3, Inc.
|
18
18
|
# All Rights Reserved
|
19
19
|
#
|
20
20
|
# This file may also be used under the terms of a commercial license
|
21
21
|
# if purchased from OpenC3, Inc.
|
22
22
|
|
23
23
|
module OpenC3
|
24
|
-
autoload(:
|
24
|
+
autoload(:FileInterface, 'openc3/interfaces/file_interface.rb')
|
25
25
|
autoload(:HttpClientInterface, 'openc3/interfaces/http_client_interface.rb')
|
26
26
|
autoload(:HttpServerInterface, 'openc3/interfaces/http_server_interface.rb')
|
27
|
+
autoload(:Interface, 'openc3/interfaces/interface.rb')
|
27
28
|
autoload(:MqttInterface, 'openc3/interfaces/mqtt_interface.rb')
|
28
29
|
autoload(:MqttStreamInterface, 'openc3/interfaces/mqtt_stream_interface.rb')
|
29
|
-
autoload(:StreamInterface, 'openc3/interfaces/stream_interface.rb')
|
30
30
|
autoload(:SerialInterface, 'openc3/interfaces/serial_interface.rb')
|
31
31
|
autoload(:SimulatedTargetInterface, 'openc3/interfaces/simulated_target_interface.rb')
|
32
|
+
autoload(:StreamInterface, 'openc3/interfaces/stream_interface.rb')
|
32
33
|
autoload(:TcpipClientInterface, 'openc3/interfaces/tcpip_client_interface.rb')
|
33
34
|
autoload(:TcpipServerInterface, 'openc3/interfaces/tcpip_server_interface.rb')
|
34
35
|
autoload(:UdpInterface, 'openc3/interfaces/udp_interface.rb')
|
@@ -14,7 +14,7 @@
|
|
14
14
|
# GNU Affero General Public License for more details.
|
15
15
|
|
16
16
|
# Modified by OpenC3, Inc.
|
17
|
-
# All changes Copyright
|
17
|
+
# All changes Copyright 2025, OpenC3, Inc.
|
18
18
|
# All Rights Reserved
|
19
19
|
#
|
20
20
|
# This file may also be used under the terms of a commercial license
|
@@ -100,7 +100,8 @@ module OpenC3
|
|
100
100
|
cycle_size = 1_000_000_000,
|
101
101
|
cycle_hour = nil,
|
102
102
|
cycle_minute = nil,
|
103
|
-
enforce_time_order = true
|
103
|
+
enforce_time_order = true,
|
104
|
+
cycle_thread: true
|
104
105
|
)
|
105
106
|
@remote_log_directory = remote_log_directory
|
106
107
|
@logging_enabled = ConfigParser.handle_true_false(logging_enabled)
|
@@ -135,13 +136,15 @@ module OpenC3
|
|
135
136
|
# each time we create an entry which we do a LOT!
|
136
137
|
@entry = String.new
|
137
138
|
|
138
|
-
|
139
|
-
|
140
|
-
@@
|
139
|
+
if cycle_thread
|
140
|
+
# Always make sure there is a cycle thread - (because it does trimming)
|
141
|
+
@@mutex.synchronize do
|
142
|
+
@@instances << self
|
141
143
|
|
142
|
-
|
143
|
-
|
144
|
-
|
144
|
+
unless @@cycle_thread
|
145
|
+
@@cycle_thread = OpenC3.safe_thread("Log cycle") do
|
146
|
+
cycle_thread_body()
|
147
|
+
end
|
145
148
|
end
|
146
149
|
end
|
147
150
|
end
|
@@ -14,7 +14,7 @@
|
|
14
14
|
# GNU Affero General Public License for more details.
|
15
15
|
|
16
16
|
# Modified by OpenC3, Inc.
|
17
|
-
# All changes Copyright
|
17
|
+
# All changes Copyright 2025, OpenC3, Inc.
|
18
18
|
# All Rights Reserved
|
19
19
|
#
|
20
20
|
# This file may also be used under the terms of a commercial license
|
@@ -309,7 +309,7 @@ module OpenC3
|
|
309
309
|
if cbor
|
310
310
|
extra = CBOR.decode(extra_encoded)
|
311
311
|
else
|
312
|
-
extra = JSON.parse(
|
312
|
+
extra = JSON.parse(extra_encoded, allow_nan: true, create_additions: true)
|
313
313
|
end
|
314
314
|
end
|
315
315
|
data = entry[next_offset..-1]
|
@@ -14,7 +14,7 @@
|
|
14
14
|
# GNU Affero General Public License for more details.
|
15
15
|
|
16
16
|
# Modified by OpenC3, Inc.
|
17
|
-
# All changes Copyright
|
17
|
+
# All changes Copyright 2025, OpenC3, Inc.
|
18
18
|
# All Rights Reserved
|
19
19
|
#
|
20
20
|
# This file may also be used under the terms of a commercial license
|
@@ -208,9 +208,10 @@ module OpenC3
|
|
208
208
|
shutdown()
|
209
209
|
end
|
210
210
|
|
211
|
-
def shutdown
|
211
|
+
def shutdown(state = 'STOPPED')
|
212
212
|
return if @shutdown_complete
|
213
213
|
@logger.info("Shutting down microservice: #{@name}")
|
214
|
+
@state = state
|
214
215
|
@cancel_thread = true
|
215
216
|
@microservice_status_sleeper.cancel if @microservice_status_sleeper
|
216
217
|
MicroserviceStatusModel.set(as_json(:allow_nan => true), scope: @scope)
|
data/lib/openc3/models/model.rb
CHANGED
@@ -139,7 +139,7 @@ module OpenC3
|
|
139
139
|
|
140
140
|
# Update the Redis hash at primary_key and set the field "name"
|
141
141
|
# to the JSON generated via calling as_json
|
142
|
-
def create(update: false, force: false, queued: false)
|
142
|
+
def create(update: false, force: false, queued: false, isoformat: false)
|
143
143
|
unless force
|
144
144
|
existing = self.class.store.hget(@primary_key, @name)
|
145
145
|
if existing
|
@@ -148,7 +148,11 @@ module OpenC3
|
|
148
148
|
raise "#{@primary_key}:#{@name} doesn't exist at update" if update
|
149
149
|
end
|
150
150
|
end
|
151
|
-
|
151
|
+
if isoformat
|
152
|
+
@updated_at = Time.now.utc.iso8601
|
153
|
+
else
|
154
|
+
@updated_at = Time.now.utc.to_nsec_from_epoch
|
155
|
+
end
|
152
156
|
|
153
157
|
if queued
|
154
158
|
write_store = self.class.store_queued
|
@@ -0,0 +1,242 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
|
3
|
+
# Copyright 2025 OpenC3, Inc.
|
4
|
+
# All Rights Reserved.
|
5
|
+
#
|
6
|
+
# This program is free software; you can modify and/or redistribute it
|
7
|
+
# under the terms of the GNU Affero General Public License
|
8
|
+
# as published by the Free Software Foundation; version 3 with
|
9
|
+
# attribution addendums as found in the LICENSE.txt
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# This file may also be used under the terms of a commercial license
|
17
|
+
# if purchased from OpenC3, Inc.
|
18
|
+
|
19
|
+
require 'openc3/models/model'
|
20
|
+
|
21
|
+
module OpenC3
|
22
|
+
class ScriptStatusModel < Model
|
23
|
+
# Note: ScriptRunner only has permissions for keys that start with running-script
|
24
|
+
RUNNING_PRIMARY_KEY = 'running-script'
|
25
|
+
COMPLETED_PRIMARY_KEY = 'running-script-completed'
|
26
|
+
|
27
|
+
def id
|
28
|
+
return @name
|
29
|
+
end
|
30
|
+
attr_reader :state # spawning, init, running, paused, waiting, breakpoint, error, crashed, stopped, completed, completed_errors, killed
|
31
|
+
attr_accessor :shard
|
32
|
+
attr_accessor :filename
|
33
|
+
attr_accessor :current_filename
|
34
|
+
attr_accessor :line_no
|
35
|
+
attr_accessor :start_line_no
|
36
|
+
attr_accessor :end_line_no
|
37
|
+
attr_accessor :username
|
38
|
+
attr_accessor :user_full_name
|
39
|
+
attr_accessor :start_time
|
40
|
+
attr_accessor :end_time
|
41
|
+
attr_accessor :disconnect
|
42
|
+
attr_accessor :environment
|
43
|
+
attr_accessor :suite_runner
|
44
|
+
attr_accessor :errors
|
45
|
+
attr_accessor :pid
|
46
|
+
attr_accessor :log
|
47
|
+
attr_accessor :report
|
48
|
+
|
49
|
+
# NOTE: The following three class methods are used by the ModelController
|
50
|
+
# and are reimplemented to enable various Model class methods to work
|
51
|
+
def self.get(name:, scope:, type: "auto")
|
52
|
+
if type == "auto" or type == "running"
|
53
|
+
# Check for running first
|
54
|
+
running = super("#{RUNNING_PRIMARY_KEY}__#{scope}", name: name)
|
55
|
+
return running if running
|
56
|
+
end
|
57
|
+
return super("#{COMPLETED_PRIMARY_KEY}__#{scope}", name: name)
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.names(scope:, type: "running")
|
61
|
+
if type == "running"
|
62
|
+
return super("#{RUNNING_PRIMARY_KEY}__#{scope}")
|
63
|
+
else
|
64
|
+
return super("#{COMPLETED_PRIMARY_KEY}__#{scope}")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.all(scope:, offset: 0, limit: 10, type: "running")
|
69
|
+
if type == "running"
|
70
|
+
keys = self.store.zrevrange("#{RUNNING_PRIMARY_KEY}__#{scope}__LIST", offset.to_i, offset.to_i + limit.to_i - 1)
|
71
|
+
return [] if keys.empty?
|
72
|
+
result = self.store.redis_pool.pipelined do
|
73
|
+
keys.each do |key|
|
74
|
+
self.store.hget("#{RUNNING_PRIMARY_KEY}__#{scope}", key)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
result = result.map do |r|
|
78
|
+
if r.nil?
|
79
|
+
nil
|
80
|
+
else
|
81
|
+
JSON.parse(r, :allow_nan => true, :create_additions => true)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
return result
|
85
|
+
else
|
86
|
+
keys = self.store.zrevrange("#{COMPLETED_PRIMARY_KEY}__#{scope}__LIST", offset.to_i, offset.to_i + limit.to_i - 1)
|
87
|
+
return [] if keys.empty?
|
88
|
+
result = self.store.redis_pool.pipelined do
|
89
|
+
keys.each do |key|
|
90
|
+
self.store.hget("#{COMPLETED_PRIMARY_KEY}__#{scope}", key)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
result = result.map do |r|
|
94
|
+
if r.nil?
|
95
|
+
nil
|
96
|
+
else
|
97
|
+
JSON.parse(r, :allow_nan => true, :create_additions => true)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
return result
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.count(scope:, type: "running")
|
105
|
+
if type == "running"
|
106
|
+
return self.store.zcount("#{RUNNING_PRIMARY_KEY}__#{scope}__LIST", 0, Float::INFINITY)
|
107
|
+
else
|
108
|
+
return self.store.zcount("#{COMPLETED_PRIMARY_KEY}__#{scope}__LIST", 0, Float::INFINITY)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def initialize(
|
113
|
+
name:, # id
|
114
|
+
state:, # spawning, init, running, paused, waiting, error, breakpoint, crashed, stopped, completed, completed_errors, killed
|
115
|
+
shard: 0, # Future enhancement of script runner shards
|
116
|
+
filename:, # The initial filename
|
117
|
+
current_filename: nil, # The current filename
|
118
|
+
line_no: 0, # The current line number
|
119
|
+
start_line_no: 1, # The line number to start the script at
|
120
|
+
end_line_no: nil, # The line number to end the script at
|
121
|
+
username:, # The username of the person who started the script
|
122
|
+
user_full_name:, # The full name of the person who started the script
|
123
|
+
start_time:, # The time the script started ISO format
|
124
|
+
end_time: nil, # The time the script ended ISO format
|
125
|
+
disconnect: false,
|
126
|
+
environment: nil,
|
127
|
+
suite_runner: nil,
|
128
|
+
errors: nil,
|
129
|
+
pid: nil,
|
130
|
+
log: nil,
|
131
|
+
report: nil,
|
132
|
+
updated_at: nil,
|
133
|
+
scope:
|
134
|
+
)
|
135
|
+
@state = state
|
136
|
+
if is_complete?()
|
137
|
+
super("#{COMPLETED_PRIMARY_KEY}__#{scope}", name: name, updated_at: updated_at, plugin: nil, scope: scope)
|
138
|
+
else
|
139
|
+
super("#{RUNNING_PRIMARY_KEY}__#{scope}", name: name, updated_at: updated_at, plugin: nil, scope: scope)
|
140
|
+
end
|
141
|
+
@shard = shard.to_i
|
142
|
+
@filename = filename
|
143
|
+
@current_filename = current_filename
|
144
|
+
@line_no = line_no
|
145
|
+
@start_line_no = start_line_no
|
146
|
+
@end_line_no = end_line_no
|
147
|
+
@username = username
|
148
|
+
@user_full_name = user_full_name
|
149
|
+
@start_time = start_time
|
150
|
+
@end_time = end_time
|
151
|
+
@disconnect = disconnect
|
152
|
+
@environment = environment
|
153
|
+
@suite_runner = suite_runner
|
154
|
+
@errors = errors
|
155
|
+
@pid = pid
|
156
|
+
@log = log
|
157
|
+
@report = report
|
158
|
+
end
|
159
|
+
|
160
|
+
def is_complete?
|
161
|
+
return (@state == 'completed' or @state == 'completed_errors' or @state == 'stopped' or @state == 'crashed' or @state == 'killed')
|
162
|
+
end
|
163
|
+
|
164
|
+
def state=(new_state)
|
165
|
+
# If the state is already a flavor of complete, leave it alone (first wins)
|
166
|
+
if not is_complete?()
|
167
|
+
@state = new_state
|
168
|
+
# If setting to complete, check for errors
|
169
|
+
# and set the state to complete_errors if they exist
|
170
|
+
if @state == 'completed' and @errors
|
171
|
+
@state = 'completed_errors'
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# Update the Redis hash at primary_key and set the field "name"
|
177
|
+
# to the JSON generated via calling as_json
|
178
|
+
def create(update: false, force: false, queued: false, isoformat: true)
|
179
|
+
@updated_at = Time.now.utc.to_nsec_from_epoch
|
180
|
+
|
181
|
+
if queued
|
182
|
+
write_store = self.class.store_queued
|
183
|
+
else
|
184
|
+
write_store = self.class.store
|
185
|
+
end
|
186
|
+
write_store.hset(@primary_key, @name, JSON.generate(self.as_json(:allow_nan => true), :allow_nan => true))
|
187
|
+
|
188
|
+
# Also add to ordered set on create
|
189
|
+
write_store.zadd(@primary_key + "__LIST", @name.to_i, @name) if not update
|
190
|
+
end
|
191
|
+
|
192
|
+
def update(force: false, queued: false)
|
193
|
+
# Magically handle the change from running to completed
|
194
|
+
if is_complete?() and @primary_key == "#{RUNNING_PRIMARY_KEY}__#{@scope}"
|
195
|
+
# Destroy the running key
|
196
|
+
destroy()
|
197
|
+
@destroyed = false
|
198
|
+
|
199
|
+
# Move to completed
|
200
|
+
@primary_key = "#{COMPLETED_PRIMARY_KEY}__#{@scope}"
|
201
|
+
create(update: false, force: force, queued: queued, isoformat: true)
|
202
|
+
else
|
203
|
+
create(update: true, force: force, queued: queued, isoformat: true)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
# Delete the model from the Store
|
208
|
+
def destroy
|
209
|
+
@destroyed = true
|
210
|
+
undeploy()
|
211
|
+
self.class.store.hdel(@primary_key, @name)
|
212
|
+
# Also remove from ordered set
|
213
|
+
self.class.store.zremrangebyscore(@primary_key + "__LIST", @name.to_i, @name.to_i)
|
214
|
+
end
|
215
|
+
|
216
|
+
def as_json(*a)
|
217
|
+
{
|
218
|
+
'name' => @name,
|
219
|
+
'state' => @state,
|
220
|
+
'shard' => @shard,
|
221
|
+
'filename' => @filename,
|
222
|
+
'current_filename' => @current_filename,
|
223
|
+
'line_no' => @line_no,
|
224
|
+
'start_line_no' => @start_line_no,
|
225
|
+
'end_line_no' => @end_line_no,
|
226
|
+
'username' => @username,
|
227
|
+
'user_full_name' => @user_full_name,
|
228
|
+
'start_time' => @start_time,
|
229
|
+
'end_time' => @end_time,
|
230
|
+
'disconnect' => @disconnect,
|
231
|
+
'environment' => @environment,
|
232
|
+
'suite_runner' => @suite_runner,
|
233
|
+
'errors' => @errors,
|
234
|
+
'pid' => @pid,
|
235
|
+
'log' => @log,
|
236
|
+
'report' => @report,
|
237
|
+
'updated_at' => @updated_at,
|
238
|
+
'scope' => @scope
|
239
|
+
}
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
@@ -503,6 +503,10 @@ module OpenC3
|
|
503
503
|
!cached
|
504
504
|
end
|
505
505
|
|
506
|
+
def goto(line_no_or_procedure_name, line_no = nil)
|
507
|
+
raise "goto is not supported outside of ScriptRunner"
|
508
|
+
end
|
509
|
+
|
506
510
|
# Require an additional ruby file
|
507
511
|
def load_utility(procedure_name)
|
508
512
|
return start(procedure_name)
|
@@ -167,17 +167,17 @@ module OpenC3
|
|
167
167
|
end
|
168
168
|
end
|
169
169
|
|
170
|
-
def running_script_list(scope: $openc3_scope)
|
170
|
+
def running_script_list(limit: 10, offset: 0, scope: $openc3_scope)
|
171
171
|
endpoint = "/script-api/running-script"
|
172
|
-
response = $script_runner_api_server.request('get', endpoint, scope: scope)
|
172
|
+
response = $script_runner_api_server.request('get', endpoint, query: {"limit" => limit, "offset" => offset}, scope: scope)
|
173
173
|
if response.nil? || response.status != 200
|
174
174
|
_script_response_error(response, "Running script list request failed", scope: scope)
|
175
175
|
else
|
176
|
-
return JSON.parse(response.body, :allow_nan => true, :create_additions => true)
|
176
|
+
return JSON.parse(response.body, :allow_nan => true, :create_additions => true)['items']
|
177
177
|
end
|
178
178
|
end
|
179
179
|
|
180
|
-
def
|
180
|
+
def script_get(id, scope: $openc3_scope)
|
181
181
|
endpoint = "/script-api/running-script/#{id}"
|
182
182
|
response = $script_runner_api_server.request('get', endpoint, scope: scope)
|
183
183
|
if response.nil? || response.status != 200
|
@@ -186,6 +186,7 @@ module OpenC3
|
|
186
186
|
return JSON.parse(response.body, :allow_nan => true, :create_additions => true)
|
187
187
|
end
|
188
188
|
end
|
189
|
+
alias running_script_get script_get # Deprecated alias for compatibility
|
189
190
|
|
190
191
|
def _running_script_action(id, action_name, scope: $openc3_scope)
|
191
192
|
endpoint = "/script-api/running-script/#{id}/#{action_name}"
|
@@ -249,13 +250,27 @@ module OpenC3
|
|
249
250
|
end
|
250
251
|
end
|
251
252
|
|
252
|
-
def
|
253
|
+
def running_script_execute_while_paused(id, filename, line_no, end_line_no = nil, scope: $openc3_scope)
|
254
|
+
endpoint = "/script-api/running-script/#{id}/executewhilepaused"
|
255
|
+
if end_line_no
|
256
|
+
response = $script_runner_api_server.request('post', endpoint, json: true, data: {'args' => [filename, line_no, end_line_no]}, scope: scope)
|
257
|
+
else
|
258
|
+
response = $script_runner_api_server.request('post', endpoint, json: true, data: {'args' => [filename, line_no]}, scope: scope)
|
259
|
+
end
|
260
|
+
if response.nil? || response.status != 200
|
261
|
+
_script_response_error(response, "Running script executewhilepaused request failed", scope: scope)
|
262
|
+
else
|
263
|
+
return true
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
def completed_script_list(limit: 10, offset: 0, scope: $openc3_scope)
|
253
268
|
endpoint = "/script-api/completed-scripts"
|
254
|
-
response = $script_runner_api_server.request('get', endpoint, scope: scope)
|
269
|
+
response = $script_runner_api_server.request('get', endpoint, query: {"limit" => limit, "offset" => offset}, scope: scope)
|
255
270
|
if response.nil? || response.status != 200
|
256
271
|
_script_response_error(response, "Completed script list request failed", scope: scope)
|
257
272
|
else
|
258
|
-
return JSON.parse(response.body, :allow_nan => true, :create_additions => true)
|
273
|
+
return JSON.parse(response.body, :allow_nan => true, :create_additions => true)['items']
|
259
274
|
end
|
260
275
|
end
|
261
276
|
end
|
@@ -29,7 +29,7 @@ module OpenC3
|
|
29
29
|
class OpenC3AuthenticationError < StandardError; end
|
30
30
|
class OpenC3AuthenticationRetryableError < OpenC3AuthenticationError; end
|
31
31
|
|
32
|
-
# OpenC3
|
32
|
+
# OpenC3 COSMOS Core authentication code
|
33
33
|
class OpenC3Authentication
|
34
34
|
def initialize()
|
35
35
|
@token = ENV['OPENC3_API_PASSWORD']
|
@@ -64,6 +64,7 @@ module OpenC3
|
|
64
64
|
|
65
65
|
# Closes the message log and marks it read only
|
66
66
|
def stop(take_mutex = true, metadata: {})
|
67
|
+
bucket_key = nil
|
67
68
|
@mutex.lock if take_mutex
|
68
69
|
if @file and not @file.closed?
|
69
70
|
@file.close
|
@@ -77,6 +78,7 @@ module OpenC3
|
|
77
78
|
end
|
78
79
|
end
|
79
80
|
@mutex.unlock if take_mutex
|
81
|
+
return bucket_key
|
80
82
|
end
|
81
83
|
|
82
84
|
# Creates a new message log and sets the filename
|
data/lib/openc3/version.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
# encoding: ascii-8bit
|
2
2
|
|
3
|
-
OPENC3_VERSION = '6.
|
3
|
+
OPENC3_VERSION = '6.4.0'
|
4
4
|
module OpenC3
|
5
5
|
module Version
|
6
6
|
MAJOR = '6'
|
7
|
-
MINOR = '
|
7
|
+
MINOR = '4'
|
8
8
|
PATCH = '0'
|
9
9
|
OTHER = ''
|
10
|
-
BUILD = '
|
10
|
+
BUILD = '7f674e6c8a5d1e77fc64182365b831a17751b78d'
|
11
11
|
end
|
12
|
-
VERSION = '6.
|
13
|
-
GEM_VERSION = '6.
|
12
|
+
VERSION = '6.4.0'
|
13
|
+
GEM_VERSION = '6.4.0'
|
14
14
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "<%= tool_name %>",
|
3
|
-
"version": "6.
|
3
|
+
"version": "6.4.0",
|
4
4
|
"scripts": {
|
5
5
|
"ng": "ng",
|
6
6
|
"start": "ng serve",
|
@@ -23,7 +23,7 @@
|
|
23
23
|
"@angular/platform-browser-dynamic": "^18.2.6",
|
24
24
|
"@angular/router": "^18.2.6",
|
25
25
|
"@astrouxds/astro-web-components": "^7.24.0",
|
26
|
-
"@openc3/js-common": "6.
|
26
|
+
"@openc3/js-common": "6.4.0",
|
27
27
|
"rxjs": "~7.8.0",
|
28
28
|
"single-spa": "^5.9.5",
|
29
29
|
"single-spa-angular": "^9.2.0",
|
@@ -1,30 +1,11 @@
|
|
1
|
-
import
|
2
|
-
import
|
3
|
-
import
|
4
|
-
import
|
5
|
-
import { fileURLToPath } from 'node:url'
|
6
|
-
import js from '@eslint/js'
|
7
|
-
import { FlatCompat } from '@eslint/eslintrc'
|
8
|
-
|
9
|
-
const __filename = fileURLToPath(import.meta.url)
|
10
|
-
const __dirname = path.dirname(__filename)
|
11
|
-
const compat = new FlatCompat({
|
12
|
-
baseDirectory: __dirname,
|
13
|
-
recommendedConfig: js.configs.recommended,
|
14
|
-
allConfig: js.configs.all,
|
15
|
-
})
|
1
|
+
import prettierConfig from "@vue/eslint-config-prettier"
|
2
|
+
import pluginVue from "eslint-plugin-vue"
|
3
|
+
import globals from "globals"
|
4
|
+
import parser from "vue-eslint-parser"
|
16
5
|
|
17
6
|
export default [
|
18
|
-
...
|
19
|
-
'plugin:vue/vue3-essential',
|
20
|
-
'plugin:prettier/recommended',
|
21
|
-
'@vue/prettier',
|
22
|
-
),
|
7
|
+
...pluginVue.configs['flat/recommended'],
|
23
8
|
{
|
24
|
-
plugins: {
|
25
|
-
prettier,
|
26
|
-
},
|
27
|
-
|
28
9
|
languageOptions: {
|
29
10
|
globals: {
|
30
11
|
...globals.node,
|
@@ -32,32 +13,26 @@ export default [
|
|
32
13
|
|
33
14
|
parser: parser,
|
34
15
|
ecmaVersion: 2022,
|
35
|
-
sourceType:
|
16
|
+
sourceType: "module",
|
36
17
|
},
|
37
18
|
|
38
19
|
rules: {
|
39
|
-
|
40
|
-
|
20
|
+
"no-console": "error",
|
21
|
+
"no-debugger": "error",
|
41
22
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
endOfLine: 'auto',
|
46
|
-
},
|
47
|
-
],
|
23
|
+
"prettier/prettier": ["warn", {
|
24
|
+
endOfLine: "auto",
|
25
|
+
}],
|
48
26
|
|
49
|
-
|
27
|
+
"vue/multi-word-component-names": "off",
|
50
28
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
allowModifiers: true,
|
55
|
-
},
|
56
|
-
],
|
29
|
+
"vue/valid-v-slot": ["error", {
|
30
|
+
allowModifiers: true,
|
31
|
+
}],
|
57
32
|
},
|
58
33
|
},
|
59
34
|
{
|
60
|
-
files: [
|
35
|
+
files: ["**/__tests__/*.{j,t}s?(x)", "**/tests/unit/**/*.spec.{j,t}s?(x)"],
|
61
36
|
|
62
37
|
languageOptions: {
|
63
38
|
globals: {
|
@@ -65,4 +40,5 @@ export default [
|
|
65
40
|
},
|
66
41
|
},
|
67
42
|
},
|
43
|
+
prettierConfig,
|
68
44
|
]
|
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "<%= tool_name %>",
|
3
|
-
"version": "6.
|
3
|
+
"version": "6.4.0",
|
4
4
|
"private": true,
|
5
5
|
"type": "module",
|
6
6
|
"scripts": {
|
@@ -11,8 +11,8 @@
|
|
11
11
|
},
|
12
12
|
"dependencies": {
|
13
13
|
"@astrouxds/astro-web-components": "^7.24.0",
|
14
|
-
"@openc3/js-common": "6.
|
15
|
-
"@openc3/vue-common": "6.
|
14
|
+
"@openc3/js-common": "6.4.0",
|
15
|
+
"@openc3/vue-common": "6.4.0",
|
16
16
|
"axios": "^1.7.7",
|
17
17
|
"date-fns": "^4.1.0",
|
18
18
|
"lodash": "^4.17.21",
|
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "<%= widget_name %>",
|
3
|
-
"version": "6.
|
3
|
+
"version": "6.4.0",
|
4
4
|
"private": true,
|
5
5
|
"type": "module",
|
6
6
|
"scripts": {
|
@@ -8,7 +8,7 @@
|
|
8
8
|
},
|
9
9
|
"dependencies": {
|
10
10
|
"@astrouxds/astro-web-components": "^7.24.0",
|
11
|
-
"@openc3/vue-common": "6.
|
11
|
+
"@openc3/vue-common": "6.4.0",
|
12
12
|
"vuetify": "^3.7.1"
|
13
13
|
},
|
14
14
|
"devDependencies": {
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openc3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.
|
4
|
+
version: 6.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Melton
|
@@ -86,14 +86,14 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 1.3
|
89
|
+
version: '1.3'
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 1.3
|
96
|
+
version: '1.3'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: psych
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -1033,6 +1033,7 @@ files:
|
|
1033
1033
|
- lib/openc3/models/router_model.rb
|
1034
1034
|
- lib/openc3/models/router_status_model.rb
|
1035
1035
|
- lib/openc3/models/scope_model.rb
|
1036
|
+
- lib/openc3/models/script_status_model.rb
|
1036
1037
|
- lib/openc3/models/secret_model.rb
|
1037
1038
|
- lib/openc3/models/setting_model.rb
|
1038
1039
|
- lib/openc3/models/sorted_model.rb
|
@@ -1284,7 +1285,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
1284
1285
|
- !ruby/object:Gem::Version
|
1285
1286
|
version: '0'
|
1286
1287
|
requirements: []
|
1287
|
-
rubygems_version: 3.6.
|
1288
|
+
rubygems_version: 3.6.8
|
1288
1289
|
specification_version: 4
|
1289
1290
|
summary: OpenC3
|
1290
1291
|
test_files: []
|