From a58658d8adac5a2013581893082a20e3010c7636 Mon Sep 17 00:00:00 2001 From: Firepup Sixfifty Date: Thu, 15 Aug 2024 23:59:11 -0500 Subject: [PATCH] Add CountAPI spec clone page --- public/pages/countapi-spec-clone.html | 161 ++++++++++++++++++++++++++ public/styles/atom-one-dark.min.css | 1 + public/styles/countapi.css | 149 ++++++++++++++++++++++++ 3 files changed, 311 insertions(+) create mode 100644 public/pages/countapi-spec-clone.html create mode 100644 public/styles/atom-one-dark.min.css create mode 100644 public/styles/countapi.css diff --git a/public/pages/countapi-spec-clone.html b/public/pages/countapi-spec-clone.html new file mode 100644 index 0000000..1d21017 --- /dev/null +++ b/public/pages/countapi-spec-clone.html @@ -0,0 +1,161 @@ + + + + + + FP650 - CountAPI spec clone + + + + + + +
+

API

+

Namespaces

+

Namespaces are meant to avoid name collisions. You may specify a namespace during the creation of a key. Its recommend use the domain of the application as namespace to avoid collision with other websites.
If the namespace is not specified the key is assigned to the default namespace. If your key resides in the default namespace you don't need to specify it.

+

Endpoints

+

+ All requests support cross-origin resource sharing (CORS) and SSL.
+ You can use JSONP sending the callback parameter. JSONP requests will never fail, they will include the HTTP code in the response.
+ Also a 1x1 GIF image is supported sending ?img. +

+

Base API path: https://api.countapi.xyz

+

In the case of a server failure, the API will send:

+
⇒ 500 { "error": "Error description" }
+

/get/:namespace?/:key

+

Get the value of a key. Optionally specify the namespace.

+
https://api.countapi.xyz/get/test
+⇒ 200 { "value": 42 }
+
+https://api.countapi.xyz/get/mysite.com/test
+⇒ 200 { "value": 24 }
+
https://api.countapi.xyz/get/nonexisting
+⇒ 404 { "value": null }
+

/set/:namespace?/:key?value=:value

+

Set the value of a key. Optionally specify the namespace. The key must be created with enable_reset set to 1 (true).

+

This endpoint will return the previous value before the assignation.

+
https://api.countapi.xyz/set/test?value=69
+⇒ 200 { "old_value": 42, "value": 69 }
+
+https://api.countapi.xyz/set/mysite.com/test?value=96
+⇒ 200 { "old_value": 24, "value": 96 }
+
https://api.countapi.xyz/set/resetdisabled?value=33
+⇒ 403 { "old_value": 1234, "value": 1234 }
+
+https://api.countapi.xyz/set/nonexisting?value=33
+⇒ 404 { "old_value": null, "value": null }
+

/update/:namespace?/:key?amount=:amount

+

Updates a key with +/- amount. Optionally specify the namespace. The amount must be within update_lowerbound and update_upperbound specified during the creation of the key.

+
https://api.countapi.xyz/update/test?amount=5 (value was 42)
+⇒ 200 { "value": 47 }
+
+https://api.countapi.xyz/update/mysite.com/test?amount=-7 (value was 53)
+⇒ 200 { "value": 46 }
+
https://api.countapi.xyz/update/outofrange?amount=3 (value was 47, update_upperbound=2)
+⇒ 403 { "value": 47 }
+
+https://api.countapi.xyz/update/nonexisting?amount=1
+⇒ 404 { "value": null }
+

/hit/:namespace?/:key

+

An easier way to track incrementing by one keys. This endpoint will create a key if it doesn't exists and increment it by one on each subsequent request. Optionally specify a namespace.
The key created has the following properties:

+ +

Effectively making the key only incrementable by one.

+
https://api.countapi.xyz/hit/mysite.com/visits (value was 35)
+⇒ 200 { "value": 36 }
+
+https://api.countapi.xyz/hit/nonexisting (key is created)
+⇒ 200 { "value": 1 }
+

/create

+

Creates a key.
All parameters are optional

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
namedefaultdescription
keyNew UUIDName of the key
namespacedefaultNamespace to store the key
value0The initial value stored
enable_reset0Allows the key to be resetted with /set
update_lowerbound-1Restrict update to not subtract more than this number. This number must be negative or zero.
update_upperbound1Restrict update to not add more than this number. This number must be positive or zero.
+
Note about expiration: Every time a key is updated its expiration is set to 6 months. So don't worry, if you still using it, it won't expire.
+
Keys and namespaces must have at least 3 characters and less or equal to 64. Keys and namespaces must match: ^[A-Za-z0-9_\-.]{3,64}$
+
https://api.countapi.xyz/create
+⇒ 200 {"namespace":"default", "key":"6d5891ff-ebda-48fb-a760-8549d6a3bf3a", "value":0}
+
+https://api.countapi.xyz/create?namespace=mysite.com&value=42
+⇒ 200 {"namespace":"mysite.com", "key":"33606dbe-4800-4228-b042-5c0fb8ec8f08", "value":42}
+
+https://api.countapi.xyz/create?key=counter&expiration=60
+⇒ 200 { "namespace": "default", "key":"counter", "value": 0 }
+
https://api.countapi.xyz/create?name=alreadycreated (the key already existed)
+⇒ 409 { "namespace": null, "key": null, "value": null }
+

/info/:namespace?/:key

+

Get information about a key. Optionally specify the namespace.

+
https://api.countapi.xyz/info/test
+⇒ 200 {
+    "namespace": "default",
+    "key": "test",
+    "ttl": 321,
+    "value": 42,
+    "enable_reset": false,
+    "update_upperbound": 1,
+    "update_lowerbound": 1
+}
+
https://api.countapi.xyz/info/nonexisting
+⇒ 404 {
+    "namespace": null,
+    "key": null,
+    "ttl": null,
+    "value": null,
+    "enable_reset": null,
+    "update_upperbound": null,
+    "update_lowerbound": null
+}
+

/stats

+

Get some CountAPI stats

+
https://api.countapi.xyz/stats
+⇒ 200 {
+    "keys_created": ...,
+    "keys_updated": ...,
+    "requests": ...,
+    "version": "..."
+}
+
+ + \ No newline at end of file diff --git a/public/styles/atom-one-dark.min.css b/public/styles/atom-one-dark.min.css new file mode 100644 index 0000000..01c548f --- /dev/null +++ b/public/styles/atom-one-dark.min.css @@ -0,0 +1 @@ +.hljs{display:block;overflow-x:auto;padding:0.5em;color:#abb2bf;background:#282c34}.hljs-comment,.hljs-quote{color:#5c6370;font-style:italic}.hljs-doctag,.hljs-keyword,.hljs-formula{color:#c678dd}.hljs-section,.hljs-name,.hljs-selector-tag,.hljs-deletion,.hljs-subst{color:#e06c75}.hljs-literal{color:#56b6c2}.hljs-string,.hljs-regexp,.hljs-addition,.hljs-attribute,.hljs-meta-string{color:#98c379}.hljs-built_in,.hljs-class .hljs-title{color:#e6c07b}.hljs-attr,.hljs-variable,.hljs-template-variable,.hljs-type,.hljs-selector-class,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-number{color:#d19a66}.hljs-symbol,.hljs-bullet,.hljs-link,.hljs-meta,.hljs-selector-id,.hljs-title{color:#61aeee}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold}.hljs-link{text-decoration:underline} \ No newline at end of file diff --git a/public/styles/countapi.css b/public/styles/countapi.css new file mode 100644 index 0000000..305a9d3 --- /dev/null +++ b/public/styles/countapi.css @@ -0,0 +1,149 @@ +@import url("https://fonts.googleapis.com/css?family=Open+Sans:400,700"); + +* { + margin: 0; + padding: 0; + outline: none; + box-sizing: border-box; + color-scheme: dark; + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; +} + +body { + color: #a0a0a0; +} + +a { + text-decoration: none; + color: #00aaff; +} + +a:hover { + text-decoration: underline; +} + +table { + border-collapse: collapse; + border-spacing: 0; +} + +.header { + padding: 3rem 4rem; + color: white; + text-align: center; + background-color: #7e1fa0; + background-image: linear-gradient(22deg, #7e1fa0, #155899); + box-shadow: inset 0 -2px 2px -2px rgba(0, 0, 0, 0.8); +} + +.header .title { + text-shadow: 1px 1px 5px black; +} + +.header .legend { + font-size: 1.15rem; + font-weight: normal; + margin-top: 0.4rem; + opacity: 0.7; +} + +.container { + max-width: 960px; + margin: auto; + padding: 2rem 4rem; + font-size: 1.1rem; + word-wrap: break-word; +} +.container h1, +.container h2, +.container h3, +.container h4, +.container h5, +.container h6 { + margin-top: 2rem; + margin-bottom: 1rem; + font-weight: normal; + color: #0c57c3; +} +.container h1 { + border-bottom: 1px solid rgba(201, 201, 201, 0.33); +} +.container p { + margin-bottom: 1em; +} +.container ul { + margin-top: 0; + padding: 0.3rem 2.2rem; +} +.container code { + padding: 2px 4px; + background-color: #010101; + border-radius: 4px; +} +.container pre { + white-space: pre-wrap; + word-wrap: break-word; + padding: 10px 10px 10px 20px; + border-radius: 0 5px 5px 0; + font-size: 15px; + border-left: 8px solid #000000; + color: #a0a0a0; + margin-bottom: 1em; +} + +.container pre.info { + border-color: #5087af; + background-color: #2f2f2f; + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; +} + +.container pre.success { + border-color: #50af51; + background-color: #054f05; +} + +.container pre.fail { + border-color: #af5050; + background-color: #4f0505; +} + +.container pre, .container pre a, .container .endpoint { + font-family: Monaco, "Lucida Console", monospace; +} + +.container table { + display: block; + width: 100%; + overflow: auto; + margin-bottom: 1em; +} +.container table th, .container table td { + padding: 0.5rem 1rem; + border: 1px solid #e9ebec; + min-width: 140px; +} +.container .highlight { + white-space: pre; + font-family: monospace; + font-size: 16px; + border-radius: 2px; + margin-bottom: 1em; +} +.container .highlight code { + background-color: rgba(239, 239, 239, 0.1); +} +.container .highlight * { + font-family: monospace; +} + +footer { + padding-top: 1rem; + margin-top: 2rem; + border-top: solid 1px #eff0f1; +} + +@media screen and (max-width: 768px) { + .container { + padding: 2rem 2rem; + } +} \ No newline at end of file