openc3 6.10.4 → 6.10.6

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: e6cc1e03ca8cd4ac75025fc7cd4758099c513957b012291e7b332e8c61c513cf
4
- data.tar.gz: '058a71978241f50cc97a1ebefe70a7a6ecc69a9f1fb51e11690d50fd167ae60f'
3
+ metadata.gz: 82d3b0dd7139864979565d068d7ef9bb74839e8c120c361ef010e6ed2f85c39d
4
+ data.tar.gz: c90d9fb70c93f8e5409c85272012e014a1dd28850ca9d747960a84b18a22ee72
5
5
  SHA512:
6
- metadata.gz: a96529177ee05a9f04257e4668f245c7346692b039e000f970166fb311c80992401f19def70cbe63844510aa97b2a90ab89bafd835b377aecd14ef0505cb2feb
7
- data.tar.gz: 3a1c5152b36c733009daaefb07786087b428bbf172dd3ecbee2cfb4bb82de88c84ac0af727c25287cd4af5d1038812e1f4a3d2566c935cf0c519b984163013f5
6
+ metadata.gz: 675f0387d53e5530b6a2895173d14cc4ebb6d5e6c991ac94d4efcde3acfa11c1ba55c473f2d586f2a1fa4e285e1eb060c6bd9c292b0d7726b506689117ea1159
7
+ data.tar.gz: 9265cd85dc41188c5e4c1610e1d340c5b4e6a7a65e798a717dea4ec8f6e0e70de258d3aad76af36bb88b292646aed63ab449ab5a4321e124e57809a26a255ed6
@@ -1,6 +1,6 @@
1
1
  # encoding: ascii-8bit
2
2
 
3
- # Copyright 2023 OpenC3, Inc.
3
+ # Copyright 2026 OpenC3, Inc.
4
4
  # All Rights Reserved.
5
5
  #
6
6
  # This program is free software; you can modify and/or redistribute it
@@ -25,7 +25,7 @@ require 'openc3/accessors/accessor'
25
25
  OpenC3.disable_warnings do
26
26
  class JsonPath
27
27
  def self.process_object(obj_or_str, opts = {})
28
- obj_or_str.is_a?(String) ? MultiJson.load(obj_or_str, max_nesting: opts[:max_nesting], create_additions: true, allow_nan: true) : obj_or_str
28
+ obj_or_str.is_a?(String) ? JSON.parse(obj_or_str, max_nesting: opts[:max_nesting], create_additions: true, allow_nan: true) : obj_or_str
29
29
  end
30
30
  end
31
31
  end
@@ -58,6 +58,9 @@ module OpenC3
58
58
  return nil if item.data_type == :DERIVED
59
59
  configure()
60
60
 
61
+ # No template items to read (e.g. command with fixed template string)
62
+ return nil if @item_keys.empty?
63
+
61
64
  # Scan the response for all the variables in brackets <VARIABLE>
62
65
  values = buffer.scan(@read_regexp)[0]
63
66
  if !values || (values.length != @item_keys.length)
@@ -78,6 +81,12 @@ module OpenC3
78
81
  result = {}
79
82
  configure()
80
83
 
84
+ # No template items to read (e.g. command with fixed template string)
85
+ if @item_keys.empty?
86
+ items.each { |item| result[item.name] = nil }
87
+ return result
88
+ end
89
+
81
90
  # Scan the response for all the variables in brackets <VARIABLE>
82
91
  values = buffer.scan(@read_regexp)[0]
83
92
  if !values || (values.length != @item_keys.length)
@@ -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 2024, OpenC3, Inc.
17
+ # All changes Copyright 2026, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
20
  # This file may also be used under the terms of a commercial license
@@ -33,6 +33,11 @@ module OpenC3
33
33
 
34
34
  class ActivityModel < Model
35
35
  MAX_DURATION = Time::SEC_PER_DAY
36
+ # Grace window (in seconds) to allow creating activities slightly in the past.
37
+ # This handles race conditions where real-time activity notifications arrive
38
+ # after the start time has already passed (e.g. from external systems).
39
+ # This is consistent with the -15 second window in the timeline microservice.
40
+ START_GRACE_SECONDS = 15
36
41
  PRIMARY_KEY = '__openc3_timelines'.freeze # MUST be equal to `TimelineModel::PRIMARY_KEY` minus the leading __
37
42
  # See run_activity(activity) in openc3/lib/openc3/microservices/timeline_microservice.rb
38
43
  VALID_KINDS = %w(command script reserve expire)
@@ -217,7 +222,7 @@ module OpenC3
217
222
  end
218
223
 
219
224
  # validate the input to the rules we have created for timelines.
220
- # - A task's start MUST NOT be in the past.
225
+ # - A task's start MUST NOT be more than START_GRACE_SECONDS in the past.
221
226
  # - A task's start MUST be before the stop.
222
227
  # - A task CAN NOT be longer than MAX_DURATION (86400) in seconds.
223
228
  # - A task MUST have a kind.
@@ -235,8 +240,8 @@ module OpenC3
235
240
  rescue NoMethodError
236
241
  raise ActivityInputError.new "start and stop must be seconds: #{start}, #{stop}"
237
242
  end
238
- if now_f >= start and kind != 'expire'
239
- raise ActivityInputError.new "activity must be in the future, current_time: #{now_f} vs #{start}"
243
+ if now_f >= start + START_GRACE_SECONDS and kind != 'expire'
244
+ raise ActivityInputError.new "activity must not be more than #{START_GRACE_SECONDS} seconds in the past, current_time: #{now_f} vs #{start}"
240
245
  elsif duration > MAX_DURATION and kind != 'expire'
241
246
  raise ActivityInputError.new "activity can not be longer than #{MAX_DURATION} seconds"
242
247
  elsif duration <= 0
@@ -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 2024, OpenC3, Inc.
17
+ # All changes Copyright 2026, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
20
  # This file may also be used under the terms of a commercial license
@@ -81,6 +81,7 @@ module OpenC3
81
81
  raise "old_token incorrect" unless verify(old_token)
82
82
  end
83
83
  Store.set(key, hash(token))
84
+ logout()
84
85
  end
85
86
 
86
87
  def self.generate_session
@@ -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 2025, OpenC3, Inc.
17
+ # All changes Copyright 2026, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
20
  # This file may also be used under the terms of a commercial license
@@ -166,10 +166,14 @@ module OpenC3
166
166
  query += "ASOF JOIN #{table_name} as T#{index} "
167
167
  end
168
168
  end
169
+ query_params = []
169
170
  if start_time && !end_time
170
- query += "WHERE T0.timestamp < '#{start_time}' LIMIT -1"
171
+ query += "WHERE T0.PACKET_TIMESECONDS < $1 LIMIT -1"
172
+ query_params << start_time
171
173
  elsif start_time && end_time
172
- query += "WHERE T0.timestamp >= '#{start_time}' AND T0.timestamp < '#{end_time}'"
174
+ query += "WHERE T0.PACKET_TIMESECONDS >= $1 AND T0.PACKET_TIMESECONDS < $2"
175
+ query_params << start_time
176
+ query_params << end_time
173
177
  end
174
178
 
175
179
  retry_count = 0
@@ -187,7 +191,7 @@ module OpenC3
187
191
  @@conn.type_map_for_results = PG::BasicTypeMapForResults.new @@conn
188
192
  end
189
193
 
190
- result = @@conn.exec(query)
194
+ result = @@conn.exec_params(query, query_params)
191
195
  if result.nil? or result.ntuples == 0
192
196
  return {}
193
197
  else
@@ -24,6 +24,11 @@ require 'openc3/utilities/local_mode'
24
24
 
25
25
  module OpenC3
26
26
  class ToolConfigModel
27
+ class InvalidNameError < StandardError; end
28
+
29
+ # Allowlist: letters, digits, hyphens, underscores, spaces, and periods
30
+ VALID_NAME_PATTERN = /\A[A-Za-z0-9_\-. ]+\z/
31
+
27
32
  def self.config_tool_names(scope: $openc3_scope)
28
33
  _, keys = Store.scan(0, match: "#{scope}__config__*", type: 'hash', count: 100)
29
34
  # Just return the tool name that is used in the other APIs
@@ -31,19 +36,26 @@ module OpenC3
31
36
  end
32
37
 
33
38
  def self.list_configs(tool, scope: $openc3_scope)
39
+ raise InvalidNameError, "Invalid tool name: #{tool}" unless tool.match?(VALID_NAME_PATTERN)
34
40
  Store.hkeys("#{scope}__config__#{tool}")
35
41
  end
36
42
 
37
43
  def self.load_config(tool, name, scope: $openc3_scope)
44
+ raise InvalidNameError, "Invalid tool name: #{tool}" unless tool.match?(VALID_NAME_PATTERN)
45
+ raise InvalidNameError, "Invalid config name: #{name}" unless name.match?(VALID_NAME_PATTERN)
38
46
  Store.hget("#{scope}__config__#{tool}", name)
39
47
  end
40
48
 
41
49
  def self.save_config(tool, name, data, local_mode: true, scope: $openc3_scope)
50
+ raise InvalidNameError, "Invalid tool name: #{tool}" unless tool.match?(VALID_NAME_PATTERN)
51
+ raise InvalidNameError, "Invalid config name: #{name}" unless name.match?(VALID_NAME_PATTERN)
42
52
  Store.hset("#{scope}__config__#{tool}", name, data)
43
53
  LocalMode.save_tool_config(scope, tool, name, data) if local_mode
44
54
  end
45
55
 
46
56
  def self.delete_config(tool, name, local_mode: true, scope: $openc3_scope)
57
+ raise InvalidNameError, "Invalid tool name: #{tool}" unless tool.match?(VALID_NAME_PATTERN)
58
+ raise InvalidNameError, "Invalid config name: #{name}" unless name.match?(VALID_NAME_PATTERN)
47
59
  Store.hdel("#{scope}__config__#{tool}", name)
48
60
  LocalMode.delete_tool_config(scope, tool, name) if local_mode
49
61
  end
@@ -48,7 +48,11 @@ module OpenC3
48
48
  end
49
49
 
50
50
  def setup(secrets)
51
- secrets.each do |type, key, data, secret_store|
51
+ secrets.each do |secret|
52
+ if secret.length < 3
53
+ raise ArgumentError, "Secret must have at least 3 items (type, key, data), got #{secret.length}"
54
+ end
55
+ type, key, data, secret_store = secret
52
56
  case type
53
57
  when 'ENV'
54
58
  @local_secrets[key] = ENV[data]
@@ -1,14 +1,14 @@
1
1
  # encoding: ascii-8bit
2
2
 
3
- OPENC3_VERSION = '6.10.4'
3
+ OPENC3_VERSION = '6.10.6'
4
4
  module OpenC3
5
5
  module Version
6
6
  MAJOR = '6'
7
7
  MINOR = '10'
8
- PATCH = '4'
8
+ PATCH = '6'
9
9
  OTHER = ''
10
- BUILD = '3ec40189fe2728ada6e0be2dd347073fafed95aa'
10
+ BUILD = '097195648aacf31991bfca633879a013c6f3af26'
11
11
  end
12
- VERSION = '6.10.4'
13
- GEM_VERSION = '6.10.4'
12
+ VERSION = '6.10.6'
13
+ GEM_VERSION = '6.10.6'
14
14
  end
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "<%= tool_name %>",
3
- "version": "6.10.4",
3
+ "version": "6.10.6",
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.10.4",
26
+ "@openc3/js-common": "6.10.6",
27
27
  "rxjs": "~7.8.0",
28
28
  "single-spa": "^5.9.5",
29
29
  "single-spa-angular": "^9.2.0",
@@ -16,7 +16,7 @@
16
16
  "@emotion/react": "^11.13.3",
17
17
  "@emotion/styled": "^11.11.0",
18
18
  "@mui/material": "^6.1.1",
19
- "@openc3/js-common": "6.10.4",
19
+ "@openc3/js-common": "6.10.6",
20
20
  "react": "^18.2.0",
21
21
  "react-dom": "^18.2.0",
22
22
  "single-spa-react": "^5.1.4"
@@ -12,7 +12,7 @@
12
12
  },
13
13
  "dependencies": {
14
14
  "@astrouxds/astro-web-components": "^7.24.0",
15
- "@openc3/js-common": "6.10.4",
15
+ "@openc3/js-common": "6.10.6",
16
16
  "@smui/button": "^7.0.0",
17
17
  "@smui/common": "^7.0.0",
18
18
  "@smui/card": "^7.0.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "<%= tool_name %>",
3
- "version": "6.10.4",
3
+ "version": "6.10.6",
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.10.4",
15
- "@openc3/vue-common": "6.10.4",
14
+ "@openc3/js-common": "6.10.6",
15
+ "@openc3/vue-common": "6.10.6",
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.10.4",
3
+ "version": "6.10.6",
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.10.4",
11
+ "@openc3/vue-common": "6.10.6",
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.10.4
4
+ version: 6.10.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Melton