nurev 0.0.1

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.
package/.meta/logo.svg ADDED
@@ -0,0 +1 @@
1
+ <svg width="200" xmlns="http://www.w3.org/2000/svg" height="200" id="screenshot-7b447149-cc30-80f8-8007-b7a021614b85" viewBox="0 0 200 200" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1"><g id="shape-7b447149-cc30-80f8-8007-b7a021614b85"><defs><clipPath id="frame-clip-7b447149-cc30-80f8-8007-b7a021614b85-render-1" class="frame-clip frame-clip-def"><rect rx="0" ry="0" x="0" y="0" width="200" height="200" transform="matrix(1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000)"/></clipPath></defs><g class="frame-container-wrapper"><g class="frame-container-blur"><g class="frame-container-shadows"><g clip-path="url(#frame-clip-7b447149-cc30-80f8-8007-b7a021614b85-render-1)" fill="none"><g class="fills" id="fills-7b447149-cc30-80f8-8007-b7a021614b85"><rect rx="0" ry="0" x="0" y="0" width="200" height="200" transform="matrix(1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000)" class="frame-background"/></g><g class="frame-children"><g id="shape-7b447149-cc30-80f8-8007-b7a9724decbe" rx="0" ry="0"><g id="shape-d133dad3-fb84-80f9-8007-b79d281df1d7"><defs><linearGradient id="fill-color-gradient-render-3-0" x1="0.4760093075001731" y1="-0.1745974308781364" x2="0.4882827912279839" y2="1.289055952997602" gradientTransform=""><stop offset="0" stop-color="#0b0859" stop-opacity="1"/><stop offset="1" stop-color="#130ea3" stop-opacity="0.9656862745098039"/></linearGradient><pattern patternUnits="userSpaceOnUse" x="-5.684341886080802e-14" y="1.4210854715202004e-14" width="200.00000000000006" height="200" id="fill-0-render-3"><g><rect width="200.00000000000006" height="200" style="fill: url(&quot;#fill-color-gradient-render-3-0&quot;);"/></g></pattern></defs><g class="fills" id="fills-d133dad3-fb84-80f9-8007-b79d281df1d7"><ellipse cx="99.99999999999997" cy="100.00000000000001" rx="100.00000000000003" ry="100" transform="matrix(0.707107, 0.707107, -0.707107, 0.707107, 100.000000, -41.421356)" fill="url(#fill-0-render-3)"/></g></g><g id="shape-f465bcc1-4510-80b3-8007-b7f123c508b7"><g class="fills" id="fills-f465bcc1-4510-80b3-8007-b7f123c508b7"><path d="M153.03302001953125,46.96702575683594C182.302734375,76.23672485351562,182.302734375,123.76332092285156,153.03302001953125,153.03305053710938C123.7633056640625,182.30276489257812,76.23672485351562,182.302734375,46.967010498046875,153.03302001953125C17.697296142578125,123.76332092285156,17.697296142578125,76.23672485351562,46.967010498046875,46.96702575683594C76.23672485351562,17.697303771972656,123.7633056640625,17.69731903076172,153.03302001953125,46.96702575683594"/></g><g id="strokes-e5478d5c-56d4-80ce-8007-b7f5b5506b20-f465bcc1-4510-80b3-8007-b7f123c508b7" class="strokes"><g class="inner-stroke-shape"><defs><clipPath id="inner-stroke-render-4-f465bcc1-4510-80b3-8007-b7f123c508b7-0"><use href="#stroke-shape-render-4-f465bcc1-4510-80b3-8007-b7f123c508b7-0"/></clipPath><path d="M153.03302001953125,46.96702575683594C182.302734375,76.23672485351562,182.302734375,123.76332092285156,153.03302001953125,153.03305053710938C123.7633056640625,182.30276489257812,76.23672485351562,182.302734375,46.967010498046875,153.03302001953125C17.697296142578125,123.76332092285156,17.697296142578125,76.23672485351562,46.967010498046875,46.96702575683594C76.23672485351562,17.697303771972656,123.7633056640625,17.69731903076172,153.03302001953125,46.96702575683594" id="stroke-shape-render-4-f465bcc1-4510-80b3-8007-b7f123c508b7-0" style="fill: none; stroke-width: 12; stroke: rgb(255, 255, 255); stroke-opacity: 1;"/></defs><use href="#stroke-shape-render-4-f465bcc1-4510-80b3-8007-b7f123c508b7-0" clip-path="url('#inner-stroke-render-4-f465bcc1-4510-80b3-8007-b7f123c508b7-0')"/></g></g></g><g id="shape-f465bcc1-4510-80b3-8007-b7f1af121f3c"><defs><linearGradient id="fill-color-gradient-render-5-0" x1="0.4760093075001731" y1="-0.1745974308781364" x2="0.4882827912279839" y2="1.289055952997602" gradientTransform=""><stop offset="0" stop-color="#0b0859" stop-opacity="1"/><stop offset="1" stop-color="#130ea3" stop-opacity="0.9656862745098039"/></linearGradient><pattern patternUnits="userSpaceOnUse" x="30.502525316941615" y="30.502525316941615" width="40" height="40" patternTransform="matrix(0.707107, 0.707107, -0.707107, 0.707107, 50.502525, -20.918831)" id="fill-0-render-5"><g><rect width="40" height="40" style="fill: url(&quot;#fill-color-gradient-render-5-0&quot;);"/></g></pattern></defs><g class="fills" id="fills-f465bcc1-4510-80b3-8007-b7f1af121f3c"><path d="M64.6446533203125,36.360382080078125C72.44992065429688,44.1656494140625,72.44992065429688,56.83940124511719,64.6446533203125,64.6446533203125C56.83941650390625,72.44992065429688,44.1656494140625,72.44992065429688,36.360382080078125,64.6446533203125C28.555145263671875,56.83940124511719,28.555145263671875,44.1656494140625,36.360382080078125,36.360382080078125C44.1656494140625,28.555130004882812,56.83941650390625,28.555130004882812,64.6446533203125,36.360382080078125" fill="url(#fill-0-render-5)"/></g><g id="strokes-e5478d5c-56d4-80ce-8007-b7f5b5517148-f465bcc1-4510-80b3-8007-b7f1af121f3c" class="strokes"><g class="inner-stroke-shape"><defs><clipPath id="inner-stroke-render-5-f465bcc1-4510-80b3-8007-b7f1af121f3c-0"><use href="#stroke-shape-render-5-f465bcc1-4510-80b3-8007-b7f1af121f3c-0"/></clipPath><path d="M64.6446533203125,36.360382080078125C72.44992065429688,44.1656494140625,72.44992065429688,56.83940124511719,64.6446533203125,64.6446533203125C56.83941650390625,72.44992065429688,44.1656494140625,72.44992065429688,36.360382080078125,64.6446533203125C28.555145263671875,56.83940124511719,28.555145263671875,44.1656494140625,36.360382080078125,36.360382080078125C44.1656494140625,28.555130004882812,56.83941650390625,28.555130004882812,64.6446533203125,36.360382080078125" id="stroke-shape-render-5-f465bcc1-4510-80b3-8007-b7f1af121f3c-0" style="fill: none; stroke-width: 12; stroke: rgb(255, 255, 255); stroke-opacity: 1;"/></defs><use href="#stroke-shape-render-5-f465bcc1-4510-80b3-8007-b7f1af121f3c-0" clip-path="url('#inner-stroke-render-5-f465bcc1-4510-80b3-8007-b7f1af121f3c-0')"/></g></g></g><g id="shape-f465bcc1-4510-80b3-8007-b7f1de15c29d"><defs><linearGradient id="fill-color-gradient-render-6-0" x1="0.4760093075001731" y1="-0.1745974308781364" x2="0.4882827912279839" y2="1.289055952997602" gradientTransform=""><stop offset="0" stop-color="#0b0859" stop-opacity="1"/><stop offset="1" stop-color="#130ea3" stop-opacity="0.9656862745098039"/></linearGradient><pattern patternUnits="userSpaceOnUse" x="129.49747468305839" y="129.4974746830584" width="40" height="39.99999999999986" patternTransform="matrix(0.707107, 0.707107, -0.707107, 0.707107, 149.497475, -61.923882)" id="fill-0-render-6"><g><rect width="40" height="39.99999999999986" style="fill: url(&quot;#fill-color-gradient-render-6-0&quot;);"/></g></pattern></defs><g class="fills" id="fills-f465bcc1-4510-80b3-8007-b7f1de15c29d"><path d="M163.63961791992188,135.3553466796875C171.44485473632812,143.1605987548828,171.44485473632812,155.8343505859375,163.63961791992188,163.63961791992188C155.8343505859375,171.44485473632812,143.16058349609375,171.44485473632812,135.3553466796875,163.63961791992188C127.55007934570312,155.8343505859375,127.55007934570312,143.1605987548828,135.3553466796875,135.3553466796875C143.16058349609375,127.55007934570312,155.8343505859375,127.55007934570312,163.63961791992188,135.3553466796875" fill="url(#fill-0-render-6)"/></g><g id="strokes-e5478d5c-56d4-80ce-8007-b7f5b551e5c5-f465bcc1-4510-80b3-8007-b7f1de15c29d" class="strokes"><g class="inner-stroke-shape"><defs><clipPath id="inner-stroke-render-6-f465bcc1-4510-80b3-8007-b7f1de15c29d-0"><use href="#stroke-shape-render-6-f465bcc1-4510-80b3-8007-b7f1de15c29d-0"/></clipPath><path d="M163.63961791992188,135.3553466796875C171.44485473632812,143.1605987548828,171.44485473632812,155.8343505859375,163.63961791992188,163.63961791992188C155.8343505859375,171.44485473632812,143.16058349609375,171.44485473632812,135.3553466796875,163.63961791992188C127.55007934570312,155.8343505859375,127.55007934570312,143.1605987548828,135.3553466796875,135.3553466796875C143.16058349609375,127.55007934570312,155.8343505859375,127.55007934570312,163.63961791992188,135.3553466796875" id="stroke-shape-render-6-f465bcc1-4510-80b3-8007-b7f1de15c29d-0" style="fill: none; stroke-width: 12; stroke: rgb(255, 255, 255); stroke-opacity: 1;"/></defs><use href="#stroke-shape-render-6-f465bcc1-4510-80b3-8007-b7f1de15c29d-0" clip-path="url('#inner-stroke-render-6-f465bcc1-4510-80b3-8007-b7f1de15c29d-0')"/></g></g></g><g id="shape-f465bcc1-4510-80b3-8007-b7f3b10b1663"><g class="fills" id="fills-f465bcc1-4510-80b3-8007-b7f3b10b1663"><path d="M167.17514038085938,131.81980895996094C176.93170166015625,141.57640075683594,176.93170166015625,157.4185791015625,167.17514038085938,167.17514038085938C157.41854858398438,176.93173217773438,141.57632446289062,176.93170166015625,131.81979370117188,167.17514038085938C122.063232421875,157.4185791015625,122.063232421875,141.57638549804688,131.81979370117188,131.81980895996094C141.57635498046875,122.06324768066406,157.41854858398438,122.063232421875,167.17514038085938,131.81980895996094"/></g><g id="strokes-e5478d5c-56d4-80ce-8007-b7f5b5521573-f465bcc1-4510-80b3-8007-b7f3b10b1663" class="strokes"><g class="inner-stroke-shape"><defs><linearGradient id="stroke-color-gradient-render-7-0" x1="0.4760093075001731" y1="-0.1745974308781364" x2="0.4882827912279839" y2="1.289055952997602" gradientTransform="matrix(0.707107, 0.707107, -0.707107, 0.707107, 0.500000, -0.207107)"><stop offset="0" stop-color="#0b0859" stop-opacity="1"/><stop offset="1" stop-color="#130ea3" stop-opacity="0.9656862745098039"/></linearGradient><clipPath id="inner-stroke-render-7-f465bcc1-4510-80b3-8007-b7f3b10b1663-0"><use href="#stroke-shape-render-7-f465bcc1-4510-80b3-8007-b7f3b10b1663-0"/></clipPath><path d="M167.17514038085938,131.81980895996094C176.93170166015625,141.57640075683594,176.93170166015625,157.4185791015625,167.17514038085938,167.17514038085938C157.41854858398438,176.93173217773438,141.57632446289062,176.93170166015625,131.81979370117188,167.17514038085938C122.063232421875,157.4185791015625,122.063232421875,141.57638549804688,131.81979370117188,131.81980895996094C141.57635498046875,122.06324768066406,157.41854858398438,122.063232421875,167.17514038085938,131.81980895996094" id="stroke-shape-render-7-f465bcc1-4510-80b3-8007-b7f3b10b1663-0" style="fill: none; stroke-width: 10; stroke: url(&quot;#stroke-color-gradient-render-7-0&quot;);"/></defs><use href="#stroke-shape-render-7-f465bcc1-4510-80b3-8007-b7f3b10b1663-0" clip-path="url('#inner-stroke-render-7-f465bcc1-4510-80b3-8007-b7f3b10b1663-0')"/></g></g></g><g id="shape-f465bcc1-4510-80b3-8007-b7f3dcc1f313"><g class="fills" id="fills-f465bcc1-4510-80b3-8007-b7f3dcc1f313"><path d="M68.18020629882812,32.824859619140625C77.936767578125,42.58143615722656,77.936767578125,58.42362976074219,68.18020629882812,68.18019104003906C58.423614501953125,77.936767578125,42.581390380859375,77.93672180175781,32.824859619140625,68.18019104003906C23.068267822265625,58.423614501953125,23.068267822265625,42.58143615722656,32.824859619140625,32.824859619140625C42.5814208984375,23.068283081054688,58.423614501953125,23.068283081054688,68.18020629882812,32.824859619140625"/></g><g id="strokes-e5478d5c-56d4-80ce-8007-b7f5b5528963-f465bcc1-4510-80b3-8007-b7f3dcc1f313" class="strokes"><g class="inner-stroke-shape"><defs><linearGradient id="stroke-color-gradient-render-8-0" x1="0.4760093075001731" y1="-0.1745974308781364" x2="0.4882827912279839" y2="1.289055952997602" gradientTransform="matrix(0.707107, 0.707107, -0.707107, 0.707107, 0.500000, -0.207107)"><stop offset="0" stop-color="#0b0859" stop-opacity="1"/><stop offset="1" stop-color="#130ea3" stop-opacity="0.9656862745098039"/></linearGradient><clipPath id="inner-stroke-render-8-f465bcc1-4510-80b3-8007-b7f3dcc1f313-0"><use href="#stroke-shape-render-8-f465bcc1-4510-80b3-8007-b7f3dcc1f313-0"/></clipPath><path d="M68.18020629882812,32.824859619140625C77.936767578125,42.58143615722656,77.936767578125,58.42362976074219,68.18020629882812,68.18019104003906C58.423614501953125,77.936767578125,42.581390380859375,77.93672180175781,32.824859619140625,68.18019104003906C23.068267822265625,58.423614501953125,23.068267822265625,42.58143615722656,32.824859619140625,32.824859619140625C42.5814208984375,23.068283081054688,58.423614501953125,23.068283081054688,68.18020629882812,32.824859619140625" id="stroke-shape-render-8-f465bcc1-4510-80b3-8007-b7f3dcc1f313-0" style="fill: none; stroke-width: 10; stroke: url(&quot;#stroke-color-gradient-render-8-0&quot;);"/></defs><use href="#stroke-shape-render-8-f465bcc1-4510-80b3-8007-b7f3dcc1f313-0" clip-path="url('#inner-stroke-render-8-f465bcc1-4510-80b3-8007-b7f3dcc1f313-0')"/></g></g></g></g></g></g></g></g></g></g></svg>
package/README.md ADDED
@@ -0,0 +1,11 @@
1
+ <p align="center">
2
+ <img src ="https://codeberg.org/Serroda/nurev/raw/branch/main/.meta/logo.svg" width="200"/>
3
+ </p>
4
+
5
+ # Nurev
6
+
7
+ Template generator for [Nuxt](https://nuxt.com/) configured with “on-demand revalidation” and support for multiple backends (WIP)
8
+
9
+ ## Available backends
10
+
11
+ - [PocketBase](https://pocketbase.io/)
package/bun.lock ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "lockfileVersion": 1,
3
+ "configVersion": 1,
4
+ "workspaces": {
5
+ "": {
6
+ "name": "nurev",
7
+ "dependencies": {
8
+ "fs-extra": "^11.3.4",
9
+ "prompts": "^2.4.2",
10
+ },
11
+ "devDependencies": {
12
+ "@types/bun": "latest",
13
+ "@types/fs-extra": "^11.0.4",
14
+ "@types/prompts": "^2.4.9",
15
+ },
16
+ "peerDependencies": {
17
+ "typescript": "^5",
18
+ },
19
+ },
20
+ },
21
+ "packages": {
22
+ "@types/bun": ["@types/bun@1.3.11", "", { "dependencies": { "bun-types": "1.3.11" } }, "sha512-5vPne5QvtpjGpsGYXiFyycfpDF2ECyPcTSsFBMa0fraoxiQyMJ3SmuQIGhzPg2WJuWxVBoxWJ2kClYTcw/4fAg=="],
23
+
24
+ "@types/fs-extra": ["@types/fs-extra@11.0.4", "", { "dependencies": { "@types/jsonfile": "*", "@types/node": "*" } }, "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ=="],
25
+
26
+ "@types/jsonfile": ["@types/jsonfile@6.1.4", "", { "dependencies": { "@types/node": "*" } }, "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ=="],
27
+
28
+ "@types/node": ["@types/node@25.5.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw=="],
29
+
30
+ "@types/prompts": ["@types/prompts@2.4.9", "", { "dependencies": { "@types/node": "*", "kleur": "^3.0.3" } }, "sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA=="],
31
+
32
+ "bun-types": ["bun-types@1.3.11", "", { "dependencies": { "@types/node": "*" } }, "sha512-1KGPpoxQWl9f6wcZh57LvrPIInQMn2TQ7jsgxqpRzg+l0QPOFvJVH7HmvHo/AiPgwXy+/Thf6Ov3EdVn1vOabg=="],
33
+
34
+ "fs-extra": ["fs-extra@11.3.4", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA=="],
35
+
36
+ "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
37
+
38
+ "jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="],
39
+
40
+ "kleur": ["kleur@3.0.3", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="],
41
+
42
+ "prompts": ["prompts@2.4.2", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="],
43
+
44
+ "sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="],
45
+
46
+ "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
47
+
48
+ "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="],
49
+
50
+ "universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="],
51
+ }
52
+ }
package/index.js ADDED
@@ -0,0 +1,77 @@
1
+ import { default as prompts } from "prompts";
2
+ import { default as fs } from "fs-extra";
3
+ import { resolve } from "path";
4
+ import kleur from "kleur";
5
+
6
+ console.log(`${kleur.bgGreen().bold("[Nurev]")}`);
7
+ console.log("Template generator 'on demanding revalidation' with Nuxt");
8
+
9
+ const questions = [
10
+ {
11
+ type: "select",
12
+ name: "manager",
13
+ message: "Pick a frontend package manager",
14
+ choices: [
15
+ {
16
+ title: "bun",
17
+ description: "Blazing fast JavaScript runtime with package manager",
18
+ value: "bun",
19
+ },
20
+ {
21
+ title: "npm",
22
+ description: "Default Nodejs package manager",
23
+ value: "npm",
24
+ },
25
+ {
26
+ title: "pnpm",
27
+ description: "Efficient package manager",
28
+ value: "pnpm",
29
+ },
30
+ ],
31
+ initial: 0,
32
+ },
33
+ {
34
+ type: "select",
35
+ name: "backend",
36
+ message: "Pick a backend",
37
+ choices: [
38
+ {
39
+ title: "PocketBase",
40
+ description: "Performance backend written in Go with SQLite",
41
+ value: "pocketbase",
42
+ },
43
+ ],
44
+ initial: 0,
45
+ },
46
+ ];
47
+
48
+ (async () => {
49
+ const response = await prompts(questions);
50
+
51
+ if (Object.keys(questions).length !== Object.keys(response).length) {
52
+ console.log("Script finished");
53
+ return;
54
+ }
55
+
56
+ const templateBase = resolve(__dirname, "templates", "base");
57
+ const templateBackend = resolve(__dirname, "templates", response.backend);
58
+ const templatePackageManager = resolve(
59
+ __dirname,
60
+ "templates",
61
+ `${response.backend}-${response.manager}`,
62
+ );
63
+ const templateDest = resolve(process.cwd());
64
+
65
+ try {
66
+ await fs.copy(templateBase, templateDest);
67
+ await fs.copy(templateBackend, templateDest);
68
+ await fs.copy(templatePackageManager, templateDest);
69
+ console.log(
70
+ kleur
71
+ .bgGreen()
72
+ .bold(`Template ${response.backend}-${response.manager} ready`),
73
+ );
74
+ } catch (error) {
75
+ console.log(error);
76
+ }
77
+ })();
package/package.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "nurev",
3
+ "module": "index.js",
4
+ "devDependencies": {
5
+ "@types/bun": "latest",
6
+ "@types/fs-extra": "^11.0.4",
7
+ "@types/prompts": "^2.4.9"
8
+ },
9
+ "peerDependencies": {
10
+ "typescript": "^5"
11
+ },
12
+ "bin": "./index.js",
13
+ "version": "0.0.1",
14
+ "type": "module",
15
+ "dependencies": {
16
+ "fs-extra": "^11.3.4",
17
+ "prompts": "^2.4.2"
18
+ }
19
+ }
@@ -0,0 +1,9 @@
1
+ <template>
2
+ <h1>App</h1>
3
+ <NuxtPage />
4
+ </template>
5
+ <style>
6
+ .outline {
7
+ outline: 1px solid red;
8
+ }
9
+ </style>
@@ -0,0 +1,5 @@
1
+ <template>
2
+ <div class="outline">
3
+ <h1>Index</h1>
4
+ </div>
5
+ </template>
@@ -0,0 +1,20 @@
1
+ <template>
2
+ <div class="outline">
3
+ <h3>
4
+ Post
5
+ <span v-if="data?.id !== undefined">
6
+ {{ data.id }}
7
+ </span>
8
+ </h3>
9
+ </div>
10
+ </template>
11
+
12
+ <script setup lang="ts">
13
+ interface IPost {
14
+ [key: string]: any;
15
+ }
16
+
17
+ const route = useRoute();
18
+ const { data } = await useFetch<IPost>("/api/post/" + route.params.id);
19
+ useSeoMeta({ title: "post " + data.value?.id });
20
+ </script>
@@ -0,0 +1,20 @@
1
+ // https://nuxt.com/docs/api/configuration/nuxt-config
2
+ export default defineNuxtConfig({
3
+ compatibilityDate: "2025-07-15",
4
+ devtools: { enabled: true },
5
+ nitro: {
6
+ preset: "bun",
7
+ },
8
+ routeRules: {
9
+ "/": { prerender: true },
10
+ "/posts/**": {
11
+ swr: true,
12
+ },
13
+ },
14
+ runtimeConfig: {
15
+ pocketbaseUrl: "",
16
+ pocketbaseUser: "",
17
+ pocketbasePassword: "",
18
+ jwtSecret: "",
19
+ },
20
+ });
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "frontend",
3
+ "type": "module",
4
+ "private": true,
5
+ "scripts": {
6
+ "build": "nuxt build",
7
+ "dev": "nuxt dev",
8
+ "generate": "nuxt generate",
9
+ "preview": "nuxt preview",
10
+ "postinstall": "nuxt prepare"
11
+ },
12
+ "dependencies": {
13
+ "jsonwebtoken": "^9.0.3",
14
+ "nuxt": "^4.4.2",
15
+ "pocketbase": "^0.26.8",
16
+ "vue": "^3.5.30",
17
+ "vue-router": "^5.0.4"
18
+ },
19
+ "devDependencies": {
20
+ "@types/jsonwebtoken": "^9.0.10"
21
+ }
22
+ }
@@ -0,0 +1,2 @@
1
+ User-Agent: *
2
+ Disallow:
@@ -0,0 +1,25 @@
1
+ export default defineCachedEventHandler(
2
+ async (event) => {
3
+ const pocketbase = event.context.pocketbase;
4
+ const id = getRouterParam(event, "id");
5
+ try {
6
+ const post = await pocketbase.collection("posts").getOne(id);
7
+ return post;
8
+ } catch (error) {
9
+ throw createError({
10
+ statusCode: 500,
11
+ message: "pocketbase can not get posts",
12
+ });
13
+ }
14
+ },
15
+ {
16
+ name: "data-posts",
17
+ getKey: (event) => {
18
+ const id = getRouterParam(event, "id");
19
+ return id || "default";
20
+ },
21
+ //1 WEEK
22
+ maxAge: 604800,
23
+ swr: true,
24
+ },
25
+ );
@@ -0,0 +1,28 @@
1
+ import { defineAuthResponseHandler } from "~~/server/utils/auth";
2
+
3
+ export default defineAuthResponseHandler(async (event) => {
4
+ const body = await readBody(event);
5
+ if (body === undefined) {
6
+ return;
7
+ }
8
+
9
+ const storage = useStorage("cache");
10
+
11
+ if (body.target === null) {
12
+ storage.clear();
13
+ return;
14
+ }
15
+
16
+ const keys = await storage.getKeys();
17
+
18
+ //DELETE HTML AND DATA CACHE
19
+ for (const key of keys) {
20
+ if (
21
+ (key.includes(`data-${body.target.table}:${body.target.id}`) ||
22
+ (key.includes(body.target.table) &&
23
+ key.includes(body.target.id.slice(0, 11)))) === true
24
+ ) {
25
+ await storage.removeItem(key);
26
+ }
27
+ }
28
+ });
@@ -0,0 +1,18 @@
1
+ import PocketBase from "pocketbase";
2
+
3
+ export default defineNitroPlugin(async (nitroApp) => {
4
+ const config = useRuntimeConfig();
5
+ const pb = new PocketBase(config.pocketbaseUrl);
6
+
7
+ try {
8
+ await pb
9
+ .collection("users")
10
+ .authWithPassword(config.pocketbaseUser, config.pocketbasePassword);
11
+
12
+ nitroApp.hooks.hook("request", (event) => {
13
+ event.context.pocketbase = pb;
14
+ });
15
+ } catch (err) {
16
+ console.log(err);
17
+ }
18
+ });
@@ -0,0 +1,47 @@
1
+ import jwt from "jsonwebtoken";
2
+
3
+ export const defineAuthResponseHandler = <T extends EventHandlerRequest, D>(
4
+ handler: EventHandler<T, D>,
5
+ ): EventHandler<T, D> =>
6
+ defineEventHandler<T>(async (event) => {
7
+ try {
8
+ const headerAuth = getHeader(event, "Authorization");
9
+
10
+ if (
11
+ headerAuth === undefined ||
12
+ headerAuth.startsWith("Bearer") === false
13
+ ) {
14
+ throw createError({
15
+ status: 401,
16
+ message: "Authorization not present",
17
+ });
18
+ }
19
+
20
+ const token = headerAuth.split(" ")[1];
21
+
22
+ if (token === undefined) {
23
+ throw createError({
24
+ status: 401,
25
+ message: "Authorization not valid",
26
+ });
27
+ }
28
+
29
+ const runtime = useRuntimeConfig();
30
+
31
+ try {
32
+ jwt.verify(token, runtime.jwtSecret);
33
+ } catch (err) {
34
+ throw createError({
35
+ status: 401,
36
+ message: "Authorization not valid",
37
+ });
38
+ }
39
+
40
+ const response = await handler(event);
41
+ // do something after the route handler
42
+ return { response };
43
+ } catch (err) {
44
+ // Error handling
45
+ return { err };
46
+ }
47
+ });
@@ -0,0 +1,18 @@
1
+ {
2
+ // https://nuxt.com/docs/guide/concepts/typescript
3
+ "files": [],
4
+ "references": [
5
+ {
6
+ "path": "./.nuxt/tsconfig.app.json"
7
+ },
8
+ {
9
+ "path": "./.nuxt/tsconfig.server.json"
10
+ },
11
+ {
12
+ "path": "./.nuxt/tsconfig.shared.json"
13
+ },
14
+ {
15
+ "path": "./.nuxt/tsconfig.node.json"
16
+ }
17
+ ]
18
+ }
@@ -0,0 +1,7 @@
1
+ TABLES_TRIGGER=
2
+ JWT_EXPIRES_MINUTES=
3
+ FRONTEND_URL=http://localhost:3000/api/private/reloadcache
4
+ NUXT_POCKETBASE_URL=https://localhost:8090
5
+ NUXT_POCKETBASE_USER=
6
+ NUXT_POCKETBASE_PASSWORD=
7
+ NUXT_JWT_SECRET=
@@ -0,0 +1,80 @@
1
+ # Template
2
+
3
+ Template made with [Nurev](https://codeberg.org/Serroda/nurev)
4
+
5
+ Tech stack:
6
+
7
+ - [Nuxt](https://nuxt.com/)
8
+ - [PocketBase](https://pocketbase.io/)
9
+
10
+ ## Setup
11
+
12
+ 1. Create a `.env` file, follow the `.env.example` file
13
+
14
+ - `TABLES_TRIGGER`: collections that trigger the Nuxt cache to be cleared when collections are updated, a new row is added or a row is removed
15
+ - **Example**
16
+ ```bash
17
+ TABLES_TRIGGER=posts,blogs
18
+ ```
19
+ - `JWT_EXPIRES_MINUTES`: JWT expire time in minutes
20
+ - **Example**
21
+ ```bash
22
+ JWT_EXPIRES_MINUTES=1
23
+ ```
24
+ - `FRONTEND_URL`: Nuxt API endpoint for clearing the cache
25
+ - **Example**
26
+ ```bash
27
+ FRONTEND_URL=http://localhost:3000/api/private/reloadcache
28
+ ```
29
+ - `NUXT_POCKETBASE_URL`: PocketBase API endpoint
30
+ - **Example**
31
+ ```bash
32
+ NUXT_POCKETBASE_URL=http://localhost:8090
33
+ ```
34
+ - `NUXT_POCKETBASE_USER`: PocketBase user created in `user` collection for login to the API
35
+ - **Example**
36
+ ```bash
37
+ NUXT_POCKETBASE_USER=paco@paco.me
38
+ ```
39
+ - `NUXT_POCKETBASE_PASSWORD`: PocketBase password user created in `user` collection for login to the API
40
+ - **Example**
41
+ ```bash
42
+ NUXT_POCKETBASE_PASSWORD=secretpassword
43
+ ```
44
+ - `NUXT_JWT_SECRET`: JWT secret for signing and validating tokens
45
+ - **Example**
46
+ ```bash
47
+ NUXT_JWT_SECRET=secretjwt
48
+ ```
49
+
50
+ 2. Create symbolic links for the environment variables with
51
+
52
+ ```bash
53
+ make setup
54
+ ```
55
+
56
+ 3. Start backend dev mode
57
+
58
+ ```bash
59
+ make backend-dev
60
+ ```
61
+
62
+ 4. Open [http://localhost:8090](`http://localhost:8090/_/) and create a superuser
63
+
64
+ 5. Create a user inside `users` collection with the same values inside `NUXT_POCKETBASE_USER` and `NUXT_POCKETBASE_PASSWORD`
65
+
66
+ 6. Create a collection named `posts` and create a new post
67
+
68
+ 7. Start frontend dev mode
69
+
70
+ ```bash
71
+ make frontend-dev
72
+ ```
73
+
74
+ 8. Open `http://localhost:3000/posts/[id]` and replace `[id]` with the post id created in the 6. step
75
+
76
+ ## Build
77
+
78
+ ```bash
79
+ make build
80
+ ```
@@ -0,0 +1,42 @@
1
+ module backend
2
+
3
+ go 1.25.0
4
+
5
+ require (
6
+ github.com/golang-jwt/jwt/v5 v5.3.1
7
+ github.com/joho/godotenv v1.5.1
8
+ github.com/pocketbase/pocketbase v0.36.7
9
+ )
10
+
11
+ require (
12
+ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
13
+ github.com/disintegration/imaging v1.6.2 // indirect
14
+ github.com/domodwyer/mailyak/v3 v3.6.2 // indirect
15
+ github.com/dustin/go-humanize v1.0.1 // indirect
16
+ github.com/fatih/color v1.18.0 // indirect
17
+ github.com/gabriel-vasile/mimetype v1.4.13 // indirect
18
+ github.com/ganigeorgiev/fexpr v0.5.0 // indirect
19
+ github.com/go-ozzo/ozzo-validation/v4 v4.3.0 // indirect
20
+ github.com/google/go-cmp v0.6.0 // indirect
21
+ github.com/google/uuid v1.6.0 // indirect
22
+ github.com/inconshreveable/mousetrap v1.1.0 // indirect
23
+ github.com/mattn/go-colorable v0.1.14 // indirect
24
+ github.com/mattn/go-isatty v0.0.20 // indirect
25
+ github.com/ncruces/go-strftime v1.0.0 // indirect
26
+ github.com/pocketbase/dbx v1.12.0 // indirect
27
+ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
28
+ github.com/spf13/cast v1.10.0 // indirect
29
+ github.com/spf13/cobra v1.10.2 // indirect
30
+ github.com/spf13/pflag v1.0.10 // indirect
31
+ golang.org/x/crypto v0.49.0 // indirect
32
+ golang.org/x/image v0.37.0 // indirect
33
+ golang.org/x/net v0.52.0 // indirect
34
+ golang.org/x/oauth2 v0.36.0 // indirect
35
+ golang.org/x/sync v0.20.0 // indirect
36
+ golang.org/x/sys v0.42.0 // indirect
37
+ golang.org/x/text v0.35.0 // indirect
38
+ modernc.org/libc v1.70.0 // indirect
39
+ modernc.org/mathutil v1.7.1 // indirect
40
+ modernc.org/memory v1.11.0 // indirect
41
+ modernc.org/sqlite v1.46.2 // indirect
42
+ )
@@ -0,0 +1,130 @@
1
+ github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
2
+ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
3
+ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
4
+ github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
5
+ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
6
+ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
7
+ github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
8
+ github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
9
+ github.com/domodwyer/mailyak/v3 v3.6.2 h1:x3tGMsyFhTCaxp6ycgR0FE/bu5QiNp+hetUuCOBXMn8=
10
+ github.com/domodwyer/mailyak/v3 v3.6.2/go.mod h1:lOm/u9CyCVWHeaAmHIdF4RiKVxKUT/H5XX10lIKAL6c=
11
+ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
12
+ github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
13
+ github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
14
+ github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
15
+ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
16
+ github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
17
+ github.com/gabriel-vasile/mimetype v1.4.13 h1:46nXokslUBsAJE/wMsp5gtO500a4F3Nkz9Ufpk2AcUM=
18
+ github.com/gabriel-vasile/mimetype v1.4.13/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
19
+ github.com/ganigeorgiev/fexpr v0.5.0 h1:XA9JxtTE/Xm+g/JFI6RfZEHSiQlk+1glLvRK1Lpv/Tk=
20
+ github.com/ganigeorgiev/fexpr v0.5.0/go.mod h1:RyGiGqmeXhEQ6+mlGdnUleLHgtzzu/VGO2WtJkF5drE=
21
+ github.com/go-ozzo/ozzo-validation/v4 v4.3.0 h1:byhDUpfEwjsVQb1vBunvIjh2BHQ9ead57VkAEY4V+Es=
22
+ github.com/go-ozzo/ozzo-validation/v4 v4.3.0/go.mod h1:2NKgrcHl3z6cJs+3Oo940FPRiTzuqKbvfrL2RxCj6Ew=
23
+ github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
24
+ github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
25
+ github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
26
+ github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
27
+ github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
28
+ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
29
+ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
30
+ github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc=
31
+ github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI=
32
+ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
33
+ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
34
+ github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
35
+ github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
36
+ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
37
+ github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
38
+ github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
39
+ github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
40
+ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
41
+ github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
42
+ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
43
+ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
44
+ github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
45
+ github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
46
+ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
47
+ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
48
+ github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
49
+ github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
50
+ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
51
+ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
52
+ github.com/pocketbase/dbx v1.12.0 h1:/oLErM+A0b4xI0PWTGPqSDVjzix48PqI/bng2l0PzoA=
53
+ github.com/pocketbase/dbx v1.12.0/go.mod h1:xXRCIAKTHMgUCyCKZm55pUOdvFziJjQfXaWKhu2vhMs=
54
+ github.com/pocketbase/pocketbase v0.36.7 h1:MrViB7BptPYrf2Nt25pJEYBqUdFjuhRKu1p5GTrkvPA=
55
+ github.com/pocketbase/pocketbase v0.36.7/go.mod h1:qX4HuVjoKXtEg41fSJVM0JLfGWXbBmHxVv/FaE446r4=
56
+ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
57
+ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
58
+ github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
59
+ github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
60
+ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
61
+ github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
62
+ github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
63
+ github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
64
+ github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
65
+ github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
66
+ github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
67
+ github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
68
+ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
69
+ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
70
+ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
71
+ go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
72
+ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
73
+ golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4=
74
+ golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA=
75
+ golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
76
+ golang.org/x/image v0.37.0 h1:ZiRjArKI8GwxZOoEtUfhrBtaCN+4b/7709dlT6SSnQA=
77
+ golang.org/x/image v0.37.0/go.mod h1:/3f6vaXC+6CEanU4KJxbcUZyEePbyKbaLoDOe4ehFYY=
78
+ golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8=
79
+ golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
80
+ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
81
+ golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=
82
+ golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
83
+ golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
84
+ golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
85
+ golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
86
+ golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
87
+ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
88
+ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
89
+ golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
90
+ golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
91
+ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
92
+ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
93
+ golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=
94
+ golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=
95
+ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
96
+ golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=
97
+ golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=
98
+ google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
99
+ google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
100
+ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
101
+ gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
102
+ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
103
+ modernc.org/cc/v4 v4.27.1 h1:9W30zRlYrefrDV2JE2O8VDtJ1yPGownxciz5rrbQZis=
104
+ modernc.org/cc/v4 v4.27.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
105
+ modernc.org/ccgo/v4 v4.32.0 h1:hjG66bI/kqIPX1b2yT6fr/jt+QedtP2fqojG2VrFuVw=
106
+ modernc.org/ccgo/v4 v4.32.0/go.mod h1:6F08EBCx5uQc38kMGl+0Nm0oWczoo1c7cgpzEry7Uc0=
107
+ modernc.org/fileutil v1.4.0 h1:j6ZzNTftVS054gi281TyLjHPp6CPHr2KCxEXjEbD6SM=
108
+ modernc.org/fileutil v1.4.0/go.mod h1:EqdKFDxiByqxLk8ozOxObDSfcVOv/54xDs/DUHdvCUU=
109
+ modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
110
+ modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
111
+ modernc.org/gc/v3 v3.1.2 h1:ZtDCnhonXSZexk/AYsegNRV1lJGgaNZJuKjJSWKyEqo=
112
+ modernc.org/gc/v3 v3.1.2/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY=
113
+ modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks=
114
+ modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
115
+ modernc.org/libc v1.70.0 h1:U58NawXqXbgpZ/dcdS9kMshu08aiA6b7gusEusqzNkw=
116
+ modernc.org/libc v1.70.0/go.mod h1:OVmxFGP1CI/Z4L3E0Q3Mf1PDE0BucwMkcXjjLntvHJo=
117
+ modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
118
+ modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
119
+ modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
120
+ modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
121
+ modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=
122
+ modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
123
+ modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
124
+ modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
125
+ modernc.org/sqlite v1.46.2 h1:gkXQ6R0+AjxFC/fTDaeIVLbNLNrRoOK7YYVz5BKhTcE=
126
+ modernc.org/sqlite v1.46.2/go.mod h1:hWjRO6Tj/5Ik8ieqxQybiEOUXy0NJFNp2tpvVpKlvig=
127
+ modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
128
+ modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
129
+ modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
130
+ modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
@@ -0,0 +1,52 @@
1
+ package main
2
+
3
+ import (
4
+ "log"
5
+ "net/http"
6
+ "time"
7
+
8
+ "github.com/golang-jwt/jwt/v5"
9
+ "github.com/pocketbase/pocketbase"
10
+ "github.com/pocketbase/pocketbase/core"
11
+ )
12
+
13
+ func triggerHandler(e CustomEventPB, variables *Variables, client *http.Client) error {
14
+ token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.RegisteredClaims{
15
+ ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Minute * time.Duration(variables.JwtExpiresMinutes))),
16
+ })
17
+
18
+ tokenSigned, err := token.SignedString([]byte(variables.NuxtJwtSecret))
19
+ if err != nil {
20
+ e.GetApp().Logger().Error("HOOK - Token error",
21
+ "error", err)
22
+ return e.Continue()
23
+ }
24
+
25
+ return sendPost(e, client, variables.FrontendURL, tokenSigned)
26
+ }
27
+
28
+ func main() {
29
+ variables := loadEnv()
30
+ client := &http.Client{}
31
+
32
+ app := pocketbase.New()
33
+ app.OnBackupRestore().BindFunc(func(e *core.BackupEvent) error {
34
+ return triggerHandler(CustomBackupEvent{e}, &variables, client)
35
+ })
36
+ app.OnBackupCreate().BindFunc(func(e *core.BackupEvent) error {
37
+ return triggerHandler(CustomBackupEvent{e}, &variables, client)
38
+ })
39
+ app.OnRecordAfterCreateSuccess(variables.TablesTrigger...).BindFunc(func(e *core.RecordEvent) error {
40
+ return triggerHandler(CustomRecordEvent{e}, &variables, client)
41
+ })
42
+ app.OnRecordAfterDeleteSuccess(variables.TablesTrigger...).BindFunc(func(e *core.RecordEvent) error {
43
+ return triggerHandler(CustomRecordEvent{e}, &variables, client)
44
+ })
45
+ app.OnRecordAfterUpdateSuccess(variables.TablesTrigger...).BindFunc(func(e *core.RecordEvent) error {
46
+ return triggerHandler(CustomRecordEvent{e}, &variables, client)
47
+ })
48
+
49
+ if err := app.Start(); err != nil {
50
+ log.Fatal(err)
51
+ }
52
+ }
@@ -0,0 +1,55 @@
1
+ package main
2
+
3
+ import (
4
+ "bytes"
5
+ "encoding/json"
6
+ "net/http"
7
+ )
8
+
9
+ // SEND HTTP POST TO THE FRONTEND TO NOTIFY THAT THE
10
+ // DATA HAS CHANGED
11
+ func sendPost(e CustomEventPB, client *http.Client, url string, tokenSigned string) error {
12
+ body := map[string]*Target{
13
+ "target": e.Target(),
14
+ }
15
+
16
+ jsonData, err := json.Marshal(body)
17
+
18
+ if err != nil {
19
+ e.GetApp().Logger().Error("HOOK - Cant create body POST",
20
+ "target", body["target"],
21
+ "error", err)
22
+ return e.Continue()
23
+ }
24
+
25
+ req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(jsonData))
26
+
27
+ if err != nil {
28
+ e.GetApp().Logger().Error("HOOK - Request error",
29
+ "target", body["target"],
30
+ "error", err)
31
+ return e.Continue()
32
+ }
33
+
34
+ req.Header.Set("Content-Type", "application/json")
35
+ req.Header.Set("Authorization", "Bearer "+tokenSigned)
36
+
37
+ resp, err := client.Do(req)
38
+
39
+ if err != nil {
40
+ e.GetApp().Logger().Error("HOOK - Connection error",
41
+ "target", body["target"],
42
+ "error", err)
43
+ return e.Continue()
44
+ }
45
+
46
+ defer resp.Body.Close()
47
+
48
+ if resp.StatusCode == http.StatusOK {
49
+ e.GetApp().Logger().Info("HOOK - Sent",
50
+ "target", body["target"],
51
+ )
52
+ }
53
+
54
+ return e.Continue()
55
+ }
@@ -0,0 +1,43 @@
1
+ package main
2
+
3
+ import "github.com/pocketbase/pocketbase/core"
4
+
5
+ type Target struct {
6
+ Table string `json:"table"`
7
+ Id string `json:"id"`
8
+ }
9
+
10
+ type CustomEventPB interface {
11
+ GetApp() core.App
12
+ Continue() error
13
+ Target() *Target
14
+ }
15
+
16
+ type CustomRecordEvent struct {
17
+ *core.RecordEvent
18
+ }
19
+
20
+ func (c CustomRecordEvent) GetApp() core.App { return c.App }
21
+ func (c CustomRecordEvent) Continue() error { return c.Next() }
22
+ func (c CustomRecordEvent) Target() *Target {
23
+ return &Target{Table: c.Record.TableName(), Id: c.Record.Id}
24
+ }
25
+
26
+ type CustomBackupEvent struct {
27
+ *core.BackupEvent
28
+ }
29
+
30
+ func (c CustomBackupEvent) GetApp() core.App { return c.App }
31
+ func (c CustomBackupEvent) Continue() error { return c.Next() }
32
+ func (c CustomBackupEvent) Target() *Target {
33
+ return nil
34
+ }
35
+
36
+ type Variables struct {
37
+ // TABLES THAT WILL TRIGGER THE HOOK
38
+ TablesTrigger []string `env:"TABLES_TRIGGER"`
39
+ // JSON WEB TOKEN SECRET
40
+ NuxtJwtSecret string `env:"NUXT_JWT_SECRET"`
41
+ JwtExpiresMinutes int `env:"JWT_EXPIRES_MINUTES"`
42
+ FrontendURL string `env:"FRONTEND_URL"`
43
+ }
@@ -0,0 +1,54 @@
1
+ package main
2
+
3
+ import (
4
+ "log"
5
+ "os"
6
+ "reflect"
7
+ "strconv"
8
+ "strings"
9
+
10
+ "github.com/joho/godotenv"
11
+ )
12
+
13
+ func loadEnv() Variables {
14
+ log.Println("Loading enviroment variables...")
15
+ err := godotenv.Load()
16
+ if err != nil {
17
+ log.Println(".env not found")
18
+ }
19
+
20
+ variables := Variables{}
21
+ values := reflect.ValueOf(&variables).Elem()
22
+ types := values.Type()
23
+
24
+ for i := 0; i < values.NumField(); i++ {
25
+ value := values.Field(i)
26
+ envName := types.Field(i).Tag.Get("env")
27
+
28
+ valueEnv := os.Getenv(envName)
29
+
30
+ if valueEnv == "" {
31
+ log.Fatalf("%s is not defined as enviroment variable", envName)
32
+ }
33
+
34
+ if !value.CanSet() {
35
+ log.Printf("%s cant set as enviroment variable", envName)
36
+ continue
37
+ }
38
+
39
+ switch value.Kind() {
40
+ case reflect.String:
41
+ value.SetString(valueEnv)
42
+ case reflect.Slice:
43
+ value.Set(reflect.ValueOf(strings.Split(valueEnv, ",")))
44
+ case reflect.Int:
45
+ parsedInt, err := strconv.Atoi(valueEnv)
46
+ if err != nil {
47
+ log.Fatalf("Invalid integer for %s: %s", envName, valueEnv)
48
+ }
49
+ value.SetInt(int64(parsedInt))
50
+ }
51
+ }
52
+
53
+ return variables
54
+ }
@@ -0,0 +1,77 @@
1
+ .PHONY: all backend-build backend-update backend-dev backend-run backend-clean \
2
+ frontend-install frontend-dev frontend-build frontend-preview frontend-clean help \
3
+ setup build
4
+
5
+
6
+ # Default target
7
+ all: help
8
+
9
+ # Backend targets
10
+ backend-setup:
11
+ @echo "Preparing backend..."
12
+ cd backend && ln -sf ../.env ./.env
13
+
14
+ backend-build:
15
+ @echo "Building backend..."
16
+ cd backend && go build -o backend
17
+
18
+ backend-update:
19
+ @echo "Updating backend..."
20
+ cd backend && go mod tidy
21
+
22
+ backend-dev: backend-update
23
+ @echo "Starting backend development..."
24
+ cd backend && go run . serve
25
+
26
+ backend-run: backend-build
27
+ @echo "Running backend..."
28
+ cd backend && ./backend serve
29
+
30
+ backend-clean:
31
+ @echo "Cleaning backend..."
32
+ cd backend && rm -f backend
33
+
34
+ # Frontend targets
35
+ frontend-setup:
36
+ @echo "Preparing frontend..."
37
+ cd frontend && ln -sf ../.env ./.env
38
+
39
+ frontend-install:
40
+ @echo "Installing frontend dependencies..."
41
+ cd frontend && bun install
42
+
43
+ frontend-dev: frontend-install
44
+ @echo "Starting frontend development server..."
45
+ cd frontend && bun --bun run dev
46
+
47
+ frontend-build: frontend-install
48
+ @echo "Building frontend for production..."
49
+ cd frontend && bun --bun run build
50
+
51
+ frontend-preview: frontend-build
52
+ @echo "Previewing frontend production build..."
53
+ cd frontend && bun --bun run preview
54
+
55
+ frontend-clean:
56
+ @echo "Cleaning frontend..."
57
+ cd frontend && rm -rf .nuxt dist output
58
+
59
+ setup: backend-setup frontend-setup
60
+ @echo "Setup ready"
61
+
62
+ build: backend-build frontend-build
63
+ @echo "Build ready"
64
+
65
+ help:
66
+ @echo "Available targets:"
67
+ @echo " make backend-setup - Create a symbolic link for backend"
68
+ @echo " make backend-build - Build the backend only"
69
+ @echo " make backend-dev - Run the backend development only"
70
+ @echo " make backend-run - Run the backend only"
71
+ @echo " make frontend-setup - Create a symbolic link for frontend"
72
+ @echo " make frontend-dev - Start frontend development server"
73
+ @echo " make frontend-build - Build frontend for production"
74
+ @echo " make frontend-preview - Preview frontend production build"
75
+ @echo " make help - Show this help message"
76
+ @echo " make setup - Prepare the project for dev mode and build"
77
+ @echo " make build - Build frontend and backend"
@@ -0,0 +1,77 @@
1
+ .PHONY: all backend-build backend-update backend-dev backend-run backend-clean \
2
+ frontend-install frontend-dev frontend-build frontend-preview frontend-clean help \
3
+ setup build
4
+
5
+
6
+ # Default target
7
+ all: help
8
+
9
+ # Backend targets
10
+ backend-setup:
11
+ @echo "Preparing backend..."
12
+ cd backend && ln -sf ../.env ./.env
13
+
14
+ backend-build:
15
+ @echo "Building backend..."
16
+ cd backend && go build -o nupo-backend
17
+
18
+ backend-update:
19
+ @echo "Updating backend..."
20
+ cd backend && go mod tidy
21
+
22
+ backend-dev: backend-update
23
+ @echo "Starting backend development..."
24
+ cd backend && go run . serve
25
+
26
+ backend-run: backend-build
27
+ @echo "Running backend..."
28
+ cd backend && ./nupo-backend serve
29
+
30
+ backend-clean:
31
+ @echo "Cleaning backend..."
32
+ cd backend && rm -f nupo-backend
33
+
34
+ # Frontend targets
35
+ frontend-setup:
36
+ @echo "Preparing frontend..."
37
+ cd frontend && ln -sf ../.env ./.env
38
+
39
+ frontend-install:
40
+ @echo "Installing frontend dependencies..."
41
+ cd frontend && npm install
42
+
43
+ frontend-dev: frontend-install
44
+ @echo "Starting frontend development server..."
45
+ cd frontend && npm run dev
46
+
47
+ frontend-build: frontend-install
48
+ @echo "Building frontend for production..."
49
+ cd frontend && npm run build
50
+
51
+ frontend-preview: frontend-build
52
+ @echo "Previewing frontend production build..."
53
+ cd frontend && npm run preview
54
+
55
+ frontend-clean:
56
+ @echo "Cleaning frontend..."
57
+ cd frontend && rm -rf .nuxt dist output
58
+
59
+ setup: backend-setup frontend-setup
60
+ @echo "Setup ready"
61
+
62
+ build: backend-build frontend-build
63
+ @echo "Build ready"
64
+
65
+ help:
66
+ @echo "Available targets:"
67
+ @echo " make backend-setup - Create a symbolic link for backend"
68
+ @echo " make backend-build - Build the backend only"
69
+ @echo " make backend-dev - Run the backend development only"
70
+ @echo " make backend-run - Run the backend only"
71
+ @echo " make frontend-setup - Create a symbolic link for frontend"
72
+ @echo " make frontend-dev - Start frontend development server"
73
+ @echo " make frontend-build - Build frontend for production"
74
+ @echo " make frontend-preview - Preview frontend production build"
75
+ @echo " make help - Show this help message"
76
+ @echo " make setup - Prepare the project for dev mode and build"
77
+ @echo " make build - Build frontend and backend"
@@ -0,0 +1,77 @@
1
+ .PHONY: all backend-build backend-update backend-dev backend-run backend-clean \
2
+ frontend-install frontend-dev frontend-build frontend-preview frontend-clean help \
3
+ setup build
4
+
5
+
6
+ # Default target
7
+ all: help
8
+
9
+ # Backend targets
10
+ backend-setup:
11
+ @echo "Preparing backend..."
12
+ cd backend && ln -sf ../.env ./.env
13
+
14
+ backend-build:
15
+ @echo "Building backend..."
16
+ cd backend && go build -o nupo-backend
17
+
18
+ backend-update:
19
+ @echo "Updating backend..."
20
+ cd backend && go mod tidy
21
+
22
+ backend-dev: backend-update
23
+ @echo "Starting backend development..."
24
+ cd backend && go run . serve
25
+
26
+ backend-run: backend-build
27
+ @echo "Running backend..."
28
+ cd backend && ./nupo-backend serve
29
+
30
+ backend-clean:
31
+ @echo "Cleaning backend..."
32
+ cd backend && rm -f nupo-backend
33
+
34
+ # Frontend targets
35
+ frontend-setup:
36
+ @echo "Preparing frontend..."
37
+ cd frontend && ln -sf ../.env ./.env
38
+
39
+ frontend-install:
40
+ @echo "Installing frontend dependencies..."
41
+ cd frontend && pnpm install
42
+
43
+ frontend-dev: frontend-install
44
+ @echo "Starting frontend development server..."
45
+ cd frontend && pnpm run dev
46
+
47
+ frontend-build: frontend-install
48
+ @echo "Building frontend for production..."
49
+ cd frontend && pnpm run build
50
+
51
+ frontend-preview: frontend-build
52
+ @echo "Previewing frontend production build..."
53
+ cd frontend && pnpm run preview
54
+
55
+ frontend-clean:
56
+ @echo "Cleaning frontend..."
57
+ cd frontend && rm -rf .nuxt dist output
58
+
59
+ setup: backend-setup frontend-setup
60
+ @echo "Setup ready"
61
+
62
+ build: backend-build frontend-build
63
+ @echo "Build ready"
64
+
65
+ help:
66
+ @echo "Available targets:"
67
+ @echo " make backend-setup - Create a symbolic link for backend"
68
+ @echo " make backend-build - Build the backend only"
69
+ @echo " make backend-dev - Run the backend development only"
70
+ @echo " make backend-run - Run the backend only"
71
+ @echo " make frontend-setup - Create a symbolic link for frontend"
72
+ @echo " make frontend-dev - Start frontend development server"
73
+ @echo " make frontend-build - Build frontend for production"
74
+ @echo " make frontend-preview - Preview frontend production build"
75
+ @echo " make help - Show this help message"
76
+ @echo " make setup - Prepare the project for dev mode and build"
77
+ @echo " make build - Build frontend and backend"