quickjs 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ecc8aa4eddd6aca97baf0e773c4880b4479b4ac4597e0edf811d256eeb61aeb9
4
- data.tar.gz: 37c8eeef2cad6e0d7773e89759c7d2d1659219247883cfd1817f2603ffbf1543
3
+ metadata.gz: c3241377c00ffedb82e1752917d2a3bd6ac1fb667eebc30eb16b153c83119103
4
+ data.tar.gz: adc59082d4d1eb6cfbe662b88d3cbbee6deeb933c623964ccb139f1ae5b238c8
5
5
  SHA512:
6
- metadata.gz: 2728bcbae59fae1138bdb5aef4e2f22290db93ce6c1e81f031e25c43108287a4f4d93d20afcfd9cb19a0e55593e1ccdadf1d83ebfbb430ee802368b73994cc2b
7
- data.tar.gz: d06939ece851f9f4fb1311846826cad5c92e594511948ac9659bb190ebe6f905fdce15b4b9d16cf5df3b08bc5483a6f27d847f3ddf752aaa18bfcf74fec087e1
6
+ metadata.gz: b434d7100850f01b027d437800018a14eec3d97292d3553736baf43ede5714146eb56c81b060462bc6e49a21df90aa562638ee9dfe35c73fdd8d0046f2eb65e0
7
+ data.tar.gz: 7b37256b42f7d5a767cb8a048ae0d287dc8d7c6590bb2155d059f8a5fc674d08fda84d1242d7bcdc198367e0aef5d4699cab6ecb984dc28e430571da25fc8122
@@ -87,6 +87,23 @@ JSValue to_js_value(JSContext *ctx, VALUE r_value)
87
87
  }
88
88
  }
89
89
 
90
+ VALUE find_ruby_error(JSContext *ctx, JSValue j_error)
91
+ {
92
+ JSValue j_errorOriginalRubyObjectId = JS_GetPropertyStr(ctx, j_error, "rb_object_id");
93
+ int errorOriginalRubyObjectId = 0;
94
+ if (JS_VALUE_GET_NORM_TAG(j_errorOriginalRubyObjectId) == JS_TAG_INT)
95
+ {
96
+ JS_ToInt32(ctx, &errorOriginalRubyObjectId, j_errorOriginalRubyObjectId);
97
+ JS_FreeValue(ctx, j_errorOriginalRubyObjectId);
98
+ if (errorOriginalRubyObjectId > 0)
99
+ {
100
+ // may be nice if cover the case of object is missing
101
+ return rb_funcall(rb_const_get(rb_cClass, rb_intern("ObjectSpace")), rb_intern("_id2ref"), 1, INT2NUM(errorOriginalRubyObjectId));
102
+ }
103
+ }
104
+ return Qnil;
105
+ }
106
+
90
107
  VALUE r_try_json_parse(VALUE r_str)
91
108
  {
92
109
  return rb_funcall(rb_const_get(rb_cClass, rb_intern("JSON")), rb_intern("parse"), 1, r_str);
@@ -135,19 +152,12 @@ VALUE to_rb_value(JSContext *ctx, JSValue j_val)
135
152
 
136
153
  if (JS_IsError(ctx, j_val))
137
154
  {
138
- JSValue j_errorOriginalRubyObjectId = JS_GetPropertyStr(ctx, j_val, "rb_object_id");
139
- int errorOriginalRubyObjectId = 0;
140
- if (JS_VALUE_GET_NORM_TAG(j_errorOriginalRubyObjectId) == JS_TAG_INT)
155
+ VALUE r_maybe_ruby_error = find_ruby_error(ctx, j_val);
156
+ if (!NIL_P(r_maybe_ruby_error))
141
157
  {
142
- JS_ToInt32(ctx, &errorOriginalRubyObjectId, j_errorOriginalRubyObjectId);
143
- JS_FreeValue(ctx, j_errorOriginalRubyObjectId);
144
- if (errorOriginalRubyObjectId > 0)
145
- {
146
- // may be nice if cover the case of object is missing
147
- return rb_funcall(rb_const_get(rb_cClass, rb_intern("ObjectSpace")), rb_intern("_id2ref"), 1, INT2NUM(errorOriginalRubyObjectId));
148
- }
158
+ return r_maybe_ruby_error;
149
159
  }
150
- // will support other errors
160
+ // will support other errors like just returning an instance of Error
151
161
  }
152
162
 
153
163
  JSValue j_global = JS_GetGlobalObject(ctx);
@@ -189,19 +199,12 @@ VALUE to_rb_value(JSContext *ctx, JSValue j_val)
189
199
  JSValue j_exceptionVal = JS_GetException(ctx);
190
200
  if (JS_IsError(ctx, j_exceptionVal))
191
201
  {
192
- JSValue j_errorOriginalRubyObjectId = JS_GetPropertyStr(ctx, j_exceptionVal, "rb_object_id");
193
- int errorOriginalRubyObjectId = 0;
194
- if (JS_VALUE_GET_NORM_TAG(j_errorOriginalRubyObjectId) == JS_TAG_INT)
202
+ VALUE r_maybe_ruby_error = find_ruby_error(ctx, j_exceptionVal);
203
+ if (!NIL_P(r_maybe_ruby_error))
195
204
  {
196
- JS_ToInt32(ctx, &errorOriginalRubyObjectId, j_errorOriginalRubyObjectId);
197
- JS_FreeValue(ctx, j_errorOriginalRubyObjectId);
198
- if (errorOriginalRubyObjectId > 0)
199
- {
200
- JS_FreeValue(ctx, j_exceptionVal);
201
- // may be nice if cover the case of object is missing
202
- rb_exc_raise(rb_funcall(rb_const_get(rb_cClass, rb_intern("ObjectSpace")), rb_intern("_id2ref"), 1, INT2NUM(errorOriginalRubyObjectId)));
203
- return Qnil;
204
- }
205
+ JS_FreeValue(ctx, j_exceptionVal);
206
+ rb_exc_raise(r_maybe_ruby_error);
207
+ return Qnil;
205
208
  }
206
209
 
207
210
  JSValue j_errorClassName = JS_GetPropertyStr(ctx, j_exceptionVal, "name");
@@ -210,8 +213,22 @@ VALUE to_rb_value(JSContext *ctx, JSValue j_val)
210
213
  JSValue j_errorClassMessage = JS_GetPropertyStr(ctx, j_exceptionVal, "message");
211
214
  const char *errorClassMessage = JS_ToCString(ctx, j_errorClassMessage);
212
215
 
216
+ JSValue j_stackTrace = JS_GetPropertyStr(ctx, j_exceptionVal, "stack");
217
+ const char *stackTrace = JS_ToCString(ctx, j_stackTrace);
218
+ const char *headlineTemplate = "Uncaught %s: %s\n%s";
219
+ int length = snprintf(NULL, 0, headlineTemplate, errorClassName, errorClassMessage, stackTrace);
220
+ char *headline = (char *)malloc(length + 1);
221
+ snprintf(headline, length + 1, headlineTemplate, errorClassName, errorClassMessage, stackTrace);
222
+
223
+ VMData *data = JS_GetContextOpaque(ctx);
224
+ VALUE r_headline = rb_str_new2(headline);
225
+ rb_ary_push(data->logs, r_log_new("error", rb_ary_new3(1, r_log_body_new(r_headline, r_headline))));
226
+
213
227
  JS_FreeValue(ctx, j_errorClassMessage);
214
228
  JS_FreeValue(ctx, j_errorClassName);
229
+ JS_FreeValue(ctx, j_stackTrace);
230
+ JS_FreeCString(ctx, stackTrace);
231
+ free(headline);
215
232
 
216
233
  VALUE r_error_class, r_error_message = rb_str_new2(errorClassMessage);
217
234
  if (is_native_error_name(errorClassName))
@@ -240,8 +257,18 @@ VALUE to_rb_value(JSContext *ctx, JSValue j_val)
240
257
  else // exception without Error object
241
258
  {
242
259
  const char *errorMessage = JS_ToCString(ctx, j_exceptionVal);
243
- VALUE r_error_message = rb_sprintf("%s", errorMessage);
260
+ const char *headlineTemplate = "Uncaught '%s'";
261
+ int length = snprintf(NULL, 0, headlineTemplate, errorMessage);
262
+ char *headline = (char *)malloc(length + 1);
263
+ snprintf(headline, length + 1, headlineTemplate, errorMessage);
264
+
265
+ VMData *data = JS_GetContextOpaque(ctx);
266
+ VALUE r_headline = rb_str_new2(headline);
267
+ rb_ary_push(data->logs, r_log_new("error", rb_ary_new3(1, r_log_body_new(r_headline, r_headline))));
268
+
269
+ free(headline);
244
270
 
271
+ VALUE r_error_message = rb_sprintf("%s", errorMessage);
245
272
  JS_FreeCString(ctx, errorMessage);
246
273
  JS_FreeValue(ctx, j_exceptionVal);
247
274
  rb_exc_raise(rb_funcall(QUICKJSRB_ERROR_FOR(QUICKJSRB_ROOT_RUNTIME_ERROR), rb_intern("new"), 2, r_error_message, Qnil));
@@ -281,84 +308,117 @@ static VALUE r_try_call_proc(VALUE r_try_args)
281
308
  );
282
309
  }
283
310
 
284
- static JSValue js_quickjsrb_call_global(JSContext *ctx, JSValueConst _this, int _argc, JSValueConst *argv)
311
+ static JSValue js_quickjsrb_call_global(JSContext *ctx, JSValueConst _this, int argc, JSValueConst *argv, int _magic, JSValue *func_data)
285
312
  {
286
- VMData *data = JS_GetContextOpaque(ctx);
287
- JSValue j_maybeFuncName = JS_ToString(ctx, argv[0]);
288
- const char *funcName = JS_ToCString(ctx, j_maybeFuncName);
289
- JS_FreeValue(ctx, j_maybeFuncName);
313
+ const char *funcName = JS_ToCString(ctx, func_data[0]);
290
314
 
315
+ VMData *data = JS_GetContextOpaque(ctx);
291
316
  VALUE r_proc = rb_hash_aref(data->defined_functions, rb_str_new2(funcName));
292
317
  if (r_proc == Qnil)
293
- { // Shouldn't happen
294
- return JS_ThrowReferenceError(ctx, "Proc `%s` is not defined", funcName);
318
+ { // Shouldn't happen
319
+ return JS_ThrowReferenceError(ctx, "Proc `%s` is not defined", funcName); // TODO: Free funcnName
295
320
  }
321
+ JS_FreeCString(ctx, funcName);
296
322
 
297
323
  VALUE r_call_args = rb_ary_new();
298
324
  rb_ary_push(r_call_args, r_proc);
299
- rb_ary_push(r_call_args, to_rb_value(ctx, argv[1]));
325
+
326
+ VALUE r_argv = rb_ary_new();
327
+ for (int i = 0; i < argc; i++)
328
+ {
329
+ rb_ary_push(r_argv, to_rb_value(ctx, argv[i]));
330
+ }
331
+ rb_ary_push(r_call_args, r_argv);
300
332
  rb_ary_push(r_call_args, ULONG2NUM(data->eval_time->limit * 1000 / CLOCKS_PER_SEC));
301
333
 
302
334
  int sadnessHappened;
303
- VALUE r_result = rb_protect(r_try_call_proc, r_call_args, &sadnessHappened);
304
- JSValue j_result;
305
- if (sadnessHappened)
335
+
336
+ if (JS_ToBool(ctx, func_data[1]))
306
337
  {
307
- VALUE r_error = rb_errinfo();
308
- JSValue j_error = j_error_from_ruby_error(ctx, r_error);
309
- return JS_Throw(ctx, j_error);
338
+ JSValue promise, resolving_funcs[2];
339
+ JSValue ret_val;
340
+
341
+ promise = JS_NewPromiseCapability(ctx, resolving_funcs);
342
+ if (JS_IsException(promise))
343
+ return JS_EXCEPTION;
344
+
345
+ // Currently, it's blocking process but should be asynchronized
346
+ JSValue j_result;
347
+ VALUE r_result = rb_protect(r_try_call_proc, r_call_args, &sadnessHappened);
348
+ if (sadnessHappened)
349
+ {
350
+ VALUE r_error = rb_errinfo();
351
+ j_result = j_error_from_ruby_error(ctx, r_error);
352
+ ret_val = JS_Call(ctx, resolving_funcs[1], JS_UNDEFINED,
353
+ 1, (JSValueConst *)&j_result);
354
+ }
355
+ else
356
+ {
357
+ j_result = to_js_value(ctx, r_result);
358
+ ret_val = JS_Call(ctx, resolving_funcs[0], JS_UNDEFINED,
359
+ 1, (JSValueConst *)&j_result);
360
+ }
361
+ JS_FreeValue(ctx, j_result);
362
+ JS_FreeValue(ctx, ret_val);
363
+ JS_FreeValue(ctx, resolving_funcs[0]);
364
+ JS_FreeValue(ctx, resolving_funcs[1]);
365
+ return promise;
310
366
  }
311
367
  else
312
368
  {
313
- j_result = to_js_value(ctx, r_result);
369
+ VALUE r_result = rb_protect(r_try_call_proc, r_call_args, &sadnessHappened);
370
+ if (sadnessHappened)
371
+ {
372
+ VALUE r_error = rb_errinfo();
373
+ JSValue j_error = j_error_from_ruby_error(ctx, r_error);
374
+ return JS_Throw(ctx, j_error);
375
+ }
376
+ else
377
+ {
378
+ return to_js_value(ctx, r_result);
379
+ }
314
380
  }
315
- JS_FreeCString(ctx, funcName);
316
- return j_result;
317
381
  }
318
382
 
319
- static JSValue js_quickjsrb_log(JSContext *ctx, JSValueConst _this, int _argc, JSValueConst *argv)
383
+ static JSValue js_quickjsrb_log(JSContext *ctx, JSValueConst _this, int argc, JSValueConst *argv, const char *severity)
320
384
  {
321
385
  VMData *data = JS_GetContextOpaque(ctx);
322
- JSValue j_severity = JS_ToString(ctx, argv[0]);
323
- const char *severity = JS_ToCString(ctx, j_severity);
324
- JS_FreeValue(ctx, j_severity);
325
-
326
- VALUE r_log_class = rb_const_get(rb_const_get(rb_const_get(rb_cClass, rb_intern("Quickjs")), rb_intern("VM")), rb_intern("Log"));
327
- VALUE r_log = rb_funcall(r_log_class, rb_intern("new"), 0);
328
- rb_iv_set(r_log, "@severity", ID2SYM(rb_intern(severity)));
329
- JS_FreeCString(ctx, severity);
330
-
331
386
  VALUE r_row = rb_ary_new();
332
- int i;
333
- JSValue j_length = JS_GetPropertyStr(ctx, argv[1], "length");
334
- int count;
335
- JS_ToInt32(ctx, &count, j_length);
336
- JS_FreeValue(ctx, j_length);
337
-
338
- for (i = 0; i < count; i++)
387
+ for (int i = 0; i < argc; i++)
339
388
  {
340
- VALUE r_loghash = rb_hash_new();
341
- JSValue j_logged = JS_GetPropertyUint32(ctx, argv[1], i);
342
- if (JS_VALUE_GET_NORM_TAG(j_logged) == JS_TAG_OBJECT && JS_PromiseState(ctx, j_logged) != -1)
343
- {
344
- rb_hash_aset(r_loghash, ID2SYM(rb_intern("raw")), rb_str_new2("Promise"));
345
- }
346
- else
347
- {
348
- rb_hash_aset(r_loghash, ID2SYM(rb_intern("raw")), to_rb_value(ctx, j_logged));
349
- }
389
+ JSValue j_logged = argv[i];
390
+ VALUE r_raw = JS_VALUE_GET_NORM_TAG(j_logged) == JS_TAG_OBJECT && JS_PromiseState(ctx, j_logged) != -1 ? rb_str_new2("Promise") : to_rb_value(ctx, j_logged);
350
391
  const char *body = JS_ToCString(ctx, j_logged);
351
- JS_FreeValue(ctx, j_logged);
352
- rb_hash_aset(r_loghash, ID2SYM(rb_intern("c")), rb_str_new2(body));
392
+ VALUE r_c = rb_str_new2(body);
353
393
  JS_FreeCString(ctx, body);
354
- rb_ary_push(r_row, r_loghash);
394
+
395
+ rb_ary_push(r_row, r_log_body_new(r_raw, r_c));
355
396
  }
356
397
 
357
- rb_iv_set(r_log, "@row", r_row);
358
- rb_ary_push(data->logs, r_log);
398
+ rb_ary_push(data->logs, r_log_new(severity, r_row));
359
399
  return JS_UNDEFINED;
360
400
  }
361
401
 
402
+ static JSValue js_console_info(JSContext *ctx, JSValueConst this, int argc, JSValueConst *argv)
403
+ {
404
+ return js_quickjsrb_log(ctx, this, argc, argv, "info");
405
+ }
406
+
407
+ static JSValue js_console_verbose(JSContext *ctx, JSValueConst this, int argc, JSValueConst *argv)
408
+ {
409
+ return js_quickjsrb_log(ctx, this, argc, argv, "verbose");
410
+ }
411
+
412
+ static JSValue js_console_warn(JSContext *ctx, JSValueConst this, int argc, JSValueConst *argv)
413
+ {
414
+ return js_quickjsrb_log(ctx, this, argc, argv, "warning");
415
+ }
416
+
417
+ static JSValue js_console_error(JSContext *ctx, JSValueConst this, int argc, JSValueConst *argv)
418
+ {
419
+ return js_quickjsrb_log(ctx, this, argc, argv, "error");
420
+ }
421
+
362
422
  static VALUE vm_m_initialize(int argc, VALUE *argv, VALUE r_self)
363
423
  {
364
424
  VALUE r_opts;
@@ -430,29 +490,27 @@ static VALUE vm_m_initialize(int argc, VALUE *argv, VALUE r_self)
430
490
  JS_FreeValue(data->context, j_timeoutEval);
431
491
  }
432
492
 
433
- JSValue j_global = JS_GetGlobalObject(data->context);
434
- JSValue j_quickjsrbGlobal = JS_NewObject(data->context);
435
- JS_SetPropertyStr(
436
- data->context, j_quickjsrbGlobal, "runRubyMethod",
437
- JS_NewCFunction(data->context, js_quickjsrb_call_global, "runRubyMethod", 2));
438
-
439
- JS_SetPropertyStr(data->context, j_global, "__quickjsrb", j_quickjsrbGlobal);
440
-
441
493
  JSValue j_console = JS_NewObject(data->context);
442
494
  JS_SetPropertyStr(
443
- data->context, j_quickjsrbGlobal, "log",
444
- JS_NewCFunction(data->context, js_quickjsrb_log, "log", 2));
495
+ data->context, j_console, "log",
496
+ JS_NewCFunction(data->context, js_console_info, "log", 1));
497
+ JS_SetPropertyStr(
498
+ data->context, j_console, "debug",
499
+ JS_NewCFunction(data->context, js_console_verbose, "debug", 1));
500
+ JS_SetPropertyStr(
501
+ data->context, j_console, "info",
502
+ JS_NewCFunction(data->context, js_console_info, "info", 1));
503
+ JS_SetPropertyStr(
504
+ data->context, j_console, "warn",
505
+ JS_NewCFunction(data->context, js_console_warn, "warn", 1));
506
+ JS_SetPropertyStr(
507
+ data->context, j_console, "error",
508
+ JS_NewCFunction(data->context, js_console_error, "error", 1));
509
+
510
+ JSValue j_global = JS_GetGlobalObject(data->context);
445
511
  JS_SetPropertyStr(data->context, j_global, "console", j_console);
446
512
  JS_FreeValue(data->context, j_global);
447
513
 
448
- const char *defineLoggers = "console.log = (...args) => __quickjsrb.log('info', args);\n"
449
- "console.debug = (...args) => __quickjsrb.log('verbose', args);\n"
450
- "console.info = (...args) => __quickjsrb.log('info', args);\n"
451
- "console.warn = (...args) => __quickjsrb.log('warning', args);\n"
452
- "console.error = (...args) => __quickjsrb.log('error', args);\n";
453
- JSValue j_defineLoggers = JS_Eval(data->context, defineLoggers, strlen(defineLoggers), "<vm>", JS_EVAL_TYPE_GLOBAL);
454
- JS_FreeValue(data->context, j_defineLoggers);
455
-
456
514
  return r_self;
457
515
  }
458
516
 
@@ -501,27 +559,23 @@ static VALUE vm_m_defineGlobalFunction(int argc, VALUE *argv, VALUE r_self)
501
559
  VALUE r_block;
502
560
  rb_scan_args(argc, argv, "10*&", &r_name, &r_flags, &r_block);
503
561
 
504
- const char *asyncKeyword =
505
- RTEST(rb_funcall(r_flags, rb_intern("include?"), 1, ID2SYM(rb_intern("async")))) ? "async " : "";
506
-
507
562
  VMData *data;
508
563
  TypedData_Get_Struct(r_self, VMData, &vm_type, data);
509
564
 
510
565
  rb_hash_aset(data->defined_functions, r_name, r_block);
511
566
  char *funcName = StringValueCStr(r_name);
512
567
 
513
- const char *template = "globalThis['%s'] = %s(...args) => __quickjsrb.runRubyMethod('%s', args);\n";
514
- int length = snprintf(NULL, 0, template, funcName, asyncKeyword, funcName);
515
- char *result = (char *)malloc(length + 1);
516
- snprintf(result, length + 1, template, funcName, asyncKeyword, funcName);
568
+ JSValueConst ruby_data[2];
569
+ ruby_data[0] = JS_NewString(data->context, funcName);
570
+ ruby_data[1] = JS_NewBool(data->context, RTEST(rb_funcall(r_flags, rb_intern("include?"), 1, ID2SYM(rb_intern("async")))));
517
571
 
518
- JSValue j_codeResult = JS_Eval(data->context, result, strlen(result), "<vm>", JS_EVAL_TYPE_MODULE);
572
+ JSValue j_global = JS_GetGlobalObject(data->context);
573
+ JS_SetPropertyStr(
574
+ data->context, j_global, funcName,
575
+ JS_NewCFunctionData(data->context, js_quickjsrb_call_global, 1, 0, 2, ruby_data));
576
+ JS_FreeValue(data->context, j_global);
519
577
 
520
- free(result);
521
- JS_FreeValue(data->context, j_codeResult);
522
578
  return rb_funcall(r_name, rb_intern("to_sym"), 0, NULL);
523
-
524
- return Qnil;
525
579
  }
526
580
 
527
581
  static VALUE vm_m_import(int argc, VALUE *argv, VALUE r_self)
@@ -178,6 +178,23 @@ static VALUE r_define_log_class(VALUE r_parent_class)
178
178
  return r_log_class;
179
179
  }
180
180
 
181
+ static VALUE r_log_new(const char *severity, VALUE r_row)
182
+ {
183
+ VALUE r_log_class = rb_const_get(rb_const_get(rb_const_get(rb_cClass, rb_intern("Quickjs")), rb_intern("VM")), rb_intern("Log"));
184
+ VALUE r_log = rb_funcall(r_log_class, rb_intern("new"), 0);
185
+ rb_iv_set(r_log, "@severity", ID2SYM(rb_intern(severity)));
186
+ rb_iv_set(r_log, "@row", r_row);
187
+ return r_log;
188
+ }
189
+
190
+ static VALUE r_log_body_new(VALUE r_raw, VALUE r_c)
191
+ {
192
+ VALUE r_log_body = rb_hash_new();
193
+ rb_hash_aset(r_log_body, ID2SYM(rb_intern("raw")), r_raw);
194
+ rb_hash_aset(r_log_body, ID2SYM(rb_intern("c")), r_c);
195
+ return r_log_body;
196
+ }
197
+
181
198
  // Exceptions
182
199
 
183
200
  #define QUICKJSRB_ROOT_RUNTIME_ERROR "RuntimeError"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Quickjs
4
- VERSION = "0.3.0"
4
+ VERSION = "0.5.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quickjs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - hmsk
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-11-08 00:00:00.000000000 Z
11
+ date: 2024-11-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json