create-harper 1.7.4 → 1.8.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.
Files changed (146) hide show
  1. package/lib/constants/frameworks.js +20 -0
  2. package/lib/constants/helpMessage.js +2 -2
  3. package/package.json +6 -2
  4. package/template-react/README.md +6 -2
  5. package/template-react/_gitignore +1 -2
  6. package/template-react/config.yaml +16 -3
  7. package/template-react/package.json +9 -7
  8. package/template-react/src/App.jsx +1 -5
  9. package/template-react/vite.config.js +2 -2
  10. package/template-react-ssr/README.md +124 -0
  11. package/template-react-ssr/_aiignore +1 -0
  12. package/template-react-ssr/_env +1 -0
  13. package/template-react-ssr/_env.example +1 -0
  14. package/template-react-ssr/_github/workflow/deploy.yaml +33 -0
  15. package/template-react-ssr/_gitignore +148 -0
  16. package/template-react-ssr/_nvmrc +1 -0
  17. package/template-react-ssr/config.yaml +42 -0
  18. package/template-react-ssr/eslint.config.js +23 -0
  19. package/template-react-ssr/graphql.config.yml +3 -0
  20. package/template-react-ssr/index.html +13 -0
  21. package/template-react-ssr/package.json +32 -0
  22. package/template-react-ssr/public/react.svg +14 -0
  23. package/template-react-ssr/public/vite.svg +42 -0
  24. package/template-react-ssr/resources/README.md +11 -0
  25. package/template-react-ssr/schemas/README.md +11 -0
  26. package/template-react-ssr/schemas/jsdocTypes.js +5 -0
  27. package/template-react-ssr/src/App.jsx +31 -0
  28. package/template-react-ssr/src/counter.js +7 -0
  29. package/template-react-ssr/src/entry-client.jsx +13 -0
  30. package/template-react-ssr/src/entry-server.jsx +18 -0
  31. package/template-react-ssr/src/style.css +96 -0
  32. package/template-react-ssr/src/vite-env.d.ts +9 -0
  33. package/template-react-ssr/test/counter.test.js +15 -0
  34. package/template-react-ssr/vite.config.js +22 -0
  35. package/template-react-ts/README.md +6 -2
  36. package/template-react-ts/_gitignore +1 -2
  37. package/template-react-ts/config.yaml +16 -3
  38. package/template-react-ts/package.json +10 -8
  39. package/template-react-ts/vite.config.ts +2 -2
  40. package/template-react-ts-ssr/README.md +132 -0
  41. package/template-react-ts-ssr/_aiignore +1 -0
  42. package/template-react-ts-ssr/_env +1 -0
  43. package/template-react-ts-ssr/_env.example +1 -0
  44. package/template-react-ts-ssr/_github/workflow/deploy.yaml +33 -0
  45. package/template-react-ts-ssr/_gitignore +148 -0
  46. package/template-react-ts-ssr/_nvmrc +1 -0
  47. package/template-react-ts-ssr/config.yaml +43 -0
  48. package/template-react-ts-ssr/eslint.config.js +23 -0
  49. package/template-react-ts-ssr/graphql.config.yml +3 -0
  50. package/template-react-ts-ssr/index.html +13 -0
  51. package/template-react-ts-ssr/package.json +36 -0
  52. package/template-react-ts-ssr/public/react.svg +14 -0
  53. package/template-react-ts-ssr/public/vite.svg +42 -0
  54. package/template-react-ts-ssr/resources/README.md +11 -0
  55. package/template-react-ts-ssr/schemas/README.md +11 -0
  56. package/template-react-ts-ssr/schemas/globalTypes.d.ts +5 -0
  57. package/template-react-ts-ssr/schemas/types.ts +5 -0
  58. package/template-react-ts-ssr/src/App.tsx +35 -0
  59. package/template-react-ts-ssr/src/counter.ts +7 -0
  60. package/template-react-ts-ssr/src/entry-client.tsx +13 -0
  61. package/template-react-ts-ssr/src/entry-server.tsx +17 -0
  62. package/template-react-ts-ssr/src/style.css +96 -0
  63. package/template-react-ts-ssr/src/vite-env.d.ts +9 -0
  64. package/template-react-ts-ssr/test/counter.test.ts +15 -0
  65. package/template-react-ts-ssr/tsconfig.json +34 -0
  66. package/template-react-ts-ssr/vite.config.ts +22 -0
  67. package/template-vanilla/README.md +5 -1
  68. package/template-vanilla-ts/README.md +5 -1
  69. package/template-vue/README.md +6 -2
  70. package/template-vue/_gitignore +1 -2
  71. package/template-vue/config.yaml +16 -3
  72. package/template-vue/package.json +9 -7
  73. package/template-vue/src/App.vue +1 -9
  74. package/template-vue/vite.config.js +1 -1
  75. package/template-vue-ssr/README.md +124 -0
  76. package/template-vue-ssr/_aiignore +1 -0
  77. package/template-vue-ssr/_env +1 -0
  78. package/template-vue-ssr/_env.example +1 -0
  79. package/template-vue-ssr/_github/workflow/deploy.yaml +33 -0
  80. package/template-vue-ssr/_gitignore +148 -0
  81. package/template-vue-ssr/_nvmrc +1 -0
  82. package/template-vue-ssr/config.yaml +42 -0
  83. package/template-vue-ssr/eslint.config.js +23 -0
  84. package/template-vue-ssr/graphql.config.yml +3 -0
  85. package/template-vue-ssr/index.html +13 -0
  86. package/template-vue-ssr/package.json +31 -0
  87. package/template-vue-ssr/public/react.svg +14 -0
  88. package/template-vue-ssr/public/vite.svg +42 -0
  89. package/template-vue-ssr/public/vue.svg +9 -0
  90. package/template-vue-ssr/resources/README.md +11 -0
  91. package/template-vue-ssr/schemas/README.md +11 -0
  92. package/template-vue-ssr/schemas/jsdocTypes.js +5 -0
  93. package/template-vue-ssr/src/App.vue +35 -0
  94. package/template-vue-ssr/src/counter.js +7 -0
  95. package/template-vue-ssr/src/entry-client.js +7 -0
  96. package/template-vue-ssr/src/entry-server.js +14 -0
  97. package/template-vue-ssr/src/style.css +96 -0
  98. package/template-vue-ssr/test/counter.test.js +15 -0
  99. package/template-vue-ssr/vite.config.js +22 -0
  100. package/template-vue-ts/README.md +6 -2
  101. package/template-vue-ts/_gitignore +1 -2
  102. package/template-vue-ts/config.yaml +16 -3
  103. package/template-vue-ts/package.json +8 -6
  104. package/template-vue-ts/vite.config.ts +1 -1
  105. package/template-vue-ts-ssr/README.md +132 -0
  106. package/template-vue-ts-ssr/_aiignore +1 -0
  107. package/template-vue-ts-ssr/_env +1 -0
  108. package/template-vue-ts-ssr/_env.example +1 -0
  109. package/template-vue-ts-ssr/_github/workflow/deploy.yaml +33 -0
  110. package/template-vue-ts-ssr/_gitignore +148 -0
  111. package/template-vue-ts-ssr/_nvmrc +1 -0
  112. package/template-vue-ts-ssr/config.yaml +43 -0
  113. package/template-vue-ts-ssr/eslint.config.js +23 -0
  114. package/template-vue-ts-ssr/graphql.config.yml +3 -0
  115. package/template-vue-ts-ssr/index.html +13 -0
  116. package/template-vue-ts-ssr/package.json +34 -0
  117. package/template-vue-ts-ssr/public/react.svg +14 -0
  118. package/template-vue-ts-ssr/public/vite.svg +42 -0
  119. package/template-vue-ts-ssr/public/vue.svg +9 -0
  120. package/template-vue-ts-ssr/resources/README.md +11 -0
  121. package/template-vue-ts-ssr/schemas/README.md +11 -0
  122. package/template-vue-ts-ssr/schemas/globalTypes.d.ts +5 -0
  123. package/template-vue-ts-ssr/schemas/types.ts +5 -0
  124. package/template-vue-ts-ssr/src/App.vue +43 -0
  125. package/template-vue-ts-ssr/src/counter.ts +7 -0
  126. package/template-vue-ts-ssr/src/entry-client.ts +7 -0
  127. package/template-vue-ts-ssr/src/entry-server.ts +13 -0
  128. package/template-vue-ts-ssr/src/style.css +96 -0
  129. package/template-vue-ts-ssr/src/vite-env.d.ts +15 -0
  130. package/template-vue-ts-ssr/test/counter.test.ts +15 -0
  131. package/template-vue-ts-ssr/tsconfig.json +33 -0
  132. package/template-vue-ts-ssr/vite.config.ts +22 -0
  133. package/template-react/deploy-template/config.yaml +0 -10
  134. package/template-react/deploy-template/fastify/static.js +0 -14
  135. package/template-react/deploy-template/package.json +0 -5
  136. package/template-react-ts/deploy-template/config.yaml +0 -10
  137. package/template-react-ts/deploy-template/fastify/static.js +0 -14
  138. package/template-react-ts/deploy-template/package.json +0 -5
  139. package/template-vue/deploy-template/config.yaml +0 -10
  140. package/template-vue/deploy-template/fastify/static.js +0 -14
  141. package/template-vue/deploy-template/package.json +0 -5
  142. package/template-vue-ts/deploy-template/config.yaml +0 -10
  143. package/template-vue-ts/deploy-template/fastify/static.js +0 -14
  144. package/template-vue-ts/deploy-template/package.json +0 -5
  145. /package/{template-react → template-react-ts-ssr}/public/typescript.svg +0 -0
  146. /package/{template-vue → template-vue-ts-ssr}/public/typescript.svg +0 -0
@@ -0,0 +1,42 @@
1
+ <svg
2
+ xmlns="http://www.w3.org/2000/svg"
3
+ aria-hidden="true"
4
+ role="img"
5
+ class="iconify iconify--logos"
6
+ width="31.88"
7
+ height="32"
8
+ preserveAspectRatio="xMidYMid meet"
9
+ viewBox="0 0 256 257"
10
+ >
11
+ <defs>
12
+ <linearGradient
13
+ id="IconifyId1813088fe1fbc01fb466"
14
+ x1="-.828%"
15
+ x2="57.636%"
16
+ y1="7.652%"
17
+ y2="78.411%"
18
+ >
19
+ <stop offset="0%" stop-color="#41D1FF"></stop>
20
+ <stop offset="100%" stop-color="#BD34FE"></stop>
21
+ </linearGradient>
22
+ <linearGradient
23
+ id="IconifyId1813088fe1fbc01fb467"
24
+ x1="43.376%"
25
+ x2="50.316%"
26
+ y1="2.242%"
27
+ y2="89.03%"
28
+ >
29
+ <stop offset="0%" stop-color="#FFEA83"></stop>
30
+ <stop offset="8.333%" stop-color="#FFDD35"></stop>
31
+ <stop offset="100%" stop-color="#FFA800"></stop>
32
+ </linearGradient>
33
+ </defs>
34
+ <path
35
+ fill="url(#IconifyId1813088fe1fbc01fb466)"
36
+ d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"
37
+ ></path>
38
+ <path
39
+ fill="url(#IconifyId1813088fe1fbc01fb467)"
40
+ d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"
41
+ ></path>
42
+ </svg>
@@ -0,0 +1,11 @@
1
+ # Resources
2
+
3
+ The [schemas you define in .GraphQL files](../.agents/skills/harper-best-practices/rules/adding-tables-with-schemas.md) will [automatically stand-up REST APIs](../.agents/skills/harper-best-practices/rules/automatic-apis.md).
4
+
5
+ But you can [extend your tables with custom logic](../.agents/skills/harper-best-practices/rules/extending-tables.md) and [create your own resources](../.agents/skills/harper-best-practices/rules/custom-resources.md) in this directory.
6
+
7
+ ## Want to read more?
8
+
9
+ Check out the rest of the "skills" documentation!
10
+
11
+ [Harper Best Practices Skill](../.agents/skills/harper-best-practices/SKILL.md)
@@ -0,0 +1,11 @@
1
+ # Schemas
2
+
3
+ Your schemas are defined in `.graphql` files within this `schemas` directory. These files contain the structure and types for your database tables, allowing Harper to automatically generate REST APIs for CRUD operations.
4
+
5
+ Take a look at the [Adding Tables with Schemas](../.agents/skills/harper-best-practices/rules/adding-tables-with-schemas.md) to learn more!
6
+
7
+ ## Want to read more?
8
+
9
+ Check out the rest of the "skills" documentation!
10
+
11
+ [Harper Best Practices Skill](../.agents/skills/harper-best-practices/SKILL.md)
@@ -0,0 +1,5 @@
1
+ /**
2
+ Generated from your schema files
3
+ Manual changes will be lost!
4
+ > harper dev .
5
+ */
@@ -0,0 +1,31 @@
1
+ import reactLogo from '/react.svg';
2
+ import viteLogo from '/vite.svg';
3
+ import { useCallback, useState } from 'react';
4
+ import { increment } from './counter.js';
5
+
6
+ export function App() {
7
+ const [counter, setCounter] = useState(0);
8
+ const countUp = useCallback(() => {
9
+ setCounter(counter => increment(counter));
10
+ }, []);
11
+
12
+ return (
13
+ <>
14
+ <div>
15
+ <a href="https://vite.dev" target="_blank" rel="noopener noreferrer">
16
+ <img src={viteLogo} className="logo" alt="Vite logo" />
17
+ </a>
18
+ <a href="https://react.dev/" target="_blank" rel="noopener noreferrer">
19
+ <img src={reactLogo} className="logo react" alt="React logo" />
20
+ </a>
21
+ <h1>Vite + React</h1>
22
+ <p>Wow, look at this!</p>
23
+ <div className="card">
24
+ <button id="counter" type="button" onClick={countUp}>
25
+ count is {counter}
26
+ </button>
27
+ </div>
28
+ </div>
29
+ </>
30
+ );
31
+ }
@@ -0,0 +1,7 @@
1
+ export function increment(value) {
2
+ return value + 1;
3
+ }
4
+
5
+ export function decrement(value) {
6
+ return value - 1;
7
+ }
@@ -0,0 +1,13 @@
1
+ import { App } from '@/App.jsx';
2
+ import { StrictMode } from 'react';
3
+ import { hydrateRoot } from 'react-dom/client';
4
+
5
+ import './style.css';
6
+
7
+ // Hydrate the server-rendered markup. (A client-only app would use `createRoot(...).render(...)`.)
8
+ hydrateRoot(
9
+ document.getElementById('app'),
10
+ <StrictMode>
11
+ <App />
12
+ </StrictMode>,
13
+ );
@@ -0,0 +1,18 @@
1
+ import { App } from '@/App.jsx';
2
+ import { StrictMode } from 'react';
3
+ import { renderToString } from 'react-dom/server';
4
+
5
+ /**
6
+ * Server render entry. The Vite Harper plugin calls this for HTML navigations and injects the
7
+ * returned markup into the `<!--ssr-outlet-->` placeholder in index.html.
8
+ *
9
+ * @param {string} _url The request URL — use it to drive routing/data loading per request.
10
+ * @returns {string}
11
+ */
12
+ export function render(_url) {
13
+ return renderToString(
14
+ <StrictMode>
15
+ <App />
16
+ </StrictMode>,
17
+ );
18
+ }
@@ -0,0 +1,96 @@
1
+ :root {
2
+ font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
3
+ line-height: 1.5;
4
+ font-weight: 400;
5
+
6
+ color-scheme: light dark;
7
+ color: rgba(255, 255, 255, 0.87);
8
+ background-color: #242424;
9
+
10
+ font-synthesis: none;
11
+ text-rendering: optimizeLegibility;
12
+ -webkit-font-smoothing: antialiased;
13
+ -moz-osx-font-smoothing: grayscale;
14
+ }
15
+
16
+ a {
17
+ font-weight: 500;
18
+ color: #646cff;
19
+ text-decoration: inherit;
20
+ }
21
+ a:hover {
22
+ color: #535bf2;
23
+ }
24
+
25
+ body {
26
+ margin: 0;
27
+ display: flex;
28
+ place-items: center;
29
+ min-width: 320px;
30
+ min-height: 100vh;
31
+ }
32
+
33
+ h1 {
34
+ font-size: 3.2em;
35
+ line-height: 1.1;
36
+ }
37
+
38
+ #app {
39
+ max-width: 1280px;
40
+ margin: 0 auto;
41
+ padding: 2rem;
42
+ text-align: center;
43
+ }
44
+
45
+ .logo {
46
+ height: 6em;
47
+ padding: 1.5em;
48
+ will-change: filter;
49
+ transition: filter 300ms;
50
+ }
51
+ .logo:hover {
52
+ filter: drop-shadow(0 0 2em #646cffaa);
53
+ }
54
+ .logo.vanilla:hover {
55
+ filter: drop-shadow(0 0 2em #3178c6aa);
56
+ }
57
+
58
+ .card {
59
+ padding: 2em;
60
+ }
61
+
62
+ .read-the-docs {
63
+ color: #888;
64
+ }
65
+
66
+ button {
67
+ border-radius: 8px;
68
+ border: 1px solid transparent;
69
+ padding: 0.6em 1.2em;
70
+ font-size: 1em;
71
+ font-weight: 500;
72
+ font-family: inherit;
73
+ background-color: #1a1a1a;
74
+ cursor: pointer;
75
+ transition: border-color 0.25s;
76
+ }
77
+ button:hover {
78
+ border-color: #646cff;
79
+ }
80
+ button:focus,
81
+ button:focus-visible {
82
+ outline: 4px auto -webkit-focus-ring-color;
83
+ }
84
+
85
+ @media (prefers-color-scheme: light) {
86
+ :root {
87
+ color: #213547;
88
+ background-color: #ffffff;
89
+ }
90
+ a:hover {
91
+ color: #747bff;
92
+ }
93
+ button {
94
+ background-color: #f9f9f9;
95
+ }
96
+ }
@@ -0,0 +1,9 @@
1
+ /// <reference types="vite/client" />
2
+
3
+ interface ImportMetaEnv {
4
+ readonly VITE_EXAMPLE_ENV_VAR: string;
5
+ }
6
+
7
+ interface ImportMeta {
8
+ readonly env: ImportMetaEnv;
9
+ }
@@ -0,0 +1,15 @@
1
+ import assert from 'node:assert/strict';
2
+ import { test } from 'node:test';
3
+ import { decrement, increment } from '../src/counter.js';
4
+
5
+ test('increment function', () => {
6
+ assert.strictEqual(increment(0), 1);
7
+ assert.strictEqual(increment(1), 2);
8
+ assert.strictEqual(increment(-1), 0);
9
+ });
10
+
11
+ test('decrement function', () => {
12
+ assert.strictEqual(decrement(0), -1);
13
+ assert.strictEqual(decrement(1), 0);
14
+ assert.strictEqual(decrement(-1), -2);
15
+ });
@@ -0,0 +1,22 @@
1
+ import react from '@vitejs/plugin-react';
2
+ import path from 'node:path';
3
+ import { defineConfig } from 'vite';
4
+
5
+ // https://vite.dev/config/
6
+ export default defineConfig({
7
+ plugins: [
8
+ react(),
9
+ ],
10
+ resolve: {
11
+ alias: {
12
+ '@': path.resolve(import.meta.dirname, './src'),
13
+ },
14
+ },
15
+ build: {
16
+ outDir: 'dist',
17
+ emptyOutDir: true,
18
+ rolldownOptions: {
19
+ external: ['**/*.test.*', '**/*.spec.*'],
20
+ },
21
+ },
22
+ });
@@ -89,7 +89,7 @@ These schemas are the heart of a great Harper app, specifying which tables you w
89
89
 
90
90
  ### View Your Website
91
91
 
92
- Pop open [http://localhost:9926](http://localhost:9926) to view [web/index.html](./web/index.html) in your browser.
92
+ Pop open [http://localhost:9926](http://localhost:9926) to view [index.html](./index.html) in your browser.
93
93
 
94
94
  ### Use Your API
95
95
 
@@ -113,7 +113,11 @@ Take a look at the [default configuration](./config.yaml), which specifies how f
113
113
 
114
114
  When you are ready, head to [https://fabric.harper.fast/](https://fabric.harper.fast/), log in to your account, and create a cluster.
115
115
 
116
- Come back here and configure your [.env](./.env) file with your secure cluster credentials. Don't commit this file to source control!
116
+ Come back and log in your local CLI to your cluster:
117
+
118
+ ```sh
119
+ harper login
120
+ ```
117
121
 
118
122
  Then you can deploy your app to your cluster:
119
123
 
@@ -1,6 +1,5 @@
1
1
  .DS_Store
2
- web
3
- deploy
2
+ dist
4
3
 
5
4
  #
6
5
  # https://raw.githubusercontent.com/github/gitignore/refs/heads/main/Node.gitignore
@@ -25,6 +25,19 @@ jsResource:
25
25
  globalTypes: 'schemas/globalTypes.d.ts'
26
26
  schemaTypes: 'schemas/types.ts'
27
27
 
28
- # Bootstraps Vite to build your frontend to HTML/JS/CSS
29
- '@harperfast/vite-plugin':
30
- package: '@harperfast/vite-plugin'
28
+ # Bootstraps Vite to build your frontend to HTML/JS/CSS.
29
+ # In production it builds your app (and recompiles when files in `files` change); the `static`
30
+ # component below serves the built output. Listed before `static` so its dev server wins in `harper dev`.
31
+ '@harperfast/vite':
32
+ package: '@harperfast/vite'
33
+ files: 'src/**/*'
34
+ output: 'dist'
35
+
36
+ # Serves the built frontend from Vite's output directory. `notFound` + `fallthrough: false` makes
37
+ # client-side routing work (unmatched routes return index.html); the REST routes above take precedence.
38
+ static:
39
+ files: 'dist/**'
40
+ notFound:
41
+ file: 'index.html'
42
+ statusCode: 200
43
+ fallthrough: false
@@ -13,22 +13,24 @@
13
13
  "test": "node --test test/*.test.ts",
14
14
  "test:watch": "node --watch --test test/*.test.ts",
15
15
  "build": "vite build",
16
- "deploy": "rm -Rf deploy && npm run build && mkdir deploy && mv web deploy/ && cp -R deploy-template/* deploy/ && cp -R schemas resources deploy/ && (cd deploy && harper deploy_component . project=web restart=true replicated=true) && rm -Rf deploy"
16
+ "deploy": "harper deploy_component . restart=true replicated=true"
17
+ },
18
+ "dependencies": {
19
+ "@harperfast/schema-codegen": "^1.0.10",
20
+ "@harperfast/vite": "^1.1.0",
21
+ "@vitejs/plugin-react": "^6.0.1",
22
+ "react": "^19.2.4",
23
+ "react-dom": "^19.2.4",
24
+ "vite": "^8.0.0"
17
25
  },
18
26
  "devDependencies": {
19
27
  "@eslint/js": "^10.0.1",
20
- "@harperfast/schema-codegen": "^1.0.10",
21
- "@harperfast/vite-plugin": "^0.2.1",
22
28
  "@types/node": "^24.10.1",
23
29
  "@types/react": "^19.2.10",
24
30
  "@types/react-dom": "^19.2.3",
25
- "@vitejs/plugin-react": "^6.0.1",
26
31
  "eslint": "^10.0.2",
27
32
  "globals": "^17.4.0",
28
33
  "prettier": "^3.8.1",
29
- "react": "^19.2.4",
30
- "react-dom": "^19.2.4",
31
- "typescript": "~6.0.0",
32
- "vite": "^8.0.0"
34
+ "typescript": "~6.0.0"
33
35
  }
34
36
  }
@@ -9,11 +9,11 @@ export default defineConfig({
9
9
  ],
10
10
  resolve: {
11
11
  alias: {
12
- '@': path.resolve(__dirname, './src'),
12
+ '@': path.resolve(import.meta.dirname, './src'),
13
13
  },
14
14
  },
15
15
  build: {
16
- outDir: 'web',
16
+ outDir: 'dist',
17
17
  emptyOutDir: true,
18
18
  rolldownOptions: {
19
19
  external: ['**/*.test.*', '**/*.spec.*'],
@@ -0,0 +1,132 @@
1
+ # your-project-name-here
2
+
3
+ Your new app is now ready for development!
4
+
5
+ Here's what you should do next:
6
+
7
+ ## Installation
8
+
9
+ To get started, make sure you have [installed Harper](https://docs.harperdb.io/docs/deployments/install-harper):
10
+
11
+ ```sh
12
+ npm install -g harper
13
+ ```
14
+
15
+ ## Development
16
+
17
+ Then you can start your app:
18
+
19
+ ```sh
20
+ npm run dev
21
+ ```
22
+
23
+ TypeScript is supported at runtime in Node.js through [type stripping](https://nodejs.org/api/typescript.html#type-stripping). Full TypeScript language support can be enabled through integrating third party build steps to transpile your TypeScript into JavaScript.
24
+
25
+ ### Define Your Schema
26
+
27
+ 1. Create a new yourTableName.graphql file in the [schemas](./schemas) directory.
28
+ 2. Craft your schema by hand.
29
+ 3. Save your changes.
30
+
31
+ These schemas are the heart of a great Harper app, specifying which tables you want and what attributes/fields they should have. Any table you `@export` stands up [endpoints automatically](./.agents/skills/harper-best-practices/rules/automatic-apis.md).
32
+
33
+ ### Add Custom Endpoints
34
+
35
+ 1. Create a new greeting.ts file in the [resources](./resources) directory.
36
+
37
+ 2. Customize your resource:
38
+
39
+ ```typescript
40
+ import { type RecordObject, type RequestTargetOrId, Resource } from 'harper';
41
+
42
+ interface GreetingRecord {
43
+ greeting: string;
44
+ }
45
+
46
+ export class Greeting extends Resource<GreetingRecord> {
47
+ static loadAsInstance = false;
48
+
49
+ async post(
50
+ target: RequestTargetOrId,
51
+ newRecord: Partial<GreetingRecord & RecordObject>,
52
+ ): Promise<GreetingRecord> {
53
+ // By default, only super users can access these endpoints.
54
+ return { greeting: 'Greetings, post!' };
55
+ }
56
+
57
+ async get(target?: RequestTargetOrId): Promise<GreetingRecord> {
58
+ // But if we want anyone to be able to access it, we can turn off the permission checks!
59
+ target.checkPermission = false;
60
+ return { greeting: 'Greetings, get! ' + process.version };
61
+ }
62
+
63
+ async put(
64
+ target: RequestTargetOrId,
65
+ record: GreetingRecord & RecordObject,
66
+ ): Promise<GreetingRecord> {
67
+ target.checkPermission = false;
68
+ if (this.getCurrentUser()?.name?.includes('Coffee')) {
69
+ // You can add your own authorization guards, of course.
70
+ return new Response('Coffee? COFFEE?!', { status: 418 });
71
+ }
72
+ return { greeting: 'Sssssssssssssss!' };
73
+ }
74
+
75
+ async patch(
76
+ target: RequestTargetOrId,
77
+ record: Partial<GreetingRecord & RecordObject>,
78
+ ): Promise<GreetingRecord> {
79
+ return { greeting: 'We can make this work!' };
80
+ }
81
+
82
+ async delete(target: RequestTargetOrId): Promise<boolean> {
83
+ return true;
84
+ }
85
+ }
86
+ ```
87
+
88
+ 3. Save your changes.
89
+
90
+ ### View Your Website
91
+
92
+ Pop open [http://localhost:9926](http://localhost:9926) to view [index.html](./index.html) in your browser.
93
+
94
+ ### Use Your API
95
+
96
+ Test your application works by querying the `/Greeting` endpoint:
97
+
98
+ ```sh
99
+ curl http://localhost:9926/Greeting
100
+ ```
101
+
102
+ You should see the following:
103
+
104
+ ```json
105
+ { "greeting": "Hello, world!" }
106
+ ```
107
+
108
+ ### Configure Your App
109
+
110
+ Take a look at the [default configuration](./config.yaml), which specifies how files are handled in your application.
111
+
112
+ ## Deployment
113
+
114
+ When you are ready, head to [https://fabric.harper.fast/](https://fabric.harper.fast/), log in to your account, and create a cluster.
115
+
116
+ Come back and log in your local CLI to your cluster:
117
+
118
+ ```sh
119
+ harper login
120
+ ```
121
+
122
+ Then you can deploy your app to your cluster:
123
+
124
+ ```sh
125
+ npm run deploy
126
+ ```
127
+
128
+ ## Keep Going!
129
+
130
+ For more information about getting started with Harper and building applications, see our [getting started guide](https://docs.harperdb.io/docs).
131
+
132
+ For more information on Harper Components, see the [Components documentation](https://docs.harperdb.io/docs/reference/components).
@@ -0,0 +1 @@
1
+ .env
@@ -0,0 +1 @@
1
+ CLI_TARGET='your-fabric.harper.fast-cluster-url-here'
@@ -0,0 +1 @@
1
+ CLI_TARGET='YOUR_FABRIC.HARPER.FAST_CLUSTER_URL_HERE'
@@ -0,0 +1,33 @@
1
+ name: Deploy to Harper Fabric
2
+ on:
3
+ workflow_dispatch:
4
+ # push:
5
+ # branches:
6
+ # - main
7
+
8
+ concurrency:
9
+ group: main
10
+ cancel-in-progress: false
11
+
12
+ jobs:
13
+ deploy:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - name: Checkout code
17
+ uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
18
+ with:
19
+ fetch-depth: 0
20
+ fetch-tags: true
21
+ - name: Set up Node.js
22
+ uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
23
+ with:
24
+ cache: 'npm'
25
+ node-version-file: '.nvmrc'
26
+ - name: Install dependencies
27
+ run: npm ci
28
+ - name: Run unit tests
29
+ run: npm test
30
+ - name: Run lint
31
+ run: npm run lint
32
+ - name: Build & deploy
33
+ run: npm run deploy