create-harper 0.0.1 → 0.0.2

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 (102) hide show
  1. package/lib/constants/defaultTargetDir.js +1 -0
  2. package/lib/constants/frameworks.js +75 -0
  3. package/lib/constants/helpMessage.js +23 -0
  4. package/lib/constants/renameFiles.js +6 -0
  5. package/lib/constants/templates.js +6 -0
  6. package/lib/fs/applyAndWriteTemplateFile.js +9 -0
  7. package/lib/fs/copy.js +11 -0
  8. package/lib/fs/copyDir.js +12 -0
  9. package/lib/fs/crawlTemplateDir.js +18 -0
  10. package/lib/fs/editFile.js +6 -0
  11. package/lib/fs/emptyDir.js +14 -0
  12. package/lib/fs/formatTargetDir.js +3 -0
  13. package/lib/fs/isEmpty.js +6 -0
  14. package/lib/install.js +17 -0
  15. package/lib/pkg/getFullCustomCommand.js +47 -0
  16. package/lib/pkg/getInstallCommand.js +6 -0
  17. package/lib/pkg/getRunCommand.js +12 -0
  18. package/lib/pkg/isValidPackageName.js +5 -0
  19. package/lib/pkg/pkgFromUserAgent.js +9 -0
  20. package/lib/pkg/toValidPackageName.js +8 -0
  21. package/lib/run.js +14 -0
  22. package/lib/start.js +15 -0
  23. package/package.json +10 -2
  24. package/template-barebones/README.md +7 -0
  25. package/template-barebones/config.yaml +7 -0
  26. package/template-barebones/package.json +14 -0
  27. package/template-barebones/schema.graphql +1 -0
  28. package/template-react/README.md +45 -0
  29. package/template-react/_github/workflow/deploy.yaml +40 -0
  30. package/template-react/config.yaml +23 -0
  31. package/template-react/deploy-template/config.yaml +2 -0
  32. package/template-react/deploy-template/fastify/static.js +14 -0
  33. package/template-react/deploy-template/package.json +5 -0
  34. package/template-react/index.html +13 -0
  35. package/template-react/package.json +24 -0
  36. package/template-react/public/react.svg +14 -0
  37. package/template-react/public/typescript.svg +16 -0
  38. package/template-react/public/vite.svg +42 -0
  39. package/template-react/resources.js +27 -0
  40. package/template-react/schema.graphql +5 -0
  41. package/template-react/src/App.jsx +34 -0
  42. package/template-react/src/main.jsx +13 -0
  43. package/template-react/src/style.css +96 -0
  44. package/template-react/src/vite-env.d.ts +9 -0
  45. package/template-react/vite.config.js +22 -0
  46. package/template-react-ts/README.md +45 -0
  47. package/template-react-ts/_github/workflow/deploy.yaml +40 -0
  48. package/template-react-ts/config.yaml +23 -0
  49. package/template-react-ts/deploy-template/config.yaml +2 -0
  50. package/template-react-ts/deploy-template/fastify/static.js +14 -0
  51. package/template-react-ts/deploy-template/package.json +5 -0
  52. package/template-react-ts/index.html +13 -0
  53. package/template-react-ts/package.json +28 -0
  54. package/template-react-ts/public/react.svg +14 -0
  55. package/template-react-ts/public/typescript.svg +16 -0
  56. package/template-react-ts/public/vite.svg +42 -0
  57. package/template-react-ts/resources.ts +52 -0
  58. package/template-react-ts/schema.graphql +5 -0
  59. package/template-react-ts/src/App.tsx +34 -0
  60. package/template-react-ts/src/main.tsx +13 -0
  61. package/template-react-ts/src/style.css +96 -0
  62. package/template-react-ts/src/vite-env.d.ts +9 -0
  63. package/template-react-ts/tsconfig.json +34 -0
  64. package/template-react-ts/vite.config.ts +22 -0
  65. package/template-shared/_aiignore +1 -0
  66. package/template-shared/_env.example +3 -0
  67. package/template-shared/_gitignore +147 -0
  68. package/template-shared/graphql.config.yml +3 -0
  69. package/template-studio/README.md +34 -0
  70. package/template-studio/config.yaml +24 -0
  71. package/template-studio/package.json +14 -0
  72. package/template-studio/resources.js +27 -0
  73. package/template-studio/schema.graphql +7 -0
  74. package/template-studio/web/index.html +28 -0
  75. package/template-studio/web/index.js +18 -0
  76. package/template-studio/web/styles.css +57 -0
  77. package/template-studio-ts/README.md +34 -0
  78. package/template-studio-ts/config.yaml +24 -0
  79. package/template-studio-ts/package.json +14 -0
  80. package/template-studio-ts/resources.ts +52 -0
  81. package/template-studio-ts/schema.graphql +7 -0
  82. package/template-studio-ts/tsconfig.json +10 -0
  83. package/template-studio-ts/web/index.html +28 -0
  84. package/template-studio-ts/web/index.js +18 -0
  85. package/template-studio-ts/web/styles.css +57 -0
  86. package/template-vanilla/README.md +57 -0
  87. package/template-vanilla/config.yaml +24 -0
  88. package/template-vanilla/package.json +14 -0
  89. package/template-vanilla/resources.js +27 -0
  90. package/template-vanilla/schema.graphql +7 -0
  91. package/template-vanilla/web/index.html +28 -0
  92. package/template-vanilla/web/index.js +18 -0
  93. package/template-vanilla/web/styles.css +57 -0
  94. package/template-vanilla-ts/README.md +57 -0
  95. package/template-vanilla-ts/config.yaml +24 -0
  96. package/template-vanilla-ts/package.json +14 -0
  97. package/template-vanilla-ts/resources.ts +52 -0
  98. package/template-vanilla-ts/schema.graphql +7 -0
  99. package/template-vanilla-ts/tsconfig.json +10 -0
  100. package/template-vanilla-ts/web/index.html +28 -0
  101. package/template-vanilla-ts/web/index.js +18 -0
  102. package/template-vanilla-ts/web/styles.css +57 -0
@@ -0,0 +1 @@
1
+ export const defaultTargetDir = 'harper-project';
@@ -0,0 +1,75 @@
1
+ import colors from 'picocolors';
2
+
3
+ const {
4
+ blue,
5
+ cyan,
6
+ gray,
7
+ yellow,
8
+ } = colors;
9
+
10
+ export const FRAMEWORKS = [
11
+ {
12
+ name: 'vanilla',
13
+ display: 'Vanilla',
14
+ color: yellow,
15
+ variants: [
16
+ {
17
+ name: 'vanilla-ts',
18
+ display: 'TypeScript',
19
+ color: blue,
20
+ },
21
+ {
22
+ name: 'vanilla',
23
+ display: 'JavaScript',
24
+ color: yellow,
25
+ },
26
+ ],
27
+ },
28
+ {
29
+ name: 'react',
30
+ display: 'React',
31
+ color: cyan,
32
+ variants: [
33
+ {
34
+ name: 'react-ts',
35
+ display: 'TypeScript',
36
+ color: blue,
37
+ },
38
+ {
39
+ name: 'react',
40
+ display: 'JavaScript',
41
+ color: yellow,
42
+ },
43
+ ],
44
+ },
45
+ {
46
+ name: 'studio',
47
+ hidden: true,
48
+ display: 'Studio',
49
+ color: gray,
50
+ variants: [
51
+ {
52
+ name: 'studio-ts',
53
+ display: 'TypeScript',
54
+ color: gray,
55
+ },
56
+ {
57
+ name: 'studio',
58
+ display: 'JavaScript',
59
+ color: gray,
60
+ },
61
+ ],
62
+ },
63
+ {
64
+ name: 'barebones',
65
+ display: 'Barebones',
66
+ color: gray,
67
+ variants: [
68
+ {
69
+ name: 'barebones',
70
+ display: 'Barebones',
71
+ color: gray,
72
+ },
73
+ ],
74
+ },
75
+ ];
@@ -0,0 +1,23 @@
1
+ import colors from 'picocolors';
2
+
3
+ const {
4
+ cyan,
5
+ green,
6
+ yellow,
7
+ } = colors;
8
+
9
+ export const helpMessage = `\
10
+ Usage: create-harper [OPTION]... [DIRECTORY]
11
+
12
+ Create a new Harper project in JavaScript or TypeScript.
13
+ When running in TTY, the CLI will start in interactive mode.
14
+
15
+ Options:
16
+ -t, --template NAME use a specific template
17
+ -i, --immediate install dependencies and start dev
18
+ --interactive / --no-interactive force interactive / non-interactive mode
19
+
20
+ Available templates:
21
+ ${yellow('vanilla-ts vanilla')}
22
+ ${green('vue-ts vue')}
23
+ ${cyan('react-ts react')}`;
@@ -0,0 +1,6 @@
1
+ export const renameFiles = {
2
+ _aiignore: '.aiignore',
3
+ _gitignore: '.gitignore',
4
+ _github: '.github',
5
+ '_env.example': '.env.example',
6
+ };
@@ -0,0 +1,6 @@
1
+ import { FRAMEWORKS } from './frameworks.js';
2
+
3
+ export const TEMPLATES = FRAMEWORKS.map((f) => f.variants.map((v) => v.name)).reduce(
4
+ (a, b) => a.concat(b),
5
+ [],
6
+ );
@@ -0,0 +1,9 @@
1
+ import template from 'lodash/template.js';
2
+ import fs from 'node:fs';
3
+
4
+ export function applyAndWriteTemplateFile(targetPath, templatePath, context) {
5
+ const templateContent = fs.readFileSync(templatePath, 'utf-8');
6
+ const templateFn = template(templateContent, { interpolate: /<<([\s\S]+?)>>/g });
7
+ const updatedContent = templateFn(context);
8
+ fs.writeFileSync(targetPath, updatedContent);
9
+ }
package/lib/fs/copy.js ADDED
@@ -0,0 +1,11 @@
1
+ import fs from 'node:fs';
2
+ import { copyDir } from './copyDir.js';
3
+
4
+ export function copy(src, dest) {
5
+ const stat = fs.statSync(src);
6
+ if (stat.isDirectory()) {
7
+ copyDir(src, dest);
8
+ } else {
9
+ fs.copyFileSync(src, dest);
10
+ }
11
+ }
@@ -0,0 +1,12 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { copy } from './copy.js';
4
+
5
+ export function copyDir(srcDir, destDir) {
6
+ fs.mkdirSync(destDir, { recursive: true });
7
+ for (const file of fs.readdirSync(srcDir)) {
8
+ const srcFile = path.resolve(srcDir, file);
9
+ const destFile = path.resolve(destDir, file);
10
+ copy(srcFile, destFile);
11
+ }
12
+ }
@@ -0,0 +1,18 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { renameFiles } from '../constants/renameFiles.js';
4
+ import { applyAndWriteTemplateFile } from './applyAndWriteTemplateFile.js';
5
+
6
+ export function crawlTemplateDir(root, dir, context) {
7
+ const files = fs.readdirSync(dir);
8
+ for (const file of files) {
9
+ const targetPath = path.join(root, renameFiles[file] ?? file);
10
+ const templatePath = path.join(dir, file);
11
+ if (fs.lstatSync(templatePath).isDirectory()) {
12
+ fs.mkdirSync(targetPath, { recursive: true });
13
+ crawlTemplateDir(targetPath, templatePath, context);
14
+ } else {
15
+ applyAndWriteTemplateFile(targetPath, templatePath, context);
16
+ }
17
+ }
18
+ }
@@ -0,0 +1,6 @@
1
+ import fs from 'node:fs';
2
+
3
+ export function editFile(file, callback) {
4
+ const content = fs.readFileSync(file, 'utf-8');
5
+ fs.writeFileSync(file, callback(content), 'utf-8');
6
+ }
@@ -0,0 +1,14 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ export function emptyDir(dir) {
5
+ if (!fs.existsSync(dir)) {
6
+ return;
7
+ }
8
+ for (const file of fs.readdirSync(dir)) {
9
+ if (file === '.git') {
10
+ continue;
11
+ }
12
+ fs.rmSync(path.resolve(dir, file), { recursive: true, force: true });
13
+ }
14
+ }
@@ -0,0 +1,3 @@
1
+ export function formatTargetDir(targetDir) {
2
+ return targetDir.trim().replace(/\/+$/g, '');
3
+ }
@@ -0,0 +1,6 @@
1
+ import fs from 'node:fs';
2
+
3
+ export function isEmpty(path) {
4
+ const files = fs.readdirSync(path);
5
+ return files.length === 0 || (files.length === 1 && files[0] === '.git');
6
+ }
package/lib/install.js ADDED
@@ -0,0 +1,17 @@
1
+ import * as prompts from '@clack/prompts';
2
+ import { getInstallCommand } from './pkg/getInstallCommand.js';
3
+ import { run } from './run.js';
4
+
5
+ export function install(root, agent) {
6
+ if (process.env._HARPER_TEST_CLI) {
7
+ prompts.log.step(
8
+ `Installing dependencies with ${agent}... (skipped in test)`,
9
+ );
10
+ return;
11
+ }
12
+ prompts.log.step(`Installing dependencies with ${agent}...`);
13
+ run(getInstallCommand(agent), {
14
+ stdio: 'inherit',
15
+ cwd: root,
16
+ });
17
+ }
@@ -0,0 +1,47 @@
1
+ export function getFullCustomCommand(customCommand, pkgInfo) {
2
+ const pkgManager = pkgInfo ? pkgInfo.name : 'npm';
3
+ const isYarn1 = pkgManager === 'yarn' && pkgInfo?.version.startsWith('1.');
4
+
5
+ return (
6
+ customCommand
7
+ .replace(/^npm create (?:-- )?/, () => {
8
+ // `bun create` uses it's own set of templates,
9
+ // the closest alternative is using `bun x` directly on the package
10
+ if (pkgManager === 'bun') {
11
+ return 'bun x create-';
12
+ }
13
+ // Deno uses `run -A npm:create-` instead of `create` or `init` to also provide needed perms
14
+ if (pkgManager === 'deno') {
15
+ return 'deno run -A npm:create-';
16
+ }
17
+ // pnpm doesn't support the -- syntax
18
+ if (pkgManager === 'pnpm') {
19
+ return 'pnpm create ';
20
+ }
21
+ // For other package managers, preserve the original format
22
+ return customCommand.startsWith('npm create -- ')
23
+ ? `${pkgManager} create -- `
24
+ : `${pkgManager} create `;
25
+ })
26
+ // Only Yarn 1.x doesn't support `@version` in the `create` command
27
+ .replace('@latest', () => (isYarn1 ? '' : '@latest'))
28
+ .replace(/^npm exec /, () => {
29
+ // Prefer `pnpm dlx`, `yarn dlx`, or `bun x`
30
+ if (pkgManager === 'pnpm') {
31
+ return 'pnpm dlx ';
32
+ }
33
+ if (pkgManager === 'yarn' && !isYarn1) {
34
+ return 'yarn dlx ';
35
+ }
36
+ if (pkgManager === 'bun') {
37
+ return 'bun x ';
38
+ }
39
+ if (pkgManager === 'deno') {
40
+ return 'deno run -A npm:';
41
+ }
42
+ // Use `npm exec` in all other cases,
43
+ // including Yarn 1.x and other custom npm clients.
44
+ return 'npm exec ';
45
+ })
46
+ );
47
+ }
@@ -0,0 +1,6 @@
1
+ export function getInstallCommand(agent) {
2
+ if (agent === 'yarn') {
3
+ return [agent];
4
+ }
5
+ return [agent, 'install'];
6
+ }
@@ -0,0 +1,12 @@
1
+ export function getRunCommand(agent, script) {
2
+ switch (agent) {
3
+ case 'yarn':
4
+ case 'pnpm':
5
+ case 'bun':
6
+ return [agent, script];
7
+ case 'deno':
8
+ return [agent, 'task', script];
9
+ default:
10
+ return [agent, 'run', script];
11
+ }
12
+ }
@@ -0,0 +1,5 @@
1
+ export function isValidPackageName(projectName) {
2
+ return /^(?:@[a-z\d\-*~][a-z\d\-*._~]*\/)?[a-z\d\-~][a-z\d\-._~]*$/.test(
3
+ projectName,
4
+ );
5
+ }
@@ -0,0 +1,9 @@
1
+ export function pkgFromUserAgent(userAgent) {
2
+ if (!userAgent) { return undefined; }
3
+ const pkgSpec = userAgent.split(' ')[0];
4
+ const pkgSpecArr = pkgSpec.split('/');
5
+ return {
6
+ name: pkgSpecArr[0],
7
+ version: pkgSpecArr[1],
8
+ };
9
+ }
@@ -0,0 +1,8 @@
1
+ export function toValidPackageName(projectName) {
2
+ return projectName
3
+ .trim()
4
+ .toLowerCase()
5
+ .replace(/\s+/g, '-')
6
+ .replace(/^[._]/, '')
7
+ .replace(/[^a-z\d\-~]+/g, '-');
8
+ }
package/lib/run.js ADDED
@@ -0,0 +1,14 @@
1
+ import spawn from 'cross-spawn';
2
+
3
+ export function run([command, ...args], options) {
4
+ const { status, error } = spawn.sync(command, args, options);
5
+ if (status != null && status > 0) {
6
+ process.exit(status);
7
+ }
8
+
9
+ if (error) {
10
+ console.error(`\n${command} ${args.join(' ')} error!`);
11
+ console.error(error);
12
+ process.exit(1);
13
+ }
14
+ }
package/lib/start.js ADDED
@@ -0,0 +1,15 @@
1
+ import * as prompts from '@clack/prompts';
2
+ import { getRunCommand } from './pkg/getRunCommand.js';
3
+ import { run } from './run.js';
4
+
5
+ export function start(root, agent) {
6
+ if (process.env._HARPER_TEST_CLI) {
7
+ prompts.log.step('Starting dev server... (skipped in test)');
8
+ return;
9
+ }
10
+ prompts.log.step('Starting dev server...');
11
+ run(getRunCommand(agent, 'dev'), {
12
+ stdio: 'inherit',
13
+ cwd: root,
14
+ });
15
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-harper",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "type": "module",
5
5
  "author": {
6
6
  "name": "HarperDB",
@@ -12,7 +12,15 @@
12
12
  },
13
13
  "files": [
14
14
  "index.js",
15
- "template-*"
15
+ "lib/",
16
+ "template-barebones/",
17
+ "template-react/",
18
+ "template-react-ts/",
19
+ "template-shared/",
20
+ "template-studio/",
21
+ "template-studio-ts/",
22
+ "template-vanilla/",
23
+ "template-vanilla-ts/"
16
24
  ],
17
25
  "scripts": {
18
26
  "lint": "oxlint .",
@@ -0,0 +1,7 @@
1
+ # <<projectName>>
2
+
3
+ This repository is intended for use alongside the Harper Learn ["Getting Started > Create Your First Application"](https://docs.harperdb.io/learn/getting-started/create-your-first-application) guide.
4
+
5
+ The `main` branch is the starting point for the guide.
6
+
7
+ The `completed` branch is the completed code example if you need to check your work.
@@ -0,0 +1,7 @@
1
+ # yaml-language-server: $schema=./node_modules/harperdb/config-app.schema.json
2
+
3
+ # This is the configuration file for the application.
4
+ # It specifies built-in Harper components that will load the specified feature and files.
5
+ # For more information, see https://docs.harperdb.io/docs/reference/components/built-in-extensions
6
+
7
+ # Follow along with https://github.com/HarperFast/create-your-first-application to learn more!
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "<<packageName>>",
3
+ "version": "1.0.0",
4
+ "description": "Your new Harper app",
5
+ "type": "module",
6
+ "scripts": {
7
+ "start": "harperdb run .",
8
+ "dev": "harperdb dev .",
9
+ "deploy": "npx -y dotenv-cli -- harperdb deploy . restart=rolling replicated=true"
10
+ },
11
+ "devDependencies": {
12
+ "harperdb": "^4.7.15"
13
+ }
14
+ }
@@ -0,0 +1 @@
1
+ ## Table Schemas
@@ -0,0 +1,45 @@
1
+ # <<projectName>>
2
+
3
+ ## Installation
4
+
5
+ To get started, make sure you have [installed Harper](https://docs.harperdb.io/docs/deployments/install-harper), which can be done quickly:
6
+
7
+ ```sh
8
+ npm install -g harperdb
9
+ ```
10
+
11
+ ## Development
12
+
13
+ Then you can start your app:
14
+
15
+ ```sh
16
+ npm run dev
17
+ ```
18
+
19
+ Navigate to [http://localhost:9926](http://localhost:9926) in a browser and view the functional web application.
20
+
21
+ For more information about getting started with HarperDB and building applications, see our [getting started guide](https://docs.harperdb.io/docs).
22
+
23
+ For more information on Harper Components, see the [Components documentation](https://docs.harperdb.io/docs/reference/components).
24
+
25
+ Take a look at the [default configuration](./config.yaml), which specifies how files are handled in your application.
26
+
27
+ The [schema.graphql](./schema.graphql) is the table schema definition. This is the main starting point for defining your database schema, specifying which tables you want and what attributes/fields they should have.
28
+
29
+ The [resources.js](resources.ts) provides a template for defining JavaScript resource classes, for customized application logic in your endpoints.
30
+
31
+ ## Deployment
32
+
33
+ When you are ready, head to [https://fabric.harper.fast/](https://fabric.harper.fast/), log in to your account, and create a cluster.
34
+
35
+ Set up your .env file with your secure cluster credentials. Don't commit this file to source control!
36
+
37
+ ```sh
38
+ npm run login
39
+ ```
40
+
41
+ Then you can deploy your app to your cluster:
42
+
43
+ ```sh
44
+ npm run deploy
45
+ ```
@@ -0,0 +1,40 @@
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 run test
30
+ - name: Run lint
31
+ run: npm run lint
32
+ - name: Build
33
+ run: npm run build
34
+ - name: Deploy
35
+ run: |
36
+ mkdir deploy
37
+ mv web deploy/
38
+ cp -R deploy-template/* deploy/
39
+ cd deploy
40
+ CLI_TARGET_USERNAME=${{ secrets.CLI_TARGET_USERNAME }} CLI_TARGET_PASSWORD='${{ secrets.CLI_TARGET_PASSWORD }}' harperdb deploy_component project='${{ secrets.CLI_DEPLOY_TARGET_NAME }}' target='${{ secrets.CLI_DEPLOY_TARGET_URL }}' restart=false replicated=true
@@ -0,0 +1,23 @@
1
+ # yaml-language-server: $schema=./node_modules/harperdb/config-app.schema.json
2
+
3
+ # This is the configuration file for the application.
4
+ # It specifies built-in Harper components that will load the specified feature and files.
5
+ # For more information, see https://docs.harperdb.io/docs/reference/components/built-in-extensions
6
+
7
+ # Load Environment Variables from the specified file
8
+ # loadEnv:
9
+ # files: '.env'
10
+
11
+ # This provides the HTTP REST interface for all exported resources
12
+ rest: true
13
+
14
+ # These reads GraphQL schemas to define the schema of database/tables/attributes.
15
+ graphqlSchema:
16
+ files: 'schema.graphql'
17
+
18
+ # Loads JavaScript modules such that their exports are exported as resources
19
+ jsResource:
20
+ files: 'resources.js'
21
+
22
+ '@harperfast/vite-plugin':
23
+ package: '@harperfast/vite-plugin'
@@ -0,0 +1,2 @@
1
+ fastifyRoutes:
2
+ files: fastify/*.js
@@ -0,0 +1,14 @@
1
+ import fastifyStatic from '@fastify/static';
2
+ import { join } from 'path';
3
+
4
+ export default async (fastify) => {
5
+ fastify.register(fastifyStatic, {
6
+ root: join(import.meta.dirname, '../web'),
7
+ maxAge: '30d',
8
+ immutable: true,
9
+ });
10
+
11
+ fastify.get('/', function(req, reply) {
12
+ reply.sendFile('index.html', { maxAge: '1m', immutable: false });
13
+ });
14
+ };
@@ -0,0 +1,5 @@
1
+ {
2
+ "dependencies": {
3
+ "@fastify/static": "^7.0.4"
4
+ }
5
+ }
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title><<projectName>></title>
8
+ </head>
9
+ <body>
10
+ <div id="app"></div>
11
+ <script type="module" src="/src/main.jsx"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "<<packageName>>",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "harper run .",
8
+ "test": "echo 'No tests implemented yet'",
9
+ "lint": "echo 'No lint implemented yet'",
10
+ "build": "vite build",
11
+ "preview": "vite preview"
12
+ },
13
+ "devDependencies": {
14
+ "@harperfast/vite-plugin": "^0.0.1",
15
+ "@vitejs/plugin-react": "^5.1.2",
16
+ "harperdb": "^4.7.15",
17
+ "react": "^19.2.3",
18
+ "react-dom": "^19.2.3",
19
+ "vite": "npm:rolldown-vite@7.2.5"
20
+ },
21
+ "overrides": {
22
+ "vite": "npm:rolldown-vite@7.2.5"
23
+ }
24
+ }
@@ -0,0 +1,14 @@
1
+ <svg
2
+ width="100%"
3
+ height="100%"
4
+ viewBox="-10.5 -9.45 21 18.9"
5
+ fill="none"
6
+ xmlns="http://www.w3.org/2000/svg"
7
+ >
8
+ <circle cx="0" cy="0" r="2" fill="#58c4dc"></circle>
9
+ <g stroke="#58c4dc" stroke-width="1" fill="none">
10
+ <ellipse rx="10" ry="4.5"></ellipse>
11
+ <ellipse rx="10" ry="4.5" transform="rotate(60)"></ellipse>
12
+ <ellipse rx="10" ry="4.5" transform="rotate(120)"></ellipse>
13
+ </g>
14
+ </svg>
@@ -0,0 +1,16 @@
1
+ <svg
2
+ xmlns="http://www.w3.org/2000/svg"
3
+ aria-hidden="true"
4
+ role="img"
5
+ class="iconify iconify--logos"
6
+ width="32"
7
+ height="32"
8
+ preserveAspectRatio="xMidYMid meet"
9
+ viewBox="0 0 256 256"
10
+ >
11
+ <path fill="#007ACC" d="M0 128v128h256V0H0z"></path>
12
+ <path
13
+ fill="#FFF"
14
+ d="m56.612 128.85l-.081 10.483h33.32v94.68h23.568v-94.68h33.321v-10.28c0-5.69-.122-10.444-.284-10.566c-.122-.162-20.4-.244-44.983-.203l-44.74.122l-.121 10.443Zm149.955-10.742c6.501 1.625 11.459 4.51 16.01 9.224c2.357 2.52 5.851 7.111 6.136 8.208c.08.325-11.053 7.802-17.798 11.988c-.244.162-1.22-.894-2.317-2.52c-3.291-4.795-6.745-6.867-12.028-7.233c-7.76-.528-12.759 3.535-12.718 10.321c0 1.992.284 3.17 1.097 4.795c1.707 3.536 4.876 5.649 14.832 9.956c18.326 7.883 26.168 13.084 31.045 20.48c5.445 8.249 6.664 21.415 2.966 31.208c-4.063 10.646-14.14 17.879-28.323 20.276c-4.388.772-14.79.65-19.504-.203c-10.28-1.828-20.033-6.908-26.047-13.572c-2.357-2.6-6.949-9.387-6.664-9.874c.122-.163 1.178-.813 2.356-1.504c1.138-.65 5.446-3.129 9.509-5.485l7.355-4.267l1.544 2.276c2.154 3.29 6.867 7.801 9.712 9.305c8.167 4.307 19.383 3.698 24.909-1.26c2.357-2.153 3.332-4.388 3.332-7.68c0-2.966-.366-4.266-1.91-6.501c-1.99-2.845-6.054-5.242-17.595-10.24c-13.206-5.69-18.895-9.224-24.096-14.832c-3.007-3.25-5.852-8.452-7.03-12.8c-.975-3.617-1.22-12.678-.447-16.335c2.723-12.76 12.353-21.659 26.25-24.3c4.51-.853 14.994-.528 19.424.569Z"
15
+ ></path>
16
+ </svg>