Moment.js docker/metadata-action OCI Date Format REPL

A tool for fiddling with Docker OCI metadata formats (handlebars -> moment.js time format string). A simple REPL is implemented which accepts a bare handlebars string in the format: {{ date 'format-string' }} Where 'format-string' is a moment.js date format specifier (e.g. 'YYYY-MM-DD HH:mm:ss.SSSS A Z' )

by TrinitronX

HTML

<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Docker OCI Timestamp Annotation Example</title>
<!--
    /*
          "xterm-old": "https://unpkg.com/@liudonghua123/xterm@5.5.0/lib/xterm-esm.js",
          "@yarnpkg/broken-lockfile": "https://esm.sh/@yarnpkg/lockfile@1.1.0/?dev",
    */
-->
    <script type="importmap">
    {
        "imports": {
          "xterm": "https://esm.sh/@xterm/xterm@5.5.0",
          "moment": "https://esm.sh/moment@2.30.1/?dev",
          "handlebars": "https://esm.sh/handlebars@4.7.8/?dev"
        }
      }
    </script>
    <link rel="stylesheet" href="https://unpkg.com/@xterm/xterm@5.5.0/css/xterm.css" />
    <!-- OLD xterm -->
<!--     <link rel="stylesheet" href="https://unpkg.com/@liudonghua123/xterm@5.5.0/css/xterm.css" /> -->

    <style>
    </style>
  </head>

  <body>
    <div class="topcontainer">
      <div class="container midcontainer">
        <div id="time1" class="neumorphic time">
          <p>
            Nonstandard Time Format
          </p>
          <p id="datetime1" class="datetime">
          </p>
        </div>
        <div id="pause-container" class="container">
          <div id="pause-button" class="neumorphic button">
            <p>
              Pause
            </p>
          </div>
        </div>
        <div id="time2" class="neumorphic time">
          <p>
            RFC 3339 + ISO 8601ISO 8601-1:2019
          </p>
          <p id="datetime2" class="datetime">
          </p>
        </div>
      </div>
      <div id="termcontainer" class="midcontainer neumorphic-container">
        <div id="xterm1" class="myterminal">
<!--           <p>
            Hello term
          </p> -->
        </div>
      </div>
    </div>
  </body>

</html>

CSS

body {
  background-color: #e6e7ee;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  margin: 0;
  font-family: Arial, sans-serif;
}

.topcontainer {
  display: flex;
  /* flex-wrap: wrap; */
  flex-direction: column;
  align-content: space-between;
  height: 100vh;
  /* height: 100%; */
  width: 95%;
  /* align-content: center; */
  /* justify-content: space-between; */
  /* DEBUG */
  /* border: 1rem solid magenta; */
}

.midcontainer {
  display: flex;
  flex-direction: row;
  height: 50%;
  /* DEBUG */
  /* border: 1rem solid red; */
  /* justify-content: flex-end; */
  width: 100%;
  /* gap: 20px 30px; */
}

.container {
  display: flex;
  gap: 20px;
  justify-content: center;
}

.neumorphic {
  background: #e6e7ee;
  border-radius: 10px;
  box-shadow: 9px 9px 16px #b8b9be, -9px -9px 16px #fff;
  padding: 20px;
  text-align: center;
  width: 200px;
  height: 100px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.datetime {
  align-self: flex-end;
  align-content: flex-end;
}

.time {
  flex-wrap: wrap;
  align-content: center;
  justify-content: center;
}

div#time2 {
  width: 300px;
}

/* Align button at bottom of midcontainer */
div#pause-container {
  align-self: flex-end;
}

.button {
  color: #00084d;
  background: #e5f2fc;
  border-radius: 10px;
  box-shadow: 9px 9px 16px #b8b9be, -9px -9px 16px #fff;
  padding: 20px;
  text-align: center;
  width: 200px;
  height: 100px;
  display: flex;
  justify-content: center;
  align-items: center;

  transition-property: all;
  transition-duration: 0.25s;
  transition-timing-function: ease-out;
  transition-delay: 0s;
}

.button:hover {
  color: #1d63ed;
}

.button:focus {
  outline: 1px solid #1d63ed;
}

.button:active {
  color: #00084d;
  background-color: #cfe7fa;
  box-shadow: -9px -9px 16px #b8b9be, 9px 9px 16px #fff;
}

.pauseActive {
  color: #104dc5;
  text-shadow: -1px -1px 1px #fff, 1px -1px 3px #092e76, -1px 1px 1px #fff, 1px 1px 1px...

JavaScript

// See https://www.npmjs.com/package/parse-yarn-lock documentation.
/* import parse as parseYarnLock from 'https://cdn.jsdelivr.net/npm/yarn-lockfile@latest/+esm'; */
import {
  Terminal
} from 'xterm';

import moment from 'moment';
import * as handlebarsESMshImport from 'handlebars';
const handlebars = handlebarsESMshImport.default;

function showTimes() {
  let now = moment().format('YYYYMMDD-hhmmss');
  // console.log(now);
  document.getElementById('datetime1').innerText = now;
  let currentDate = new Date();
  let format = "YYYY-MM-DDTHH:mm:ss.SSSSZ";
  // Based on Intersection of RFC 3339 and ISO 8601 formats
  // https://ijmacd.github.io/rfc3339-iso8601/
  let dockerOCITimestamp = moment(currentDate).utc().format(format);
  // console.log(dockerOCITimestamp);
  document.getElementById('datetime2').innerText = dockerOCITimestamp;
}

var intervalId = window.setInterval(showTimes, 1000);

function pauseInterval() {
  if (intervalId != null) {
    clearInterval(intervalId);
    intervalId = null;
    document.getElementById('pause-button').classList.add('pauseActive');
  } else {
    intervalId = window.setInterval(showTimes, 1000);
    document.getElementById('pause-button').classList.remove('pauseActive');
  }
}

document.getElementById('pause-button').addEventListener('click', pauseInterval);

const PS1 = "docker@date-fiddle.js \x1B[1;3;31mxterm.js\x1B[0m $ ";
const terminal = new Terminal({ cursorBlink: 'block' });
/* const ws = new WebSocket("ws://localhost:3000", "echo-protocol"); */

function handlebarsDateFormat(dockerMetadataActionTagInputFormat) {
  // Compile the Handlebars template from input
  let template = handlebars.compile(dockerMetadataActionTagInputFormat);
  
  let currentDate = new Date();
  const context = {
    date: function (format) {
      return moment(currentDate).utc().format(format);
    }
  };
  // Execute the compiled template with the context
  const result = template(context);
  console.log(result);
  terminal.write(result);
 ...