@@ -0,0 +1,11 @@ | |||||
root = true | |||||
[*] | |||||
charset = utf-8 | |||||
end_of_line = lf | |||||
indent_size = tab | |||||
indent_style = tab | |||||
insert_final_newline = true | |||||
max_line_length = 120 | |||||
tab_width = 2 | |||||
trim_trailing_whitespace = true |
@@ -0,0 +1,2 @@ | |||||
node_modules | |||||
.DS_Store |
@@ -0,0 +1,8 @@ | |||||
# Default ignored files | |||||
/shelf/ | |||||
/workspace.xml | |||||
# Editor-based HTTP Client requests | |||||
/httpRequests/ | |||||
# Datasource local storage ignored files | |||||
/dataSources/ | |||||
/dataSources.local.xml |
@@ -0,0 +1,13 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<module type="WEB_MODULE" version="4"> | |||||
<component name="NewModuleRootManager"> | |||||
<content url="file://$MODULE_DIR$"> | |||||
<excludeFolder url="file://$MODULE_DIR$/.tmp" /> | |||||
<excludeFolder url="file://$MODULE_DIR$/packages/core/dist" /> | |||||
<excludeFolder url="file://$MODULE_DIR$/temp" /> | |||||
<excludeFolder url="file://$MODULE_DIR$/tmp" /> | |||||
</content> | |||||
<orderEntry type="inheritedJdk" /> | |||||
<orderEntry type="sourceFolder" forTests="false" /> | |||||
</component> | |||||
</module> |
@@ -0,0 +1,8 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<project version="4"> | |||||
<component name="ProjectModuleManager"> | |||||
<modules> | |||||
<module fileurl="file://$PROJECT_DIR$/.idea/backend-template.iml" filepath="$PROJECT_DIR$/.idea/backend-template.iml" /> | |||||
</modules> | |||||
</component> | |||||
</project> |
@@ -0,0 +1,6 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<project version="4"> | |||||
<component name="VcsDirectoryMappings"> | |||||
<mapping directory="$PROJECT_DIR$" vcs="Git" /> | |||||
</component> | |||||
</project> |
@@ -0,0 +1,9 @@ | |||||
{ | |||||
"root": true, | |||||
"extends": [ | |||||
"lxsmnsyc/typescript" | |||||
], | |||||
"parserOptions": { | |||||
"project": "./tsconfig.eslint.json" | |||||
} | |||||
} |
@@ -0,0 +1,107 @@ | |||||
# Logs | |||||
logs | |||||
*.log | |||||
npm-debug.log* | |||||
yarn-debug.log* | |||||
yarn-error.log* | |||||
lerna-debug.log* | |||||
# Diagnostic reports (https://nodejs.org/api/report.html) | |||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json | |||||
# Runtime data | |||||
pids | |||||
*.pid | |||||
*.seed | |||||
*.pid.lock | |||||
# Directory for instrumented libs generated by jscoverage/JSCover | |||||
lib-cov | |||||
# Coverage directory used by tools like istanbul | |||||
coverage | |||||
*.lcov | |||||
# nyc test coverage | |||||
.nyc_output | |||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) | |||||
.grunt | |||||
# Bower dependency directory (https://bower.io/) | |||||
bower_components | |||||
# node-waf configuration | |||||
.lock-wscript | |||||
# Compiled binary addons (https://nodejs.org/api/addons.html) | |||||
build/Release | |||||
# Dependency directories | |||||
node_modules/ | |||||
jspm_packages/ | |||||
# TypeScript v1 declaration files | |||||
typings/ | |||||
# TypeScript cache | |||||
*.tsbuildinfo | |||||
# Optional npm cache directory | |||||
.npm | |||||
# Optional eslint cache | |||||
.eslintcache | |||||
# Microbundle cache | |||||
.rpt2_cache/ | |||||
.rts2_cache_cjs/ | |||||
.rts2_cache_es/ | |||||
.rts2_cache_umd/ | |||||
# Optional REPL history | |||||
.node_repl_history | |||||
# Output of 'npm pack' | |||||
*.tgz | |||||
# Yarn Integrity file | |||||
.yarn-integrity | |||||
# dotenv environment variables file | |||||
.env | |||||
.env.production | |||||
.env.development | |||||
# parcel-bundler cache (https://parceljs.org/) | |||||
.cache | |||||
# Next.js build output | |||||
.next | |||||
# Nuxt.js build / generate output | |||||
.nuxt | |||||
dist | |||||
# Gatsby files | |||||
.cache/ | |||||
# Comment in the public line in if your project uses Gatsby and *not* Next.js | |||||
# https://nextjs.org/blog/next-9-1#public-directory-support | |||||
# public | |||||
# vuepress build output | |||||
.vuepress/dist | |||||
# Serverless directories | |||||
.serverless/ | |||||
# FuseBox cache | |||||
.fusebox/ | |||||
# DynamoDB Local files | |||||
.dynamodb/ | |||||
# TernJS port file | |||||
.tern-port | |||||
.npmrc |
@@ -0,0 +1,66 @@ | |||||
{ | |||||
"name": "@modal-sh/core", | |||||
"version": "0.0.0", | |||||
"files": [ | |||||
"dist", | |||||
"src" | |||||
], | |||||
"engines": { | |||||
"node": ">=12" | |||||
}, | |||||
"license": "UNLICENSED", | |||||
"keywords": [ | |||||
"pridepack" | |||||
], | |||||
"devDependencies": { | |||||
"@types/node": "^18.14.1", | |||||
"eslint": "^8.35.0", | |||||
"eslint-config-lxsmnsyc": "^0.5.0", | |||||
"pridepack": "2.4.4", | |||||
"tslib": "^2.5.0", | |||||
"typescript": "^4.9.5", | |||||
"vitest": "^0.28.1" | |||||
}, | |||||
"scripts": { | |||||
"prepublishOnly": "pridepack clean && pridepack build", | |||||
"build": "pridepack build", | |||||
"type-check": "pridepack check", | |||||
"lint": "pridepack lint", | |||||
"clean": "pridepack clean", | |||||
"watch": "pridepack watch", | |||||
"start": "pridepack start", | |||||
"dev": "pridepack dev", | |||||
"test": "vitest" | |||||
}, | |||||
"private": true, | |||||
"description": "Core library.", | |||||
"repository": { | |||||
"url": "", | |||||
"type": "git" | |||||
}, | |||||
"homepage": "", | |||||
"bugs": { | |||||
"url": "" | |||||
}, | |||||
"author": "TheoryOfNekomata <allan.crisostomo@outlook.com>", | |||||
"publishConfig": { | |||||
"access": "restricted" | |||||
}, | |||||
"types": "./dist/types/index.d.ts", | |||||
"main": "./dist/cjs/production/index.js", | |||||
"module": "./dist/esm/production/index.js", | |||||
"exports": { | |||||
".": { | |||||
"development": { | |||||
"require": "./dist/cjs/development/index.js", | |||||
"import": "./dist/esm/development/index.js" | |||||
}, | |||||
"require": "./dist/cjs/production/index.js", | |||||
"import": "./dist/esm/production/index.js", | |||||
"types": "./dist/types/index.d.ts" | |||||
} | |||||
}, | |||||
"typesVersions": { | |||||
"*": {} | |||||
} | |||||
} |
@@ -0,0 +1,3 @@ | |||||
{ | |||||
"target": "es2018" | |||||
} |
@@ -0,0 +1,23 @@ | |||||
export interface AddFunctionOptions { | |||||
a: number; | |||||
b: number; | |||||
} | |||||
export interface AddFunction { | |||||
(options: AddFunctionOptions): number; | |||||
} | |||||
export const add: AddFunction = (options: AddFunctionOptions): number => { | |||||
if (process.env.NODE_ENV !== 'production') { | |||||
console.log('This code would not appear on production builds'); | |||||
} | |||||
const { a, b } = options as unknown as Record<string, unknown>; | |||||
if (typeof a !== 'number' || typeof b !== 'number') { | |||||
throw new TypeError('a and b must be numbers'); | |||||
} | |||||
if (!Number.isFinite(a) || !Number.isFinite(b)) { | |||||
throw new RangeError('a and b must be finite numbers'); | |||||
} | |||||
return a + b; | |||||
}; |
@@ -0,0 +1,8 @@ | |||||
import { describe, it, expect } from 'vitest'; | |||||
import { add } from '../src'; | |||||
describe('blah', () => { | |||||
it('works', () => { | |||||
expect(add({ a: 1, b: 1 })).toEqual(2); | |||||
}); | |||||
}); |
@@ -0,0 +1,24 @@ | |||||
{ | |||||
"exclude": ["node_modules"], | |||||
"include": ["src", "types", "test"], | |||||
"compilerOptions": { | |||||
"module": "ESNext", | |||||
"lib": ["ESNext"], | |||||
"importHelpers": true, | |||||
"declaration": true, | |||||
"sourceMap": true, | |||||
"rootDir": "./", | |||||
"strict": true, | |||||
"noUnusedLocals": true, | |||||
"noUnusedParameters": true, | |||||
"noImplicitReturns": true, | |||||
"noFallthroughCasesInSwitch": true, | |||||
"moduleResolution": "node", | |||||
"jsx": "react", | |||||
"esModuleInterop": true, | |||||
"target": "es2018", | |||||
"paths": { | |||||
"@/*": ["./src/*"], | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,24 @@ | |||||
{ | |||||
"exclude": ["node_modules"], | |||||
"include": ["src", "types"], | |||||
"compilerOptions": { | |||||
"module": "ESNext", | |||||
"lib": ["ESNext"], | |||||
"importHelpers": true, | |||||
"declaration": true, | |||||
"sourceMap": true, | |||||
"rootDir": "./src", | |||||
"strict": true, | |||||
"noUnusedLocals": true, | |||||
"noUnusedParameters": true, | |||||
"noImplicitReturns": true, | |||||
"noFallthroughCasesInSwitch": true, | |||||
"moduleResolution": "node", | |||||
"jsx": "react", | |||||
"esModuleInterop": true, | |||||
"target": "es2018", | |||||
"paths": { | |||||
"@/*": ["./src/*"], | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,9 @@ | |||||
{ | |||||
"root": true, | |||||
"extends": [ | |||||
"lxsmnsyc/typescript" | |||||
], | |||||
"parserOptions": { | |||||
"project": "./tsconfig.eslint.json" | |||||
} | |||||
} |
@@ -0,0 +1,107 @@ | |||||
# Logs | |||||
logs | |||||
*.log | |||||
npm-debug.log* | |||||
yarn-debug.log* | |||||
yarn-error.log* | |||||
lerna-debug.log* | |||||
# Diagnostic reports (https://nodejs.org/api/report.html) | |||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json | |||||
# Runtime data | |||||
pids | |||||
*.pid | |||||
*.seed | |||||
*.pid.lock | |||||
# Directory for instrumented libs generated by jscoverage/JSCover | |||||
lib-cov | |||||
# Coverage directory used by tools like istanbul | |||||
coverage | |||||
*.lcov | |||||
# nyc test coverage | |||||
.nyc_output | |||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) | |||||
.grunt | |||||
# Bower dependency directory (https://bower.io/) | |||||
bower_components | |||||
# node-waf configuration | |||||
.lock-wscript | |||||
# Compiled binary addons (https://nodejs.org/api/addons.html) | |||||
build/Release | |||||
# Dependency directories | |||||
node_modules/ | |||||
jspm_packages/ | |||||
# TypeScript v1 declaration files | |||||
typings/ | |||||
# TypeScript cache | |||||
*.tsbuildinfo | |||||
# Optional npm cache directory | |||||
.npm | |||||
# Optional eslint cache | |||||
.eslintcache | |||||
# Microbundle cache | |||||
.rpt2_cache/ | |||||
.rts2_cache_cjs/ | |||||
.rts2_cache_es/ | |||||
.rts2_cache_umd/ | |||||
# Optional REPL history | |||||
.node_repl_history | |||||
# Output of 'npm pack' | |||||
*.tgz | |||||
# Yarn Integrity file | |||||
.yarn-integrity | |||||
# dotenv environment variables file | |||||
.env | |||||
.env.production | |||||
.env.development | |||||
# parcel-bundler cache (https://parceljs.org/) | |||||
.cache | |||||
# Next.js build output | |||||
.next | |||||
# Nuxt.js build / generate output | |||||
.nuxt | |||||
dist | |||||
# Gatsby files | |||||
.cache/ | |||||
# Comment in the public line in if your project uses Gatsby and *not* Next.js | |||||
# https://nextjs.org/blog/next-9-1#public-directory-support | |||||
# public | |||||
# vuepress build output | |||||
.vuepress/dist | |||||
# Serverless directories | |||||
.serverless/ | |||||
# FuseBox cache | |||||
.fusebox/ | |||||
# DynamoDB Local files | |||||
.dynamodb/ | |||||
# TernJS port file | |||||
.tern-port | |||||
.npmrc |
@@ -0,0 +1,54 @@ | |||||
{ | |||||
"name": "@modal-sh/web-api", | |||||
"version": "0.0.0", | |||||
"files": [ | |||||
"dist", | |||||
"src" | |||||
], | |||||
"engines": { | |||||
"node": ">=12" | |||||
}, | |||||
"keywords": [ | |||||
"pridepack" | |||||
], | |||||
"devDependencies": { | |||||
"@types/node": "^18.14.1", | |||||
"eslint": "^8.35.0", | |||||
"eslint-config-lxsmnsyc": "^0.5.0", | |||||
"pridepack": "2.4.4", | |||||
"tslib": "^2.5.0", | |||||
"typescript": "^4.9.5", | |||||
"vite": "^4.3.9", | |||||
"vite-tsconfig-paths": "^4.2.0", | |||||
"vitest": "^0.28.1" | |||||
}, | |||||
"dependencies": { | |||||
"@modal-sh/core": "workspace:*", | |||||
"fastify": "^4.12.0" | |||||
}, | |||||
"scripts": { | |||||
"prepublishOnly": "pridepack clean && pridepack build", | |||||
"build": "pridepack build", | |||||
"type-check": "pridepack check", | |||||
"lint": "pridepack lint", | |||||
"clean": "pridepack clean", | |||||
"watch": "pridepack watch", | |||||
"start": "pridepack start", | |||||
"dev": "pridepack dev", | |||||
"test": "vitest" | |||||
}, | |||||
"private": true, | |||||
"description": "Web API.", | |||||
"repository": { | |||||
"url": "", | |||||
"type": "git" | |||||
}, | |||||
"homepage": "", | |||||
"bugs": { | |||||
"url": "" | |||||
}, | |||||
"author": "TheoryOfNekomata <allan.crisostomo@outlook.com>", | |||||
"publishConfig": { | |||||
"access": "restricted" | |||||
} | |||||
} |
@@ -0,0 +1,3 @@ | |||||
{ | |||||
"target": "es2018" | |||||
} |
@@ -0,0 +1,6 @@ | |||||
export namespace meta { | |||||
export const host = process.env.HOST ?? '0.0.0.0'; | |||||
export const port = Number(process.env.PORT ?? 8080); | |||||
export const env = process.env.NODE_ENV ?? 'development'; | |||||
} |
@@ -0,0 +1,22 @@ | |||||
import { createServer } from '@/server'; | |||||
import { addRoutes } from '@/routes'; | |||||
import * as config from '@/config'; | |||||
const logger = config.meta.env !== 'test'; | |||||
const server = createServer({ | |||||
logger, | |||||
}); | |||||
addRoutes(server); | |||||
server.listen( | |||||
{ port: config.meta.port, host: config.meta.host }, | |||||
(err, address) => { | |||||
if (err) { | |||||
server.log.error(err.message); | |||||
process.exit(1); | |||||
} | |||||
server.log.info(`server listening on ${address}`); | |||||
}, | |||||
); |
@@ -0,0 +1,23 @@ | |||||
import { FastifyInstance } from 'fastify'; | |||||
import { add, AddFunctionOptions } from '@modal-sh/core'; | |||||
export const addRoutes = (server: FastifyInstance) => { | |||||
server.post('/', async (request, reply) => { | |||||
const { a, b } = request.body as AddFunctionOptions; | |||||
try { | |||||
const response = add({a, b}); | |||||
reply.send(response); | |||||
} catch (errorRaw) { | |||||
if (errorRaw instanceof TypeError) { | |||||
reply.status(400).send(errorRaw.message); | |||||
} else if (errorRaw instanceof RangeError) { | |||||
reply.status(400).send(errorRaw.message); | |||||
} else { | |||||
const error = errorRaw as Error; | |||||
reply.status(500).send(error.message); | |||||
} | |||||
} | |||||
}); | |||||
return server; | |||||
}; |
@@ -0,0 +1,11 @@ | |||||
import fastify, { FastifyServerOptions } from 'fastify'; | |||||
export interface CreateServerOptions extends FastifyServerOptions {} | |||||
export const createServer = (options = {} as CreateServerOptions) => { | |||||
const server = fastify(options); | |||||
// TODO set up server stuff here | |||||
return server; | |||||
}; |
@@ -0,0 +1,34 @@ | |||||
import { FastifyInstance } from 'fastify'; | |||||
import { | |||||
describe, | |||||
it, | |||||
expect, | |||||
beforeAll, | |||||
afterAll, | |||||
} from 'vitest'; | |||||
import { createServer } from '../src/server'; | |||||
import { addRoutes } from '../src/routes'; | |||||
describe('Example', () => { | |||||
let SERVER: FastifyInstance; | |||||
beforeAll(() => { | |||||
SERVER = createServer(); | |||||
addRoutes(SERVER); | |||||
}); | |||||
afterAll(async () => { | |||||
await SERVER.close(); | |||||
}); | |||||
it('should have the expected content', async () => { | |||||
const response = await SERVER | |||||
.inject() | |||||
.post('/') | |||||
.body({ a: 1, b: 2 }) | |||||
.headers({ | |||||
'Accept': 'application/json', | |||||
}); | |||||
expect(response.statusCode).toBe(200); | |||||
}); | |||||
}); |
@@ -0,0 +1,24 @@ | |||||
{ | |||||
"exclude": ["node_modules"], | |||||
"include": ["src", "types", "test"], | |||||
"compilerOptions": { | |||||
"module": "ESNext", | |||||
"lib": ["DOM", "ESNext"], | |||||
"importHelpers": true, | |||||
"declaration": true, | |||||
"sourceMap": true, | |||||
"rootDir": "./", | |||||
"strict": true, | |||||
"noUnusedLocals": true, | |||||
"noUnusedParameters": true, | |||||
"noImplicitReturns": true, | |||||
"noFallthroughCasesInSwitch": true, | |||||
"moduleResolution": "node", | |||||
"jsx": "react", | |||||
"esModuleInterop": true, | |||||
"target": "es2018", | |||||
"paths": { | |||||
"@/*": ["./src/*"], | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,24 @@ | |||||
{ | |||||
"exclude": ["node_modules"], | |||||
"include": ["src", "types"], | |||||
"compilerOptions": { | |||||
"module": "ESNext", | |||||
"lib": ["ESNext"], | |||||
"importHelpers": true, | |||||
"declaration": true, | |||||
"sourceMap": true, | |||||
"rootDir": "./src", | |||||
"strict": true, | |||||
"noUnusedLocals": true, | |||||
"noUnusedParameters": true, | |||||
"noImplicitReturns": true, | |||||
"noFallthroughCasesInSwitch": true, | |||||
"moduleResolution": "node", | |||||
"jsx": "react", | |||||
"esModuleInterop": true, | |||||
"target": "es2018", | |||||
"paths": { | |||||
"@/*": ["./src/*"], | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,6 @@ | |||||
import { defineConfig } from 'vite'; | |||||
import tsconfigPaths from 'vite-tsconfig-paths'; | |||||
export default defineConfig({ | |||||
plugins: [tsconfigPaths()], | |||||
}); |
@@ -0,0 +1,2 @@ | |||||
packages: | |||||
- 'packages/*' |