platzky-promocode 0.2.2__tar.gz
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.
- platzky_promocode-0.2.2/LICENSE +21 -0
- platzky_promocode-0.2.2/PKG-INFO +76 -0
- platzky_promocode-0.2.2/README.md +60 -0
- platzky_promocode-0.2.2/platzky_promocode/__init__.py +8 -0
- platzky_promocode-0.2.2/platzky_promocode/plugin.py +117 -0
- platzky_promocode-0.2.2/platzky_promocode/py.typed +0 -0
- platzky_promocode-0.2.2/platzky_promocode/static/540.js +2 -0
- platzky_promocode-0.2.2/platzky_promocode/static/540.js.LICENSE.txt +9 -0
- platzky_promocode-0.2.2/platzky_promocode/static/705.js +1 -0
- platzky_promocode-0.2.2/platzky_promocode/static/remoteEntry.js +1 -0
- platzky_promocode-0.2.2/pyproject.toml +79 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 platzky
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: platzky_promocode
|
|
3
|
+
Version: 0.2.2
|
|
4
|
+
Summary: Plugin for revealing promo codes.
|
|
5
|
+
License: MIT
|
|
6
|
+
Author: ravenw-wing
|
|
7
|
+
Requires-Python: >=3.10,<4.0
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
# platzky-promocode
|
|
17
|
+
|
|
18
|
+
A [platzky](https://github.com/platzky/platzky) plugin that adds a click-to-reveal promo code button.
|
|
19
|
+
|
|
20
|
+
The promo code is never present as plain text in the page — it is base64-encoded and decoded client-side only on click.
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
pip install platzky_promocode
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Configuration
|
|
29
|
+
|
|
30
|
+
Register the plugin in your platzky config:
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"plugins": [
|
|
35
|
+
{
|
|
36
|
+
"name": "promocode",
|
|
37
|
+
"config": {
|
|
38
|
+
"promo_code": "SUMMER24",
|
|
39
|
+
"text": "Reveal your discount",
|
|
40
|
+
"color": "#e63946"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
| Field | Required | Default | Description |
|
|
48
|
+
|---|---|---|---|
|
|
49
|
+
| `promo_code` | yes | — | The code to reveal on click |
|
|
50
|
+
| `text` | no | `"Reveal Promo Code"` | Button label before reveal |
|
|
51
|
+
| `color` | no | `"#4caf50"` | Button background (any CSS color literal) |
|
|
52
|
+
|
|
53
|
+
## Usage in a location pin
|
|
54
|
+
|
|
55
|
+
Add a `promo_code` field to the location data and include it in `visible_data`:
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"promo_code": {
|
|
60
|
+
"code": "SUMMER24",
|
|
61
|
+
"text": "Reveal your discount",
|
|
62
|
+
"color": "#e63946"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
When the plugin is enabled, it automatically detects this field and renders it as an interactive button — no extra markup needed in the location data.
|
|
68
|
+
|
|
69
|
+
## Usage in a Jinja2 template
|
|
70
|
+
|
|
71
|
+
```html
|
|
72
|
+
{{ promocode_button() }}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The button uses the `text`, `color`, and `promo_code` values from the plugin config.
|
|
76
|
+
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# platzky-promocode
|
|
2
|
+
|
|
3
|
+
A [platzky](https://github.com/platzky/platzky) plugin that adds a click-to-reveal promo code button.
|
|
4
|
+
|
|
5
|
+
The promo code is never present as plain text in the page — it is base64-encoded and decoded client-side only on click.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
pip install platzky_promocode
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Configuration
|
|
14
|
+
|
|
15
|
+
Register the plugin in your platzky config:
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"plugins": [
|
|
20
|
+
{
|
|
21
|
+
"name": "promocode",
|
|
22
|
+
"config": {
|
|
23
|
+
"promo_code": "SUMMER24",
|
|
24
|
+
"text": "Reveal your discount",
|
|
25
|
+
"color": "#e63946"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
| Field | Required | Default | Description |
|
|
33
|
+
|---|---|---|---|
|
|
34
|
+
| `promo_code` | yes | — | The code to reveal on click |
|
|
35
|
+
| `text` | no | `"Reveal Promo Code"` | Button label before reveal |
|
|
36
|
+
| `color` | no | `"#4caf50"` | Button background (any CSS color literal) |
|
|
37
|
+
|
|
38
|
+
## Usage in a location pin
|
|
39
|
+
|
|
40
|
+
Add a `promo_code` field to the location data and include it in `visible_data`:
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"promo_code": {
|
|
45
|
+
"code": "SUMMER24",
|
|
46
|
+
"text": "Reveal your discount",
|
|
47
|
+
"color": "#e63946"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
When the plugin is enabled, it automatically detects this field and renders it as an interactive button — no extra markup needed in the location data.
|
|
53
|
+
|
|
54
|
+
## Usage in a Jinja2 template
|
|
55
|
+
|
|
56
|
+
```html
|
|
57
|
+
{{ promocode_button() }}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The button uses the `text`, `color`, and `promo_code` values from the plugin config.
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"""Plugin for revealing promo codes embedded in blog content."""
|
|
2
|
+
|
|
3
|
+
import base64
|
|
4
|
+
import re
|
|
5
|
+
from typing import Any, ClassVar
|
|
6
|
+
|
|
7
|
+
from markupsafe import escape
|
|
8
|
+
from platzky.plugin.content_transformer import ContentTransformerPluginBase
|
|
9
|
+
from platzky.plugin.plugin import ConfigPluginError
|
|
10
|
+
from platzky.shortcodes import Shortcode, ShortcodeAttr, ShortcodeAttrs
|
|
11
|
+
from pydantic import BaseModel, ValidationError, field_validator
|
|
12
|
+
|
|
13
|
+
_COLOR_RE = re.compile(
|
|
14
|
+
r"^(#[0-9a-fA-F]{3,8}"
|
|
15
|
+
r"|rgb\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*\)"
|
|
16
|
+
r"|rgba\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*[\d.]+\s*\)"
|
|
17
|
+
r"|[a-zA-Z]+)$"
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class PromocodeConfig(BaseModel):
|
|
22
|
+
"""Configuration for the Promocode plugin."""
|
|
23
|
+
|
|
24
|
+
color: str = "#4caf50"
|
|
25
|
+
text: str = "Reveal Promo Code"
|
|
26
|
+
|
|
27
|
+
@field_validator("color")
|
|
28
|
+
@classmethod
|
|
29
|
+
def validate_color(cls, v: str) -> str:
|
|
30
|
+
"""Reject values that are not valid CSS color literals."""
|
|
31
|
+
if not _COLOR_RE.match(v.strip()):
|
|
32
|
+
raise ValueError(f"Invalid CSS color: {v!r}")
|
|
33
|
+
return v.strip()
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class _PromocodeShortcode(Shortcode):
|
|
37
|
+
"""Shortcode that renders a reveal button for a promo code."""
|
|
38
|
+
|
|
39
|
+
name = "promocode"
|
|
40
|
+
description = "Reveal a promo code on click. Hidden until clicked."
|
|
41
|
+
attributes: ClassVar[ShortcodeAttrs] = ShortcodeAttrs(
|
|
42
|
+
[ShortcodeAttr("color", "Button colour (any CSS colour literal)", required=False)]
|
|
43
|
+
)
|
|
44
|
+
example = "[promocode]SUMMER2024[/promocode]"
|
|
45
|
+
|
|
46
|
+
def __init__(self, config: PromocodeConfig) -> None:
|
|
47
|
+
"""Initialise with plugin config.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
config: Plugin configuration supplying button text and default colour.
|
|
51
|
+
"""
|
|
52
|
+
self._config = config
|
|
53
|
+
|
|
54
|
+
def render(self, attrs: ShortcodeAttrs, content: str) -> str:
|
|
55
|
+
"""Render a reveal button for the promo code in content.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
attrs: Parsed shortcode attributes; ``color`` overrides the configured colour.
|
|
59
|
+
content: The promo code to encode.
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
A ``<button>`` element that reveals the code on click.
|
|
63
|
+
"""
|
|
64
|
+
code = content.strip()
|
|
65
|
+
encoded = base64.b64encode(code.encode()).decode()
|
|
66
|
+
safe_text = escape(self._config.text)
|
|
67
|
+
color = (
|
|
68
|
+
attrs.color.strip()
|
|
69
|
+
if attrs.color and _COLOR_RE.match(attrs.color.strip())
|
|
70
|
+
else self._config.color
|
|
71
|
+
)
|
|
72
|
+
return (
|
|
73
|
+
f'<button class="platzky-promocode-btn"'
|
|
74
|
+
f' style="--platzky-promocode-color:{color};"'
|
|
75
|
+
f' data-code="{encoded}"'
|
|
76
|
+
f' onclick="platzkyRevealPromocode(this)">'
|
|
77
|
+
f"{safe_text}"
|
|
78
|
+
f"</button>"
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class PromocodePlugin(ContentTransformerPluginBase):
|
|
83
|
+
"""Plugin that registers a ``[promocode]`` shortcode.
|
|
84
|
+
|
|
85
|
+
Blog authors embed promo codes in post content as::
|
|
86
|
+
|
|
87
|
+
[promocode]SAVE20[/promocode]
|
|
88
|
+
|
|
89
|
+
An optional ``color`` attribute overrides the configured button colour::
|
|
90
|
+
|
|
91
|
+
[promocode color="#e91e63"]SAVE20[/promocode]
|
|
92
|
+
|
|
93
|
+
The actual code is base64-encoded in a ``data-code`` attribute and decoded
|
|
94
|
+
client-side via ``atob()`` so it is never present as plain text in the DOM.
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
shortcodes: ClassVar[dict[str, Shortcode]] = {}
|
|
98
|
+
|
|
99
|
+
def __init__(self, _config: dict[str, Any]) -> None:
|
|
100
|
+
"""Initialise the plugin, parse config, and build the shortcode registry.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
_config: Raw configuration dict from the platzky engine.
|
|
104
|
+
|
|
105
|
+
Raises:
|
|
106
|
+
ConfigPluginError: If the configuration is invalid.
|
|
107
|
+
"""
|
|
108
|
+
super().__init__(_config)
|
|
109
|
+
try:
|
|
110
|
+
config = PromocodeConfig.model_validate(_config)
|
|
111
|
+
except ValidationError as e:
|
|
112
|
+
raise ConfigPluginError(f"Invalid configuration: {e}") from e
|
|
113
|
+
self.shortcodes = {"promocode": _PromocodeShortcode(config)} # type: ignore[misc]
|
|
114
|
+
self.config = config
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
Plugin = PromocodePlugin
|
|
File without changes
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! For license information please see 540.js.LICENSE.txt */
|
|
2
|
+
"use strict";(self.webpackChunkplatzky_promocode_frontend=self.webpackChunkplatzky_promocode_frontend||[]).push([[540],{287(e,t){var r=Symbol.for("react.element"),n=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),u=Symbol.for("react.strict_mode"),c=Symbol.for("react.profiler"),a=Symbol.for("react.provider"),f=Symbol.for("react.context"),i=Symbol.for("react.forward_ref"),l=Symbol.for("react.suspense"),s=Symbol.for("react.memo"),p=Symbol.for("react.lazy"),y=Symbol.iterator,d={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},_=Object.assign,h={};function m(e,t,r){this.props=e,this.context=t,this.refs=h,this.updater=r||d}function b(){}function v(e,t,r){this.props=e,this.context=t,this.refs=h,this.updater=r||d}m.prototype.isReactComponent={},m.prototype.setState=function(e,t){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")},m.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},b.prototype=m.prototype;var S=v.prototype=new b;S.constructor=v,_(S,m.prototype),S.isPureReactComponent=!0;var k=Array.isArray,w=Object.prototype.hasOwnProperty,E={current:null},$={key:!0,ref:!0,__self:!0,__source:!0};function R(e,t,n){var o,u={},c=null,a=null;if(null!=t)for(o in void 0!==t.ref&&(a=t.ref),void 0!==t.key&&(c=""+t.key),t)w.call(t,o)&&!$.hasOwnProperty(o)&&(u[o]=t[o]);var f=arguments.length-2;if(1===f)u.children=n;else if(1<f){for(var i=Array(f),l=0;l<f;l++)i[l]=arguments[l+2];u.children=i}if(e&&e.defaultProps)for(o in f=e.defaultProps)void 0===u[o]&&(u[o]=f[o]);return{$$typeof:r,type:e,key:c,ref:a,props:u,_owner:E.current}}function C(e){return"object"==typeof e&&null!==e&&e.$$typeof===r}var g=/\/+/g;function j(e,t){return"object"==typeof e&&null!==e&&null!=e.key?function(e){var t={"=":"=0",":":"=2"};return"$"+e.replace(/[=:]/g,function(e){return t[e]})}(""+e.key):t.toString(36)}function O(e,t,o,u,c){var a=typeof e;"undefined"!==a&&"boolean"!==a||(e=null);var f=!1;if(null===e)f=!0;else switch(a){case"string":case"number":f=!0;break;case"object":switch(e.$$typeof){case r:case n:f=!0}}if(f)return c=c(f=e),e=""===u?"."+j(f,0):u,k(c)?(o="",null!=e&&(o=e.replace(g,"$&/")+"/"),O(c,t,o,"",function(e){return e})):null!=c&&(C(c)&&(c=function(e,t){return{$$typeof:r,type:e.type,key:t,ref:e.ref,props:e.props,_owner:e._owner}}(c,o+(!c.key||f&&f.key===c.key?"":(""+c.key).replace(g,"$&/")+"/")+e)),t.push(c)),1;if(f=0,u=""===u?".":u+":",k(e))for(var i=0;i<e.length;i++){var l=u+j(a=e[i],i);f+=O(a,t,o,l,c)}else if(l=function(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=y&&e[y]||e["@@iterator"])?e:null}(e),"function"==typeof l)for(e=l.call(e),i=0;!(a=e.next()).done;)f+=O(a=a.value,t,o,l=u+j(a,i++),c);else if("object"===a)throw t=String(e),Error("Objects are not valid as a React child (found: "+("[object Object]"===t?"object with keys {"+Object.keys(e).join(", ")+"}":t)+"). If you meant to render a collection of children, use an array instead.");return f}function x(e,t,r){if(null==e)return e;var n=[],o=0;return O(e,n,"","",function(e){return t.call(r,e,o++)}),n}function P(e){if(-1===e._status){var t=e._result;(t=t()).then(function(t){0!==e._status&&-1!==e._status||(e._status=1,e._result=t)},function(t){0!==e._status&&-1!==e._status||(e._status=2,e._result=t)}),-1===e._status&&(e._status=0,e._result=t)}if(1===e._status)return e._result.default;throw e._result}var I={current:null},T={transition:null},V={ReactCurrentDispatcher:I,ReactCurrentBatchConfig:T,ReactCurrentOwner:E};function A(){throw Error("act(...) is not supported in production builds of React.")}t.Children={map:x,forEach:function(e,t,r){x(e,function(){t.apply(this,arguments)},r)},count:function(e){var t=0;return x(e,function(){t++}),t},toArray:function(e){return x(e,function(e){return e})||[]},only:function(e){if(!C(e))throw Error("React.Children.only expected to receive a single React element child.");return e}},t.Component=m,t.Fragment=o,t.Profiler=c,t.PureComponent=v,t.StrictMode=u,t.Suspense=l,t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=V,t.act=A,t.cloneElement=function(e,t,n){if(null==e)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+e+".");var o=_({},e.props),u=e.key,c=e.ref,a=e._owner;if(null!=t){if(void 0!==t.ref&&(c=t.ref,a=E.current),void 0!==t.key&&(u=""+t.key),e.type&&e.type.defaultProps)var f=e.type.defaultProps;for(i in t)w.call(t,i)&&!$.hasOwnProperty(i)&&(o[i]=void 0===t[i]&&void 0!==f?f[i]:t[i])}var i=arguments.length-2;if(1===i)o.children=n;else if(1<i){f=Array(i);for(var l=0;l<i;l++)f[l]=arguments[l+2];o.children=f}return{$$typeof:r,type:e.type,key:u,ref:c,props:o,_owner:a}},t.createContext=function(e){return(e={$$typeof:f,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null}).Provider={$$typeof:a,_context:e},e.Consumer=e},t.createElement=R,t.createFactory=function(e){var t=R.bind(null,e);return t.type=e,t},t.createRef=function(){return{current:null}},t.forwardRef=function(e){return{$$typeof:i,render:e}},t.isValidElement=C,t.lazy=function(e){return{$$typeof:p,_payload:{_status:-1,_result:e},_init:P}},t.memo=function(e,t){return{$$typeof:s,type:e,compare:void 0===t?null:t}},t.startTransition=function(e){var t=T.transition;T.transition={};try{e()}finally{T.transition=t}},t.unstable_act=A,t.useCallback=function(e,t){return I.current.useCallback(e,t)},t.useContext=function(e){return I.current.useContext(e)},t.useDebugValue=function(){},t.useDeferredValue=function(e){return I.current.useDeferredValue(e)},t.useEffect=function(e,t){return I.current.useEffect(e,t)},t.useId=function(){return I.current.useId()},t.useImperativeHandle=function(e,t,r){return I.current.useImperativeHandle(e,t,r)},t.useInsertionEffect=function(e,t){return I.current.useInsertionEffect(e,t)},t.useLayoutEffect=function(e,t){return I.current.useLayoutEffect(e,t)},t.useMemo=function(e,t){return I.current.useMemo(e,t)},t.useReducer=function(e,t,r){return I.current.useReducer(e,t,r)},t.useRef=function(e){return I.current.useRef(e)},t.useState=function(e){return I.current.useState(e)},t.useSyncExternalStore=function(e,t,r){return I.current.useSyncExternalStore(e,t,r)},t.useTransition=function(){return I.current.useTransition()},t.version="18.3.1"},540(e,t,r){e.exports=r(287)}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunkplatzky_promocode_frontend=self.webpackChunkplatzky_promocode_frontend||[]).push([[705],{705(r,t,e){e.r(t),e.d(t,{default:()=>a});var n=e(914);function o(r,t){(null==t||t>r.length)&&(t=r.length);for(var e=0,n=Array(t);e<t;e++)n[e]=r[e];return n}function a(r){var t,e,a=r.code,l=r.text,i=r.color,u=(t=(0,n.useState)(!1),e=2,function(r){if(Array.isArray(r))return r}(t)||function(r,t){var e=null==r?null:"undefined"!=typeof Symbol&&r[Symbol.iterator]||r["@@iterator"];if(null!=e){var n,o,a,l,i=[],u=!0,c=!1;try{if(a=(e=e.call(r)).next,0===t){if(Object(e)!==e)return;u=!1}else for(;!(u=(n=a.call(e)).done)&&(i.push(n.value),i.length!==t);u=!0);}catch(r){c=!0,o=r}finally{try{if(!u&&null!=e.return&&(l=e.return(),Object(l)!==l))return}finally{if(c)throw o}}return i}}(t,e)||function(r,t){if(r){if("string"==typeof r)return o(r,t);var e={}.toString.call(r).slice(8,-1);return"Object"===e&&r.constructor&&(e=r.constructor.name),"Map"===e||"Set"===e?Array.from(r):"Arguments"===e||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e)?o(r,t):void 0}}(t,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),c=u[0],f=u[1];return n.createElement("button",{type:"button",onClick:function(){return!c&&f(!0)},style:{backgroundColor:c?"#333":i,border:"none",borderRadius:"4px",color:"#fff",cursor:c?"default":"pointer",fontFamily:c?"monospace":"inherit",fontSize:"1rem",letterSpacing:c?"0.1em":"normal",padding:"0.5rem 1.25rem",transition:"opacity 0.2s"}},c?atob(a):l)}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var promocode;(()=>{"use strict";var e,r,t,o,n,a,i,u,l,f,s,p,d,c,h,v,g,m,b,y={623(e,r,t){var o={"./Button":()=>t.e(705).then(()=>()=>t(705))},n=(e,r)=>(t.R=r,r=t.o(o,e)?o[e]():Promise.resolve().then(()=>{throw new Error('Module "'+e+'" does not exist in container.')}),t.R=void 0,r),a=(e,r)=>{if(t.S){var o="default",n=t.S[o];if(n&&n!==e)throw new Error("Container initialization failed as it has already been initialized with a different share scope");return t.S[o]=e,t.I(o,r)}};t.d(r,{get:()=>n,init:()=>a})}},w={};function S(e){var r=w[e];if(void 0!==r)return r.exports;var t=w[e]={exports:{}};return y[e](t,t.exports,S),t.exports}S.m=y,S.c=w,S.d=(e,r)=>{for(var t in r)S.o(r,t)&&!S.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},S.f={},S.e=e=>Promise.all(Object.keys(S.f).reduce((r,t)=>(S.f[t](e,r),r),[])),S.u=e=>e+".js",S.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),S.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),e={},r="platzky-promocode-frontend:",S.l=(t,o,n,a)=>{if(e[t])e[t].push(o);else{var i,u;if(void 0!==n)for(var l=document.getElementsByTagName("script"),f=0;f<l.length;f++){var s=l[f];if(s.getAttribute("src")==t||s.getAttribute("data-webpack")==r+n){i=s;break}}i||(u=!0,(i=document.createElement("script")).charset="utf-8",S.nc&&i.setAttribute("nonce",S.nc),i.setAttribute("data-webpack",r+n),i.src=t),e[t]=[o];var p=(r,o)=>{i.onerror=i.onload=null,clearTimeout(d);var n=e[t];if(delete e[t],i.parentNode&&i.parentNode.removeChild(i),n&&n.forEach(e=>e(o)),r)return r(o)},d=setTimeout(p.bind(null,void 0,{type:"timeout",target:i}),12e4);i.onerror=p.bind(null,i.onerror),i.onload=p.bind(null,i.onload),u&&document.head.appendChild(i)}},S.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{S.S={};var e={},r={};S.I=(t,o)=>{o||(o=[]);var n=r[t];if(n||(n=r[t]={}),!(o.indexOf(n)>=0)){if(o.push(n),e[t])return e[t];S.o(S.S,t)||(S.S[t]={});var a=S.S[t],i="platzky-promocode-frontend",u=[];return"default"===t&&((e,r,t,o)=>{var n=a[e]=a[e]||{},u=n[r];(!u||!u.loaded&&(1!=!u.eager?o:i>u.from))&&(n[r]={get:()=>S.e(540).then(()=>()=>S(540)),from:i,eager:!1})})("react","18.3.1"),e[t]=u.length?Promise.all(u).then(()=>e[t]=1):1}}})(),(()=>{var e;S.g.importScripts&&(e=S.g.location+"");var r=S.g.document;if(!e&&r&&(r.currentScript&&"SCRIPT"===r.currentScript.tagName.toUpperCase()&&(e=r.currentScript.src),!e)){var t=r.getElementsByTagName("script");if(t.length)for(var o=t.length-1;o>-1&&(!e||!/^http(s?):/.test(e));)e=t[o--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),S.p=e})(),t=e=>{var r=e=>e.split(".").map(e=>+e==e?+e:e),t=/^([^-+]+)?(?:-([^+]+))?(?:\+(.+))?$/.exec(e),o=t[1]?r(t[1]):[];return t[2]&&(o.length++,o.push.apply(o,r(t[2]))),t[3]&&(o.push([]),o.push.apply(o,r(t[3]))),o},o=(e,r)=>{e=t(e),r=t(r);for(var o=0;;){if(o>=e.length)return o<r.length&&"u"!=(typeof r[o])[0];var n=e[o],a=(typeof n)[0];if(o>=r.length)return"u"==a;var i=r[o],u=(typeof i)[0];if(a!=u)return"o"==a&&"n"==u||"s"==u||"u"==a;if("o"!=a&&"u"!=a&&n!=i)return n<i;o++}},n=e=>{var r=e[0],t="";if(1===e.length)return"*";if(r+.5){t+=0==r?">=":-1==r?"<":1==r?"^":2==r?"~":r>0?"=":"!=";for(var o=1,a=1;a<e.length;a++)o--,t+="u"==(typeof(u=e[a]))[0]?"-":(o>0?".":"")+(o=2,u);return t}var i=[];for(a=1;a<e.length;a++){var u=e[a];i.push(0===u?"not("+l()+")":1===u?"("+l()+" || "+l()+")":2===u?i.pop()+" "+i.pop():n(u))}return l();function l(){return i.pop().replace(/^\((.+)\)$/,"$1")}},a=(e,r)=>{if(0 in e){r=t(r);var o=e[0],n=o<0;n&&(o=-o-1);for(var i=0,u=1,l=!0;;u++,i++){var f,s,p=u<e.length?(typeof e[u])[0]:"";if(i>=r.length||"o"==(s=(typeof(f=r[i]))[0]))return!l||("u"==p?u>o&&!n:""==p!=n);if("u"==s){if(!l||"u"!=p)return!1}else if(l)if(p==s)if(u<=o){if(f!=e[u])return!1}else{if(n?f>e[u]:f<e[u])return!1;f!=e[u]&&(l=!1)}else if("s"!=p&&"n"!=p){if(n||u<=o)return!1;l=!1,u--}else{if(u<=o||s<p!=n)return!1;l=!1}else"s"!=p&&"n"!=p&&(l=!1,u--)}}var d=[],c=d.pop.bind(d);for(i=1;i<e.length;i++){var h=e[i];d.push(1==h?c()|c():2==h?c()&c():h?a(h,r):!c())}return!!c()},i=(e,r)=>e&&S.o(e,r),u=e=>(e.loaded=1,e.get()),l=e=>Object.keys(e).reduce((r,t)=>(e[t].eager&&(r[t]=e[t]),r),{}),f=(e,r,t)=>{var n=t?l(e[r]):e[r];return Object.keys(n).reduce((e,r)=>!e||!n[e].loaded&&o(e,r)?r:e,0)},s=(e,r,t,o)=>"Unsatisfied version "+t+" from "+(t&&e[r][t].from)+" of shared singleton module "+r+" (required "+n(o)+")",p=e=>{throw new Error(e)},d=e=>{"undefined"!=typeof console&&console.warn&&console.warn(e)},c=(e,r,t)=>t?t():((e,r)=>p("Shared module "+r+" doesn't exist in shared scope "+e))(e,r),h=(e=>function(r,t,o,n,a){var i=S.I(r);return i&&i.then&&!o?i.then(e.bind(e,r,S.S[r],t,!1,n,a)):e(r,S.S[r],t,o,n,a)})((e,r,t,o,n,l)=>{if(!i(r,t))return c(e,t,l);var p=f(r,t,o);return a(n,p)||d(s(r,t,p,n)),u(r[t][p])}),v={},g={914:()=>h("default","react",!1,[1,18,2,0],()=>S.e(540).then(()=>()=>S(540)))},m={705:[914]},b={},S.f.consumes=(e,r)=>{S.o(m,e)&&m[e].forEach(e=>{if(S.o(v,e))return r.push(v[e]);if(!b[e]){var t=r=>{v[e]=0,S.m[e]=t=>{delete S.c[e],t.exports=r()}};b[e]=!0;var o=r=>{delete v[e],S.m[e]=t=>{throw delete S.c[e],r}};try{var n=g[e]();n.then?r.push(v[e]=n.then(t).catch(o)):t(n)}catch(e){o(e)}}})},(()=>{var e={223:0};S.f.j=(r,t)=>{var o=S.o(e,r)?e[r]:void 0;if(0!==o)if(o)t.push(o[2]);else{var n=new Promise((t,n)=>o=e[r]=[t,n]);t.push(o[2]=n);var a=S.p+S.u(r),i=new Error;S.l(a,t=>{if(S.o(e,r)&&(0!==(o=e[r])&&(e[r]=void 0),o)){var n=t&&("load"===t.type?"missing":t.type),a=t&&t.target&&t.target.src;i.message="Loading chunk "+r+" failed.\n("+n+": "+a+")",i.name="ChunkLoadError",i.type=n,i.request=a,o[1](i)}},"chunk-"+r,r)}};var r=(r,t)=>{var o,n,[a,i,u]=t,l=0;if(a.some(r=>0!==e[r])){for(o in i)S.o(i,o)&&(S.m[o]=i[o]);u&&u(S)}for(r&&r(t);l<a.length;l++)n=a[l],S.o(e,n)&&e[n]&&e[n][0](),e[n]=0},t=self.webpackChunkplatzky_promocode_frontend=self.webpackChunkplatzky_promocode_frontend||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})();var k=S(623);promocode=k})();
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["poetry-core"]
|
|
3
|
+
build-backend = "poetry.core.masonry.api"
|
|
4
|
+
|
|
5
|
+
[tool.poetry]
|
|
6
|
+
name = "platzky_promocode"
|
|
7
|
+
version = "0.2.2"
|
|
8
|
+
description = "Plugin for revealing promo codes."
|
|
9
|
+
authors = ["ravenw-wing"]
|
|
10
|
+
license = "MIT"
|
|
11
|
+
readme = "README.md"
|
|
12
|
+
include = ["platzky_promocode/static/**"]
|
|
13
|
+
|
|
14
|
+
[tool.poetry.dependencies]
|
|
15
|
+
python = "^3.10"
|
|
16
|
+
|
|
17
|
+
[tool.poetry.plugins."platzky.plugins"]
|
|
18
|
+
promocode = "platzky_promocode.plugin:PromocodePlugin"
|
|
19
|
+
|
|
20
|
+
[tool.poetry.group.dev.dependencies]
|
|
21
|
+
pytest = "^9.0.3"
|
|
22
|
+
black = "^26.3.1"
|
|
23
|
+
ruff = "^0.8.3"
|
|
24
|
+
pyright = "^1.1.390"
|
|
25
|
+
coverage = "^7.6.9"
|
|
26
|
+
interrogate = "^1.7.0"
|
|
27
|
+
platzky = "2.0.0a0"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
[tool.black]
|
|
31
|
+
line-length = 100
|
|
32
|
+
target-version = ["py310"]
|
|
33
|
+
|
|
34
|
+
[tool.ruff]
|
|
35
|
+
line-length = 100
|
|
36
|
+
target-version = "py310"
|
|
37
|
+
show-fixes = true
|
|
38
|
+
|
|
39
|
+
[tool.ruff.lint]
|
|
40
|
+
select = [
|
|
41
|
+
"I",
|
|
42
|
+
"F",
|
|
43
|
+
"E",
|
|
44
|
+
"W",
|
|
45
|
+
"PT",
|
|
46
|
+
"RUF",
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
[tool.pyright]
|
|
50
|
+
pythonVersion = "3.10"
|
|
51
|
+
pythonPlatform = "All"
|
|
52
|
+
typeCheckingMode = "strict"
|
|
53
|
+
reportMissingImports = true
|
|
54
|
+
reportMissingTypeStubs = false
|
|
55
|
+
reportMissingParameterType = true
|
|
56
|
+
reportUnknownArgumentType = true
|
|
57
|
+
reportUnknownMemberType = true
|
|
58
|
+
reportUnknownVariableType = true
|
|
59
|
+
reportUnknownParameterType = true
|
|
60
|
+
reportUnnecessaryTypeIgnoreComment = true
|
|
61
|
+
reportUntypedClassDecorator = false
|
|
62
|
+
reportUntypedFunctionDecorator = false
|
|
63
|
+
reportUnnecessaryIsInstance = false
|
|
64
|
+
reportUnusedFunction = true
|
|
65
|
+
reportUntypedBaseClass = false
|
|
66
|
+
|
|
67
|
+
[tool.pytest.ini_options]
|
|
68
|
+
markers = [
|
|
69
|
+
"skip_coverage: skip coverage for this test",
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
[tool.interrogate]
|
|
73
|
+
fail-under = 95
|
|
74
|
+
ignore-init-method = true
|
|
75
|
+
ignore-init-module = true
|
|
76
|
+
ignore-magic = true
|
|
77
|
+
ignore-private = true
|
|
78
|
+
ignore-semiprivate = false
|
|
79
|
+
exclude = ["tests", "docs"]
|