feat: scaffold application #1

Merged
naomi merged 3 commits from feat/scaffold into main 2025-07-04 13:38:33 -07:00
37 changed files with 12484 additions and 11 deletions
Showing only changes of commit 452f7bb35b - Show all commits

38
.gitea/workflows/ci.yml Normal file
View File

@ -0,0 +1,38 @@
name: Node.js CI
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
lint:
name: Lint and Test
steps:
- name: Checkout Source Files
uses: actions/checkout@v4
- name: Use Node.js v24
uses: actions/setup-node@v4
with:
node-version: 24
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: 9
- name: Install Dependencies
run: pnpm install
- name: Lint Source Files
run: pnpm run lint
- name: Verify Build
run: pnpm run build
- name: Run Tests
run: pnpm run test

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
**/node_modules
/node_modules
.turbo

6
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,6 @@
{
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"eslint.validate": ["typescript"],
}

View File

@ -1,20 +1,17 @@
# New Repository Template # Hikari
This template contains all of our basic files for a new GitHub repository. There is also a handy workflow that will create an issue on a new repository made from this template, with a checklist for the steps we usually take in setting up a new repository. Hikari is our centralised platform for managing things like:
If you're starting a Node.JS project with TypeScript, we have a [specific template](https://github.com/naomi-lgbt/nodejs-typescript-template) for that purpose. - Your user account and information
- Your subscriptions to our products
- Your licenses for our products
- Configurations for some of our products (such as our Discord bots)
## Readme She also offers a paid AI agent to assist with our products and support queries.
Delete all of the above text (including this line), and uncomment the below text to use our standard readme template.
<!-- # Project Name
Project Description
## Live Version ## Live Version
This page is currently deployed. [View the live website.] This page is currently deployed. [View the live website.](https://hikari.nhcarrigan.com)
## Feedback and Bugs ## Feedback and Bugs

17
client/.editorconfig Normal file
View File

@ -0,0 +1,17 @@
# Editor configuration, see https://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
[*.ts]
quote_type = single
ij_typescript_use_double_quotes = false
[*.md]
max_line_length = off
trim_trailing_whitespace = false

42
client/.gitignore vendored Normal file
View File

@ -0,0 +1,42 @@
# See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files.
# Compiled output
/dist
/tmp
/out-tsc
/bazel-out
# Node
/node_modules
npm-debug.log
yarn-error.log
# IDEs and editors
.idea/
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# Visual Studio Code
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history/*
# Miscellaneous
/.angular/cache
.sass-cache/
/connect.lock
/coverage
/libpeerconnection.log
testem.log
/typings
# System files
.DS_Store
Thumbs.db

4
client/.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,4 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846
"recommendations": ["angular.ng-template"]
}

20
client/.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,20 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "ng serve",
"type": "chrome",
"request": "launch",
"preLaunchTask": "npm: start",
"url": "http://localhost:4200/"
},
{
"name": "ng test",
"type": "chrome",
"request": "launch",
"preLaunchTask": "npm: test",
"url": "http://localhost:9876/debug.html"
}
]
}

42
client/.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,42 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "start",
"isBackground": true,
"problemMatcher": {
"owner": "typescript",
"pattern": "$tsc",
"background": {
"activeOnStart": true,
"beginsPattern": {
"regexp": "(.*?)"
},
"endsPattern": {
"regexp": "bundle generation complete"
}
}
}
},
{
"type": "npm",
"script": "test",
"isBackground": true,
"problemMatcher": {
"owner": "typescript",
"pattern": "$tsc",
"background": {
"activeOnStart": true,
"beginsPattern": {
"regexp": "(.*?)"
},
"endsPattern": {
"regexp": "bundle generation complete"
}
}
}
}
]
}

59
client/README.md Normal file
View File

@ -0,0 +1,59 @@
# Client
This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 20.0.4.
## Development server
To start a local development server, run:
```bash
ng serve
```
Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files.
## Code scaffolding
Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
```bash
ng generate component component-name
```
For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
```bash
ng generate --help
```
## Building
To build the project run:
```bash
ng build
```
This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed.
## Running unit tests
To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command:
```bash
ng test
```
## Running end-to-end tests
For end-to-end (e2e) testing, run:
```bash
ng e2e
```
Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
## Additional Resources
For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.

76
client/angular.json Normal file
View File

@ -0,0 +1,76 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"client": {
"projectType": "application",
"schematics": {},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular/build:application",
"options": {
"outputPath": "dist/client",
"index": "src/index.html",
"browser": "src/main.ts",
"polyfills": [
"zone.js"
],
"tsConfig": "tsconfig.json",
"assets": [
{
"glob": "**/*",
"input": "public"
}
],
"styles": [
"src/styles.css"
],
"scripts": []
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kB",
"maximumError": "1MB"
},
{
"type": "anyComponentStyle",
"maximumWarning": "4kB",
"maximumError": "8kB"
}
],
"outputHashing": "all"
},
"development": {
"optimization": false,
"extractLicenses": false,
"sourceMap": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular/build:dev-server",
"configurations": {
"production": {
"buildTarget": "client:build:production"
},
"development": {
"buildTarget": "client:build:development"
}
},
"defaultConfiguration": "development"
}
}
}
},
"cli": {
"analytics": "9b43c6dc-600f-45e2-9c3a-bcdd024a3346"
}
}

22
client/eslint.config.js Normal file
View File

@ -0,0 +1,22 @@
import NaomisConfig from "@nhcarrigan/eslint-config";
export default [
...NaomisConfig,
{
rules: {
"no-console": "off",
"new-cap": "off",
"@typescript-eslint/naming-convention": "off",
"jsdoc/require-jsdoc": "off",
"jsdoc/require-param": "off",
"jsdoc/require-returns": "off",
"@typescript-eslint/no-useless-constructor": "off",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/consistent-type-assertions": "off",
"@typescript-eslint/no-extraneous-class": "off",
"stylistic/no-multi-spaces": "off",
"unicorn/filename-case": "off",
"@typescript-eslint/consistent-type-imports": "off",
},
},
];

48
client/package.json Normal file
View File

@ -0,0 +1,48 @@
{
"name": "client",
"version": "0.0.0",
"type": "module",
"scripts": {
"ng": "ng",
"dev": "ng dev",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "echo 'No tests yet' && exit 0",
"lint": "eslint ./src --max-warnings 0"
},
"prettier": {
"overrides": [
{
"files": "*.html",
"options": {
"parser": "angular"
}
}
]
},
"private": true,
"dependencies": {
"@angular/common": "20.0.6",
"@angular/compiler": "20.0.6",
"@angular/core": "20.0.6",
"@angular/forms": "20.0.6",
"@angular/platform-browser": "20.0.6",
"@angular/router": "20.0.6",
"rxjs": "7.8.2",
"tslib": "2.8.1",
"zone.js": "0.15.1"
},
"devDependencies": {
"@angular/build": "20.0.5",
"@angular/cli": "20.0.5",
"@angular/compiler-cli": "20.0.6",
"@types/jasmine": "5.1.8",
"jasmine-core": "5.8.0",
"karma": "6.4.4",
"karma-chrome-launcher": "3.2.0",
"karma-coverage": "2.2.1",
"karma-jasmine": "5.1.0",
"karma-jasmine-html-reporter": "2.1.0",
"typescript": "5.8.3"
}
}

BIN
client/public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,21 @@
/**
* @copyright nhcarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import {
ApplicationConfig,
provideBrowserGlobalErrorListeners,
provideZoneChangeDetection,
} from "@angular/core";
import { provideRouter } from "@angular/router";
import { routes } from "./app.routes";
export const appConfig: ApplicationConfig = {
providers: [
provideBrowserGlobalErrorListeners(),
provideZoneChangeDetection({ eventCoalescing: true }),
provideRouter(routes),
],
};

0
client/src/app/app.css Normal file
View File

3
client/src/app/app.html Normal file
View File

@ -0,0 +1,3 @@
<main>
<router-outlet></router-outlet>
</main>

View File

@ -0,0 +1,12 @@
/**
* @copyright nhcarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { Routes } from "@angular/router";
import { Home } from "./home/home.js";
export const routes: Routes = [
{ component: Home, path: "", pathMatch: "full" },
];

18
client/src/app/app.ts Normal file
View File

@ -0,0 +1,18 @@
/**
* @copyright nhcarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { Component } from "@angular/core";
import { RouterOutlet } from "@angular/router";
@Component({
imports: [ RouterOutlet ],
selector: "app-root",
styleUrl: "./app.css",
templateUrl: "./app.html",
})
export class App {
protected title = "client";
}

View File

View File

@ -0,0 +1,8 @@
<h1>Hi there, I'm Hikari~!</h1>
<img src="https://cdn.nhcarrigan.com/new-avatars/hikari-full.png" alt="Hikari" height="250" />
<p>
I am here to help you with all of NHCarrigan's products, including things like managing your subscriptions and configuring applications!
</p>
<p>
Naomi is still hard at work bringing me to life! We would love to hear your thoughts in our <a href="https://chat.nhcarrigan.com" target="_blank">community</a>~!
</p>

View File

@ -0,0 +1,17 @@
/**
* @copyright nhcarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { Component } from "@angular/core";
@Component({
imports: [],
selector: "app-home",
styleUrl: "./home.css",
templateUrl: "./home.html",
})
export class Home {
}

15
client/src/index.html Normal file
View File

@ -0,0 +1,15 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Hikari</title>
<meta name="description" content="Dashboard and account management platform for NHCarrigan's products.">
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
<script src="https://cdn.nhcarrigan.com/headers/index.js"></script>
</html>

15
client/src/main.ts Normal file
View File

@ -0,0 +1,15 @@
/**
* @copyright nhcarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { bootstrapApplication } from "@angular/platform-browser";
import { appConfig } from "./app/app.config.js";
import { App } from "./app/app.js";
bootstrapApplication(App, appConfig).
// eslint-disable-next-line unicorn/prefer-top-level-await -- Angular wonky
catch((error: unknown) => {
console.error(error);
});

1
client/src/styles.css Normal file
View File

@ -0,0 +1 @@
/* You can add global styles to this file, and also import other style files */

27
client/tsconfig.json Normal file
View File

@ -0,0 +1,27 @@
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
{
"compileOnSave": false,
"compilerOptions": {
"outDir": "./dist/out-tsc",
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"skipLibCheck": true,
"isolatedModules": true,
"esModuleInterop": true,
"experimentalDecorators": true,
"moduleResolution": "bundler",
"importHelpers": true,
"target": "ES2022",
"module": "ES2022",
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
}
}

23
package.json Normal file
View File

@ -0,0 +1,23 @@
{
"name": "hikari",
"version": "0.0.0",
"description": "Dashboard and account management for NHCarrigan",
"main": "index.js",
"type": "module",
"scripts": {
"lint": "turbo lint",
"build": "turbo build",
"dev": "turbo dev",
"test": "turbo test"
},
"keywords": [],
"author": "Naomi Carrigan",
"license": "See license in LICENSE.md",
"packageManager": "pnpm@10.12.3",
"devDependencies": {
"@nhcarrigan/eslint-config": "5.2.0",
"@nhcarrigan/typescript-config": "4.0.0",
"eslint": "9.30.1",
"turbo": "2.5.4"
}
}

11839
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

3
pnpm-workspace.yaml Normal file
View File

@ -0,0 +1,3 @@
packages:
- client
- server

1
server/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
prod

5
server/eslint.config.js Normal file
View File

@ -0,0 +1,5 @@
import NaomisConfig from '@nhcarrigan/eslint-config';
export default [
...NaomisConfig
]

24
server/package.json Normal file
View File

@ -0,0 +1,24 @@
{
"name": "server",
"version": "0.0.0",
"description": "",
"main": "prod/index.js",
"type": "module",
"scripts": {
"lint": "eslint ./src --max-warnings 0",
"build": "tsc",
"start": "op run --env-file=./prod.env -- node ./prod/index.js",
"test": "echo 'No tests yet' && exit 0"
},
"keywords": [],
"author": "",
"license": "ISC",
"packageManager": "pnpm@10.12.3",
"dependencies": {
"@nhcarrigan/logger": "1.0.0",
"fastify": "5.4.0"
},
"devDependencies": {
"@types/node": "24.0.10"
}
}

1
server/prod.env Normal file
View File

@ -0,0 +1 @@
LOG_TOKEN="op://Environment Variables - Naomi/Alert Server/api_auth"

28
server/src/index.ts Normal file
View File

@ -0,0 +1,28 @@
/**
* @copyright nhcarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import fastify from "fastify";
import { logger } from "./utils/logger.js";
const server = fastify({
logger: false,
});
server.get("/", async(_request, reply) => {
reply.redirect("https://hikari.nhcarrigan.com");
});
server.get("/health", async(_request, reply) => {
reply.status(200).send("OK~!");
});
server.listen({ port: 20_000 }, (error) => {
if (error) {
void logger.error("instantiate server", error);
return;
}
void logger.log("debug", "Server listening on port 20000.");
});

View File

@ -0,0 +1,12 @@
/**
* @copyright nhcarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { Logger } from "@nhcarrigan/logger";
export const logger = new Logger(
"Hikari API",
process.env.LOG_TOKEN ?? "",
);

7
server/tsconfig.json Normal file
View File

@ -0,0 +1,7 @@
{
"extends": "@nhcarrigan/typescript-config",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./prod",
}
}

19
turbo.json Normal file
View File

@ -0,0 +1,19 @@
{
"$schema": "https://turbo.build/schema.json",
"tasks": {
"build": {
"dependsOn": ["^lint", "^test"],
"outputs": ["dist/**", "prod/**"]
},
"test": {
"dependsOn": []
},
"lint": {
"dependsOn": []
},
"dev": {
"cache": false,
"persistent": true
}
}
}