commit 281bbb130921e58375e5ee1527215fc488782663
Author: test-org <>
Date: Sun Jan 28 19:31:48 2024 +0000
Initial commit
diff --git a/.gitea/workflows/publish.yaml b/.gitea/workflows/publish.yaml
new file mode 100644
index 0000000..acce2e7
--- /dev/null
+++ b/.gitea/workflows/publish.yaml
@@ -0,0 +1,31 @@
+name: Publish ApplicationRecord to Registry
+on:
+ release:
+ types: [published]
+
+env:
+ CERC_REGISTRY_USER_KEY: ${{ secrets.CICD_LACONIC_USER_KEY }}
+ CERC_REGISTRY_BOND_ID: ${{ secrets.CICD_LACONIC_BOND_ID }}
+
+jobs:
+ cns_publish:
+ runs-on: ubuntu-latest
+ steps:
+ - name: "Clone project repository"
+ uses: actions/checkout@v3
+ - name: Use Node.js
+ uses: actions/setup-node@v3
+ with:
+ node-version: 18
+ - name: "Install Yarn"
+ run: npm install -g yarn
+ - name: "Install registry CLI"
+ run: |
+ npm config set @cerc-io:registry https://git.vdb.to/api/packages/cerc-io/npm/
+ yarn global add @cerc-io/laconic-registry-cli
+ - name: "Install jq"
+ run: apt -y update && apt -y install jq
+ - name: "Publish Application Record"
+ run: scripts/publish-app-record.sh
+ - name: "Request Deployment"
+ run: scripts/request-app-deployment.sh
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..669d643
--- /dev/null
+++ b/README.md
@@ -0,0 +1,12 @@
+# progressive-web-app-template
+
+A template repo from which progressive-web-apps deployable on Laconic can be made.
+
+## Usage
+
+After creating a repository from this template, search for occurrences of "UPDATE-ME-FROM-TEMPLATE" and replace with strings appropriate to the new repository.
+
+Run `npm install` then commit the file `package-lock.json` to the repository.
+
+Add the secrets `CICD_LACONIC_USER_KEY` and `CICD_LACONIC_BOND_ID` to the repository or organization.
+
diff --git a/next.config.js b/next.config.js
new file mode 100644
index 0000000..bc3bd17
--- /dev/null
+++ b/next.config.js
@@ -0,0 +1,12 @@
+/** @type {import('next').NextConfig} */
+const withPWA = require('next-pwa')({
+ dest: 'public',
+})
+
+module.exports = withPWA({
+ env: {
+ CERC_TEST_WEBAPP_CONFIG1: process.env.CERC_TEST_WEBAPP_CONFIG1,
+ CERC_TEST_WEBAPP_CONFIG2: process.env.CERC_TEST_WEBAPP_CONFIG2,
+ CERC_WEBAPP_DEBUG: process.env.CERC_WEBAPP_DEBUG,
+ },
+})
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..6e1cfc9
--- /dev/null
+++ b/package.json
@@ -0,0 +1,22 @@
+{
+ "private": true,
+ "name": "UPDATE-ME-FROM-TEMPLATE",
+ "version": "0.1.0",
+ "repository": "https://UPDATE-ME-FROM-TEMPLATE",
+ "scripts": {
+ "dev": "next dev",
+ "build": "next build",
+ "start": "next start"
+ },
+ "dependencies": {
+ "next": "latest",
+ "next-pwa": "^5.6.0",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ },
+ "devDependencies": {
+ "@types/node": "17.0.4",
+ "@types/react": "17.0.38",
+ "typescript": "4.5.4"
+ }
+}
diff --git a/pages/_app.tsx b/pages/_app.tsx
new file mode 100644
index 0000000..a9ff536
--- /dev/null
+++ b/pages/_app.tsx
@@ -0,0 +1,38 @@
+import Head from 'next/head'
+import '../styles/globals.css'
+import { AppProps } from 'next/app'
+
+export default function MyApp({ Component, pageProps }: AppProps) {
+ return (
+ <>
+
+
+
+
+
+
+ Laconic Test PWA
+
+
+
+
+
+
+
+
+ >
+ )
+}
diff --git a/pages/api/hello.ts b/pages/api/hello.ts
new file mode 100644
index 0000000..a42f463
--- /dev/null
+++ b/pages/api/hello.ts
@@ -0,0 +1,8 @@
+// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
+import { NextApiRequest, NextApiResponse } from 'next'
+
+const hello = (req: NextApiRequest, res: NextApiResponse) => {
+ res.status(200).json({ name: 'John Doe' })
+}
+
+export default hello
diff --git a/pages/index.tsx b/pages/index.tsx
new file mode 100644
index 0000000..96e5929
--- /dev/null
+++ b/pages/index.tsx
@@ -0,0 +1,50 @@
+import styles from '../styles/Home.module.css'
+
+export default function Home() {
+ return (
+
+
+
+
+
+
+
+ CONFIG1 has value: {process.env.CERC_TEST_WEBAPP_CONFIG1}
+
+
+
+ CONFIG2 has value: {process.env.CERC_TEST_WEBAPP_CONFIG2}
+
+
+
+ WEBAPP_DEBUG has value: {process.env.CERC_WEBAPP_DEBUG}
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000..be8a3fc
Binary files /dev/null and b/public/favicon.ico differ
diff --git a/public/icons/icon-128x128.png b/public/icons/icon-128x128.png
new file mode 100644
index 0000000..b6f3bde
Binary files /dev/null and b/public/icons/icon-128x128.png differ
diff --git a/public/icons/icon-144x144.png b/public/icons/icon-144x144.png
new file mode 100644
index 0000000..35529f7
Binary files /dev/null and b/public/icons/icon-144x144.png differ
diff --git a/public/icons/icon-152x152.png b/public/icons/icon-152x152.png
new file mode 100644
index 0000000..3543e09
Binary files /dev/null and b/public/icons/icon-152x152.png differ
diff --git a/public/icons/icon-16x16.png b/public/icons/icon-16x16.png
new file mode 100644
index 0000000..144f30d
Binary files /dev/null and b/public/icons/icon-16x16.png differ
diff --git a/public/icons/icon-192x192.png b/public/icons/icon-192x192.png
new file mode 100644
index 0000000..b6cc9df
Binary files /dev/null and b/public/icons/icon-192x192.png differ
diff --git a/public/icons/icon-32x32.png b/public/icons/icon-32x32.png
new file mode 100644
index 0000000..c29c45b
Binary files /dev/null and b/public/icons/icon-32x32.png differ
diff --git a/public/icons/icon-384x384.png b/public/icons/icon-384x384.png
new file mode 100644
index 0000000..4c3ba7f
Binary files /dev/null and b/public/icons/icon-384x384.png differ
diff --git a/public/icons/icon-512x512.png b/public/icons/icon-512x512.png
new file mode 100644
index 0000000..6b1e998
Binary files /dev/null and b/public/icons/icon-512x512.png differ
diff --git a/public/icons/icon-72x72.png b/public/icons/icon-72x72.png
new file mode 100644
index 0000000..b6bddb4
Binary files /dev/null and b/public/icons/icon-72x72.png differ
diff --git a/public/icons/icon-96x96.png b/public/icons/icon-96x96.png
new file mode 100644
index 0000000..d5bfcf4
Binary files /dev/null and b/public/icons/icon-96x96.png differ
diff --git a/public/manifest.json b/public/manifest.json
new file mode 100644
index 0000000..4164668
--- /dev/null
+++ b/public/manifest.json
@@ -0,0 +1,53 @@
+{
+ "name": "Laconic Test Progressive Web App",
+ "short_name": "Test PWA",
+ "theme_color": "#ffffff",
+ "background_color": "#004740",
+ "display": "fullscreen",
+ "orientation": "portrait",
+ "scope": "/",
+ "start_url": "/",
+ "icons": [
+ {
+ "src": "icons/icon-72x72.png",
+ "sizes": "72x72",
+ "type": "image/png"
+ },
+ {
+ "src": "icons/icon-96x96.png",
+ "sizes": "96x96",
+ "type": "image/png"
+ },
+ {
+ "src": "icons/icon-128x128.png",
+ "sizes": "128x128",
+ "type": "image/png"
+ },
+ {
+ "src": "icons/icon-144x144.png",
+ "sizes": "144x144",
+ "type": "image/png"
+ },
+ {
+ "src": "icons/icon-152x152.png",
+ "sizes": "152x152",
+ "type": "image/png"
+ },
+ {
+ "src": "icons/icon-192x192.png",
+ "sizes": "192x192",
+ "type": "image/png"
+ },
+ {
+ "src": "icons/icon-384x384.png",
+ "sizes": "384x384",
+ "type": "image/png"
+ },
+ {
+ "src": "icons/icon-512x512.png",
+ "sizes": "512x512",
+ "type": "image/png"
+ }
+ ],
+ "splash_pages": null
+}
diff --git a/public/vercel.svg b/public/vercel.svg
new file mode 100644
index 0000000..fbf0e25
--- /dev/null
+++ b/public/vercel.svg
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/scripts/publish-app-record.sh b/scripts/publish-app-record.sh
new file mode 100755
index 0000000..cb406d7
--- /dev/null
+++ b/scripts/publish-app-record.sh
@@ -0,0 +1,69 @@
+#!/bin/bash
+
+set -e
+
+RECORD_FILE=tmp.rf.$$
+CONFIG_FILE=`mktemp`
+
+CERC_APP_TYPE=${CERC_APP_TYPE:-"webapp"}
+CERC_REPO_REF=${CERC_REPO_REF:-${GITHUB_SHA:-`git log -1 --format="%H"`}}
+CERC_IS_LATEST_RELEASE=${CERC_IS_LATEST_RELEASE:-"true"}
+
+rcd_name=$(jq -r '.name' package.json | sed 's/null//')
+rcd_desc=$(jq -r '.description' package.json | sed 's/null//')
+rcd_repository=$(jq -r '.repository' package.json | sed 's/null//')
+rcd_homepage=$(jq -r '.homepage' package.json | sed 's/null//')
+rcd_license=$(jq -r '.license' package.json | sed 's/null//')
+rcd_author=$(jq -r '.author' package.json | sed 's/null//')
+rcd_app_version=$(jq -r '.version' package.json | sed 's/null//')
+
+cat < "$CONFIG_FILE"
+services:
+ cns:
+ restEndpoint: '${CERC_REGISTRY_REST_ENDPOINT:-http://console.laconic.com:1317}'
+ gqlEndpoint: '${CERC_REGISTRY_GQL_ENDPOINT:-http://console.laconic.com:9473/api}'
+ chainId: ${CERC_REGISTRY_CHAIN_ID:-laconic_9000-1}
+ gas: 550000
+ fees: 200000aphoton
+EOF
+
+next_ver=$(laconic -c $CONFIG_FILE cns record list --type ApplicationRecord --all --name "$rcd_name" 2>/dev/null | jq -r -s ".[] | sort_by(.createTime) | reverse | [ .[] | select(.bondId == \"$CERC_REGISTRY_BOND_ID\") ] | .[0].attributes.version" | awk -F. -v OFS=. '{$NF += 1 ; print}')
+
+if [ -z "$next_ver" ] || [ "1" == "$next_ver" ]; then
+ next_ver=0.0.1
+fi
+
+cat < "$RECORD_FILE"
+record:
+ type: ApplicationRecord
+ version: ${next_ver}
+ name: "$rcd_name"
+ description: "$rcd_desc"
+ homepage: "$rcd_homepage"
+ license: "$rcd_license"
+ author: "$rcd_author"
+ repository:
+ - "$rcd_repository"
+ repository_ref: "$CERC_REPO_REF"
+ app_version: "$rcd_app_version"
+ app_type: "$CERC_APP_TYPE"
+EOF
+
+
+cat $RECORD_FILE
+RECORD_ID=$(laconic -c $CONFIG_FILE cns record publish --filename $RECORD_FILE --user-key "${CERC_REGISTRY_USER_KEY}" --bond-id ${CERC_REGISTRY_BOND_ID} | jq -r '.id')
+echo $RECORD_ID
+
+if [ -z "$CERC_REGISTRY_APP_CRN" ]; then
+ authority=$(echo "$rcd_name" | cut -d'/' -f1 | sed 's/@//')
+ app=$(echo "$rcd_name" | cut -d'/' -f2-)
+ CERC_REGISTRY_APP_CRN="crn://$authority/applications/$app"
+fi
+
+laconic -c $CONFIG_FILE cns name set --user-key "${CERC_REGISTRY_USER_KEY}" --bond-id ${CERC_REGISTRY_BOND_ID} "$CERC_REGISTRY_APP_CRN@${rcd_app_version}" "$RECORD_ID"
+laconic -c $CONFIG_FILE cns name set --user-key "${CERC_REGISTRY_USER_KEY}" --bond-id ${CERC_REGISTRY_BOND_ID} "$CERC_REGISTRY_APP_CRN@${CERC_REPO_REF}" "$RECORD_ID"
+if [ "true" == "$CERC_IS_LATEST_RELEASE" ]; then
+ laconic -c $CONFIG_FILE cns name set --user-key "${CERC_REGISTRY_USER_KEY}" --bond-id ${CERC_REGISTRY_BOND_ID} "$CERC_REGISTRY_APP_CRN" "$RECORD_ID"
+fi
+
+rm -f $RECORD_FILE $CONFIG_FILE
diff --git a/scripts/request-app-deployment.sh b/scripts/request-app-deployment.sh
new file mode 100755
index 0000000..73f5e48
--- /dev/null
+++ b/scripts/request-app-deployment.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+
+set -e
+
+RECORD_FILE=tmp.rf.$$
+CONFIG_FILE=`mktemp`
+
+rcd_name=$(jq -r '.name' package.json | sed 's/null//' | sed 's/^@//')
+rcd_app_version=$(jq -r '.version' package.json | sed 's/null//')
+
+cat < "$CONFIG_FILE"
+services:
+ cns:
+ restEndpoint: '${CERC_REGISTRY_REST_ENDPOINT:-http://console.laconic.com:1317}'
+ gqlEndpoint: '${CERC_REGISTRY_GQL_ENDPOINT:-http://console.laconic.com:9473/api}'
+ chainId: ${CERC_REGISTRY_CHAIN_ID:-laconic_9000-1}
+ gas: 550000
+ fees: 200000aphoton
+EOF
+
+if [ -z "$CERC_REGISTRY_APP_CRN" ]; then
+ authority=$(echo "$rcd_name" | cut -d'/' -f1 | sed 's/@//')
+ app=$(echo "$rcd_name" | cut -d'/' -f2-)
+ CERC_REGISTRY_APP_CRN="crn://$authority/applications/$app"
+fi
+
+APP_RECORD=$(laconic -c $CONFIG_FILE cns name resolve "$CERC_REGISTRY_APP_CRN" | jq '.[0]')
+if [ -z "$APP_RECORD" ] || [ "null" == "$APP_RECORD" ]; then
+ echo "No record found for $CERC_REGISTRY_APP_CRN."
+ exit 1
+fi
+
+cat < "$RECORD_FILE"
+record:
+ type: ApplicationDeploymentRequest
+ version: 1.0.0
+ name: "$rcd_name@$rcd_app_version"
+ application: "$CERC_REGISTRY_APP_CRN@$rcd_app_version"
+ dns: "$CERC_REGISTRY_DEPLOYMENT_SHORT_HOSTNAME"
+ deployment: "$CERC_REGISTRY_DEPLOYMENT_CRN"
+ meta:
+ note: "Added by CI"
+ repository: "`git remote get-url origin`"
+ repository_ref: "${GITHUB_SHA:-`git log -1 --format="%H"`}"
+EOF
+
+cat $RECORD_FILE
+RECORD_ID=$(laconic -c $CONFIG_FILE cns record publish --filename $RECORD_FILE --user-key "${CERC_REGISTRY_USER_KEY}" --bond-id ${CERC_REGISTRY_BOND_ID} | jq -r '.id')
+echo $RECORD_ID
+
+rm -f $RECORD_FILE $CONFIG_FILE
diff --git a/styles/Home.module.css b/styles/Home.module.css
new file mode 100644
index 0000000..b55cee6
--- /dev/null
+++ b/styles/Home.module.css
@@ -0,0 +1,123 @@
+.container {
+ min-height: 100vh;
+ padding: 0 0.5rem;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+}
+
+.main {
+ padding: 5rem 0;
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+}
+
+.footer {
+ width: 100%;
+ height: 100px;
+ border-top: 1px solid #eaeaea;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.footer img {
+ margin-left: 0.5rem;
+}
+
+.footer a {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.title a {
+ color: #0070f3;
+ text-decoration: none;
+}
+
+.title a:hover,
+.title a:focus,
+.title a:active {
+ text-decoration: underline;
+}
+
+.title {
+ margin: 0;
+ line-height: 1.15;
+ font-size: 4rem;
+}
+
+.title,
+.description {
+ text-align: center;
+}
+
+.description {
+ line-height: 1.5;
+ font-size: 1.5rem;
+}
+
+.code {
+ background: #fafafa;
+ border-radius: 5px;
+ padding: 0.75rem;
+ font-size: 1.1rem;
+ font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
+ Bitstream Vera Sans Mono, Courier New, monospace;
+}
+
+.grid {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-wrap: wrap;
+
+ max-width: 800px;
+ margin-top: 3rem;
+}
+
+.card {
+ margin: 1rem;
+ flex-basis: 45%;
+ padding: 1.5rem;
+ text-align: left;
+ color: inherit;
+ text-decoration: none;
+ border: 1px solid #eaeaea;
+ border-radius: 10px;
+ transition: color 0.15s ease, border-color 0.15s ease;
+}
+
+.card:hover,
+.card:focus,
+.card:active {
+ color: #0070f3;
+ border-color: #0070f3;
+}
+
+.card h3 {
+ margin: 0 0 1rem 0;
+ font-size: 1.5rem;
+}
+
+.card p {
+ margin: 0;
+ font-size: 1.25rem;
+ line-height: 1.5;
+}
+
+.logo {
+ height: 1em;
+}
+
+@media (max-width: 600px) {
+ .grid {
+ width: 100%;
+ flex-direction: column;
+ }
+}
diff --git a/styles/globals.css b/styles/globals.css
new file mode 100644
index 0000000..e5e2dcc
--- /dev/null
+++ b/styles/globals.css
@@ -0,0 +1,16 @@
+html,
+body {
+ padding: 0;
+ margin: 0;
+ font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
+ Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
+}
+
+a {
+ color: inherit;
+ text-decoration: none;
+}
+
+* {
+ box-sizing: border-box;
+}
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..99710e8
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "preserve",
+ "incremental": true
+ },
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
+ "exclude": ["node_modules"]
+}