ocean-brain 0.1.6

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 (66) hide show
  1. package/dist/index.js +42 -0
  2. package/package.json +33 -0
  3. package/server/client/dist/assets/index-BBmw_0Bo.css +1 -0
  4. package/server/client/dist/assets/index-TKn2sngc.js +393 -0
  5. package/server/client/dist/assets/module-RjUF93sV.js +716 -0
  6. package/server/client/dist/assets/native-48B9X9Wg.js +1 -0
  7. package/server/client/dist/assets/note-core-DTIu0anW.js +178 -0
  8. package/server/client/dist/assets/note-vendor-DhbUD4OO.js +54 -0
  9. package/server/client/dist/fonts/Pretendard-Bold.woff +0 -0
  10. package/server/client/dist/fonts/Pretendard-Bold.woff2 +0 -0
  11. package/server/client/dist/fonts/Pretendard-Regular.woff +0 -0
  12. package/server/client/dist/fonts/Pretendard-Regular.woff2 +0 -0
  13. package/server/client/dist/icon.png +0 -0
  14. package/server/client/dist/index.html +19 -0
  15. package/server/dist/app.js +18 -0
  16. package/server/dist/app.js.map +1 -0
  17. package/server/dist/main.js +5 -0
  18. package/server/dist/main.js.map +1 -0
  19. package/server/dist/models.js +8 -0
  20. package/server/dist/models.js.map +1 -0
  21. package/server/dist/modules/auth.js +16 -0
  22. package/server/dist/modules/auth.js.map +1 -0
  23. package/server/dist/modules/graphql.js +7 -0
  24. package/server/dist/modules/graphql.js.map +1 -0
  25. package/server/dist/modules/logger.js +72 -0
  26. package/server/dist/modules/logger.js.map +1 -0
  27. package/server/dist/modules/use-async.js +13 -0
  28. package/server/dist/modules/use-async.js.map +1 -0
  29. package/server/dist/paths.js +14 -0
  30. package/server/dist/paths.js.map +1 -0
  31. package/server/dist/schema/cache/index.js +58 -0
  32. package/server/dist/schema/cache/index.js.map +1 -0
  33. package/server/dist/schema/image/index.js +88 -0
  34. package/server/dist/schema/image/index.js.map +1 -0
  35. package/server/dist/schema/index.js +30 -0
  36. package/server/dist/schema/index.js.map +1 -0
  37. package/server/dist/schema/note/index.js +400 -0
  38. package/server/dist/schema/note/index.js.map +1 -0
  39. package/server/dist/schema/placeholder/index.js +105 -0
  40. package/server/dist/schema/placeholder/index.js.map +1 -0
  41. package/server/dist/schema/reminder/index.js +161 -0
  42. package/server/dist/schema/reminder/index.js.map +1 -0
  43. package/server/dist/schema/tag/index.js +81 -0
  44. package/server/dist/schema/tag/index.js.map +1 -0
  45. package/server/dist/types/index.js +2 -0
  46. package/server/dist/types/index.js.map +1 -0
  47. package/server/dist/types/input.js +1 -0
  48. package/server/dist/types/input.js.map +1 -0
  49. package/server/dist/urls.js +8 -0
  50. package/server/dist/urls.js.map +1 -0
  51. package/server/dist/views/image.js +101 -0
  52. package/server/dist/views/image.js.map +1 -0
  53. package/server/dist/views/index.js +2 -0
  54. package/server/dist/views/index.js.map +1 -0
  55. package/server/prisma/migrations/20230521193126_0000/migration.sql +24 -0
  56. package/server/prisma/migrations/20240317022222_0001/migration.sql +8 -0
  57. package/server/prisma/migrations/20240317094153_0002/migration.sql +8 -0
  58. package/server/prisma/migrations/20240318110450_0003/migration.sql +21 -0
  59. package/server/prisma/migrations/20240414044922_0004/migration.sql +15 -0
  60. package/server/prisma/migrations/20241115130540_0005/migration.sql +25 -0
  61. package/server/prisma/migrations/20250416124833_0006/migration.sql +29 -0
  62. package/server/prisma/migrations/20250711131318_0007/migration.sql +12 -0
  63. package/server/prisma/migrations/20251024192500_0008/migration.sql +2 -0
  64. package/server/prisma/migrations/20251026050237_0009/migration.sql +18 -0
  65. package/server/prisma/migrations/migration_lock.toml +3 -0
  66. package/server/prisma/schema.prisma +78 -0
Binary file
@@ -0,0 +1,19 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <link rel="icon" type="image/png" href="/icon.png" />
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
+ <title>Ocean Brain</title>
9
+ <script type="module" crossorigin src="/assets/index-TKn2sngc.js"></script>
10
+ <link rel="modulepreload" crossorigin href="/assets/note-core-DTIu0anW.js">
11
+ <link rel="modulepreload" crossorigin href="/assets/note-vendor-DhbUD4OO.js">
12
+ <link rel="stylesheet" crossorigin href="/assets/index-BBmw_0Bo.css">
13
+ </head>
14
+
15
+ <body>
16
+ <div id="root"></div>
17
+ </body>
18
+
19
+ </html>
@@ -0,0 +1,18 @@
1
+ import express from "express";
2
+ import session from "express-session";
3
+ import { createHandler } from "graphql-http/lib/use/express";
4
+ import logger from "./modules/logger.js";
5
+ import { paths } from "./paths.js";
6
+ import schema from "./schema/index.js";
7
+ import router from "./urls.js";
8
+ var app_default = express().use(logger).use(express.static(paths.clientDist, { extensions: ["html"] })).use("/assets/images/", express.static(paths.imageDir)).use(session({
9
+ secret: "my-secret",
10
+ resave: false,
11
+ saveUninitialized: false
12
+ })).use(express.json({ limit: "50mb" })).use("/api", router).use("/graphql", createHandler({ schema })).get(/.*/, (req, res) => {
13
+ res.sendFile(paths.clientIndex);
14
+ });
15
+ export {
16
+ app_default as default
17
+ };
18
+ //# sourceMappingURL=app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/app.ts"],"sourcesContent":["import express from 'express';\nimport session from 'express-session';\nimport { createHandler } from 'graphql-http/lib/use/express';\n\nimport logger from './modules/logger.js';\nimport { paths } from './paths.js';\nimport schema from './schema/index.js';\nimport router from './urls.js';\n\nexport default express()\n .use(logger)\n .use(express.static(paths.clientDist, { extensions: ['html'] }))\n .use('/assets/images/', express.static(paths.imageDir))\n .use(session({\n secret: 'my-secret',\n resave: false,\n saveUninitialized: false\n }))\n .use(express.json({ limit: '50mb' }))\n .use('/api', router)\n .use('/graphql', createHandler({ schema }))\n .get(/.*/, (req, res) => {\n res.sendFile(paths.clientIndex);\n });\n"],"mappings":"AAAA,OAAO,aAAa;AACpB,OAAO,aAAa;AACpB,SAAS,qBAAqB;AAE9B,OAAO,YAAY;AACnB,SAAS,aAAa;AACtB,OAAO,YAAY;AACnB,OAAO,YAAY;AAEnB,IAAO,cAAQ,QAAQ,EAClB,IAAI,MAAM,EACV,IAAI,QAAQ,OAAO,MAAM,YAAY,EAAE,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,EAC9D,IAAI,mBAAmB,QAAQ,OAAO,MAAM,QAAQ,CAAC,EACrD,IAAI,QAAQ;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,mBAAmB;AACvB,CAAC,CAAC,EACD,IAAI,QAAQ,KAAK,EAAE,OAAO,OAAO,CAAC,CAAC,EACnC,IAAI,QAAQ,MAAM,EAClB,IAAI,YAAY,cAAc,EAAE,OAAO,CAAC,CAAC,EACzC,IAAI,MAAM,CAAC,KAAK,QAAQ;AACrB,MAAI,SAAS,MAAM,WAAW;AAClC,CAAC;","names":[]}
@@ -0,0 +1,5 @@
1
+ import app from "./app.js";
2
+ const PORT = Number(process.env.PORT || 6683);
3
+ const HOST = process.env.HOST || "0.0.0.0";
4
+ app.listen(PORT, HOST, () => console.log(`http server listen on ${HOST}:${PORT}`));
5
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/main.ts"],"sourcesContent":["import app from './app.js';\n\nconst PORT = Number(process.env.PORT || 6683);\nconst HOST = process.env.HOST || '0.0.0.0';\n\napp.listen(PORT, HOST, () => console.log(`http server listen on ${HOST}:${PORT}`));\n"],"mappings":"AAAA,OAAO,SAAS;AAEhB,MAAM,OAAO,OAAO,QAAQ,IAAI,QAAQ,IAAI;AAC5C,MAAM,OAAO,QAAQ,IAAI,QAAQ;AAEjC,IAAI,OAAO,MAAM,MAAM,MAAM,QAAQ,IAAI,yBAAyB,IAAI,IAAI,IAAI,EAAE,CAAC;","names":[]}
@@ -0,0 +1,8 @@
1
+ import { PrismaClient } from "@prisma/client";
2
+ const prisma = new PrismaClient();
3
+ var models_default = prisma;
4
+ export * from "@prisma/client";
5
+ export {
6
+ models_default as default
7
+ };
8
+ //# sourceMappingURL=models.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/models.ts"],"sourcesContent":["import { PrismaClient } from '@prisma/client';\n\nconst prisma = new PrismaClient();\n\nexport default prisma;\nexport * from '@prisma/client';\n"],"mappings":"AAAA,SAAS,oBAAoB;AAE7B,MAAM,SAAS,IAAI,aAAa;AAEhC,IAAO,iBAAQ;AACf,cAAc;","names":[]}
@@ -0,0 +1,16 @@
1
+ import crypto from "crypto";
2
+ const createPasswordHash = async (password) => {
3
+ const salt = crypto.randomBytes(16).toString("hex");
4
+ const hash = crypto.pbkdf2Sync(password, salt, 1e3, 64, "sha512").toString("hex");
5
+ return `${salt}:${hash}`;
6
+ };
7
+ const comparePassword = async (password, storedHash) => {
8
+ const [salt, hash] = storedHash.split(":");
9
+ const newHash = crypto.pbkdf2Sync(password, salt, 1e3, 64, "sha512").toString("hex");
10
+ return hash === newHash;
11
+ };
12
+ export {
13
+ comparePassword,
14
+ createPasswordHash
15
+ };
16
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/modules/auth.ts"],"sourcesContent":["import crypto from 'crypto';\n\nexport const createPasswordHash = async (password: string) => {\n const salt = crypto.randomBytes(16).toString('hex');\n const hash = crypto.pbkdf2Sync(password, salt, 1000, 64, 'sha512').toString('hex');\n return `${salt}:${hash}`;\n};\n\nexport const comparePassword = async (password: string, storedHash: string) => {\n const [salt, hash] = storedHash.split(':');\n const newHash = crypto.pbkdf2Sync(password, salt, 1000, 64, 'sha512').toString('hex');\n return hash === newHash;\n};\n"],"mappings":"AAAA,OAAO,YAAY;AAEZ,MAAM,qBAAqB,OAAO,aAAqB;AAC1D,QAAM,OAAO,OAAO,YAAY,EAAE,EAAE,SAAS,KAAK;AAClD,QAAM,OAAO,OAAO,WAAW,UAAU,MAAM,KAAM,IAAI,QAAQ,EAAE,SAAS,KAAK;AACjF,SAAO,GAAG,IAAI,IAAI,IAAI;AAC1B;AAEO,MAAM,kBAAkB,OAAO,UAAkB,eAAuB;AAC3E,QAAM,CAAC,MAAM,IAAI,IAAI,WAAW,MAAM,GAAG;AACzC,QAAM,UAAU,OAAO,WAAW,UAAU,MAAM,KAAM,IAAI,QAAQ,EAAE,SAAS,KAAK;AACpF,SAAO,SAAS;AACpB;","names":[]}
@@ -0,0 +1,7 @@
1
+ function gql(texts, ...values) {
2
+ return texts.map((text, i) => text + (values[i] || "")).join("");
3
+ }
4
+ export {
5
+ gql
6
+ };
7
+ //# sourceMappingURL=graphql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/modules/graphql.ts"],"sourcesContent":["export function gql(texts: TemplateStringsArray, ...values: unknown[]) {\n return texts.map((text, i) => text + (values[i] || '')).join('');\n}\n"],"mappings":"AAAO,SAAS,IAAI,UAAgC,QAAmB;AACnE,SAAO,MAAM,IAAI,CAAC,MAAM,MAAM,QAAQ,OAAO,CAAC,KAAK,GAAG,EAAE,KAAK,EAAE;AACnE;","names":[]}
@@ -0,0 +1,72 @@
1
+ import expressWinston from "express-winston";
2
+ import winston from "winston";
3
+ const loggerOptions = {
4
+ transports: [
5
+ new winston.transports.Console()
6
+ ],
7
+ meta: true,
8
+ requestWhitelist: [
9
+ "httpVersion",
10
+ "method",
11
+ "originalUrl",
12
+ "url",
13
+ "query",
14
+ "params",
15
+ "ip",
16
+ "headers"
17
+ ],
18
+ responseWhitelist: [
19
+ "statusCode"
20
+ ],
21
+ headerBlacklist: [
22
+ "authorization",
23
+ "cookie",
24
+ "set-cookie",
25
+ "x-api-key"
26
+ ],
27
+ requestFilter: (req, propName) => {
28
+ if (propName === "headers") {
29
+ const h = req.headers || {};
30
+ return {
31
+ "user-agent": h["user-agent"],
32
+ "content-type": h["content-type"],
33
+ "accept": h["accept"],
34
+ "x-forwarded-for": h["x-forwarded-for"],
35
+ "x-real-ip": h["x-real-ip"]
36
+ };
37
+ }
38
+ return req[propName];
39
+ },
40
+ responseFilter: (res, propName) => {
41
+ return res[propName];
42
+ },
43
+ format: winston.format.combine(
44
+ winston.format.colorize({ all: true }),
45
+ winston.format.timestamp({ format: "YYYY-MM-DD HH:mm:ss" }),
46
+ winston.format.printf((info) => {
47
+ const meta = info.meta || {};
48
+ const req = meta.req || {};
49
+ const res = meta.res || {};
50
+ const rt = meta.responseTime;
51
+ const method = req.method;
52
+ const url = req.originalUrl || req.url;
53
+ const status = res.statusCode;
54
+ const headers = req.headers || {};
55
+ const ua = headers["user-agent"];
56
+ const fwd = headers["x-forwarded-for"];
57
+ const fwdFirst = typeof fwd === "string" ? fwd.split(",")[0].trim() : void 0;
58
+ const realIp = fwdFirst || headers["x-real-ip"];
59
+ const socketIp = req.ip || req.socket?.remoteAddress;
60
+ const clientIp = fwdFirst || realIp || socketIp || "";
61
+ return `${info.timestamp} ${info.level}: [${status ?? ""}] ${method || ""} ${url || ""} ${rt ?? ""}ms ip="${clientIp}" ua="${ua || ""}"`;
62
+ })
63
+ ),
64
+ colorize: true,
65
+ expressFormat: false
66
+ };
67
+ var logger_default = expressWinston.logger(loggerOptions);
68
+ export {
69
+ logger_default as default,
70
+ loggerOptions
71
+ };
72
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/modules/logger.ts"],"sourcesContent":["import type { LoggerOptions } from 'express-winston';\nimport expressWinston from 'express-winston';\nimport winston from 'winston';\nimport type { TransformableInfo } from 'logform';\n\nexport const loggerOptions: LoggerOptions = {\n transports: [\n new winston.transports.Console()\n ],\n meta: true,\n requestWhitelist: [\n 'httpVersion',\n 'method',\n 'originalUrl',\n 'url',\n 'query',\n 'params',\n 'ip',\n 'headers'\n ],\n responseWhitelist: [\n 'statusCode'\n ],\n headerBlacklist: [\n 'authorization',\n 'cookie',\n 'set-cookie',\n 'x-api-key'\n ],\n requestFilter: (\n req: { headers?: Record<string, string | string[] | undefined> } & Record<string, unknown>,\n propName: string\n ): unknown => {\n if (propName === 'headers') {\n const h = req.headers || {};\n return {\n 'user-agent': h['user-agent'],\n 'content-type': h['content-type'],\n 'accept': h['accept'],\n 'x-forwarded-for': h['x-forwarded-for'],\n 'x-real-ip': h['x-real-ip']\n };\n }\n return (req as Record<string, unknown>)[propName];\n },\n responseFilter: (res: Record<string, unknown>, propName: string): unknown => {\n return res[propName];\n },\n format: winston.format.combine(\n winston.format.colorize({ all: true }),\n winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),\n winston.format.printf((info: TransformableInfo) => {\n const meta = (info as unknown as { meta?: Record<string, unknown> }).meta || {};\n const req = (meta.req as Record<string, unknown>) || {};\n const res = (meta.res as Record<string, unknown>) || {};\n const rt = (meta as Record<string, unknown>).responseTime as number | undefined;\n const method = req.method as string | undefined;\n const url = (req.originalUrl as string | undefined) || (req.url as string | undefined);\n const status = res.statusCode as number | undefined;\n const headers = (req.headers as Record<string, string> | undefined) || {};\n const ua = headers['user-agent'];\n const fwd = headers['x-forwarded-for'];\n const fwdFirst = typeof fwd === 'string' ? fwd.split(',')[0].trim() : undefined;\n const realIp = fwdFirst || headers['x-real-ip'];\n const socketIp = (req as unknown as { ip?: string; socket?: { remoteAddress?: string } }).ip\n || (req as unknown as { socket?: { remoteAddress?: string } }).socket?.remoteAddress;\n const clientIp = fwdFirst || realIp || socketIp || '';\n return `${info.timestamp as string} ${info.level as string}: [${status ?? ''}] ${method || ''} ${url || ''} ${rt ?? ''}ms ip=\"${clientIp}\" ua=\"${ua || ''}\"`;\n })\n ),\n colorize: true,\n expressFormat: false\n};\n\nexport default expressWinston.logger(loggerOptions);\n"],"mappings":"AACA,OAAO,oBAAoB;AAC3B,OAAO,aAAa;AAGb,MAAM,gBAA+B;AAAA,EACxC,YAAY;AAAA,IACR,IAAI,QAAQ,WAAW,QAAQ;AAAA,EACnC;AAAA,EACA,MAAM;AAAA,EACN,kBAAkB;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AAAA,EACA,mBAAmB;AAAA,IACf;AAAA,EACJ;AAAA,EACA,iBAAiB;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AAAA,EACA,eAAe,CACX,KACA,aACU;AACV,QAAI,aAAa,WAAW;AACxB,YAAM,IAAI,IAAI,WAAW,CAAC;AAC1B,aAAO;AAAA,QACH,cAAc,EAAE,YAAY;AAAA,QAC5B,gBAAgB,EAAE,cAAc;AAAA,QAChC,UAAU,EAAE,QAAQ;AAAA,QACpB,mBAAmB,EAAE,iBAAiB;AAAA,QACtC,aAAa,EAAE,WAAW;AAAA,MAC9B;AAAA,IACJ;AACA,WAAQ,IAAgC,QAAQ;AAAA,EACpD;AAAA,EACA,gBAAgB,CAAC,KAA8B,aAA8B;AACzE,WAAO,IAAI,QAAQ;AAAA,EACvB;AAAA,EACA,QAAQ,QAAQ,OAAO;AAAA,IACnB,QAAQ,OAAO,SAAS,EAAE,KAAK,KAAK,CAAC;AAAA,IACrC,QAAQ,OAAO,UAAU,EAAE,QAAQ,sBAAsB,CAAC;AAAA,IAC1D,QAAQ,OAAO,OAAO,CAAC,SAA4B;AAC/C,YAAM,OAAQ,KAAuD,QAAQ,CAAC;AAC9E,YAAM,MAAO,KAAK,OAAmC,CAAC;AACtD,YAAM,MAAO,KAAK,OAAmC,CAAC;AACtD,YAAM,KAAM,KAAiC;AAC7C,YAAM,SAAS,IAAI;AACnB,YAAM,MAAO,IAAI,eAAuC,IAAI;AAC5D,YAAM,SAAS,IAAI;AACnB,YAAM,UAAW,IAAI,WAAkD,CAAC;AACxE,YAAM,KAAK,QAAQ,YAAY;AAC/B,YAAM,MAAM,QAAQ,iBAAiB;AACrC,YAAM,WAAW,OAAO,QAAQ,WAAW,IAAI,MAAM,GAAG,EAAE,CAAC,EAAE,KAAK,IAAI;AACtE,YAAM,SAAS,YAAY,QAAQ,WAAW;AAC9C,YAAM,WAAY,IAAwE,MAClF,IAA2D,QAAQ;AAC3E,YAAM,WAAW,YAAY,UAAU,YAAY;AACnD,aAAO,GAAG,KAAK,SAAmB,IAAI,KAAK,KAAe,MAAM,UAAU,EAAE,KAAK,UAAU,EAAE,IAAI,OAAO,EAAE,IAAI,MAAM,EAAE,UAAU,QAAQ,SAAS,MAAM,EAAE;AAAA,IAC7J,CAAC;AAAA,EACL;AAAA,EACA,UAAU;AAAA,EACV,eAAe;AACnB;AAEA,IAAO,iBAAQ,eAAe,OAAO,aAAa;","names":[]}
@@ -0,0 +1,13 @@
1
+ function useAsync(callback) {
2
+ return function(req, res, next) {
3
+ callback(req, res, next).catch((e) => {
4
+ res.status(500).send("Internal Server Error");
5
+ console.log(e);
6
+ next();
7
+ });
8
+ };
9
+ }
10
+ export {
11
+ useAsync as default
12
+ };
13
+ //# sourceMappingURL=use-async.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/modules/use-async.ts"],"sourcesContent":["import type {\n Request,\n Response,\n NextFunction\n} from 'express';\nimport type { Controller } from '~/types/index.js';\n\nexport default function useAsync(callback: Controller) {\n return function (req: Request, res: Response, next: NextFunction) {\n callback(req, res, next)\n .catch((e: Error) => {\n res.status(500).send('Internal Server Error');\n console.log(e);\n next();\n });\n };\n}\n"],"mappings":"AAOe,SAAR,SAA0B,UAAsB;AACnD,SAAO,SAAU,KAAc,KAAe,MAAoB;AAC9D,aAAS,KAAK,KAAK,IAAI,EAClB,MAAM,CAAC,MAAa;AACjB,UAAI,OAAO,GAAG,EAAE,KAAK,uBAAuB;AAC5C,cAAQ,IAAI,CAAC;AACb,WAAK;AAAA,IACT,CAAC;AAAA,EACT;AACJ;","names":[]}
@@ -0,0 +1,14 @@
1
+ import path from "path";
2
+ import { fileURLToPath } from "url";
3
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
4
+ const PACKAGE_ROOT = process.env.OCEAN_BRAIN_PACKAGE_ROOT || path.resolve(__dirname, "..");
5
+ const IMAGE_DIR = process.env.OCEAN_BRAIN_IMAGE_DIR || path.resolve(process.env.OCEAN_BRAIN_DATA_DIR || ".", "assets/images");
6
+ const paths = {
7
+ clientDist: path.resolve(PACKAGE_ROOT, "client/dist"),
8
+ clientIndex: path.resolve(PACKAGE_ROOT, "client/dist/index.html"),
9
+ imageDir: path.resolve(IMAGE_DIR)
10
+ };
11
+ export {
12
+ paths
13
+ };
14
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/paths.ts"],"sourcesContent":["import path from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\n// 패키지 루트 (dist/paths.js 기준 상위)\nconst PACKAGE_ROOT = process.env.OCEAN_BRAIN_PACKAGE_ROOT\n || path.resolve(__dirname, '..');\n\n// 이미지 디렉토리 (별도 지정 가능, Docker에서 분리 볼륨용)\nconst IMAGE_DIR = process.env.OCEAN_BRAIN_IMAGE_DIR\n || path.resolve(process.env.OCEAN_BRAIN_DATA_DIR || '.', 'assets/images');\n\nexport const paths = {\n clientDist: path.resolve(PACKAGE_ROOT, 'client/dist'),\n clientIndex: path.resolve(PACKAGE_ROOT, 'client/dist/index.html'),\n imageDir: path.resolve(IMAGE_DIR)\n};\n"],"mappings":"AAAA,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAE9B,MAAM,YAAY,KAAK,QAAQ,cAAc,YAAY,GAAG,CAAC;AAG7D,MAAM,eAAe,QAAQ,IAAI,4BAC1B,KAAK,QAAQ,WAAW,IAAI;AAGnC,MAAM,YAAY,QAAQ,IAAI,yBACvB,KAAK,QAAQ,QAAQ,IAAI,wBAAwB,KAAK,eAAe;AAErE,MAAM,QAAQ;AAAA,EACjB,YAAY,KAAK,QAAQ,cAAc,aAAa;AAAA,EACpD,aAAa,KAAK,QAAQ,cAAc,wBAAwB;AAAA,EAChE,UAAU,KAAK,QAAQ,SAAS;AACpC;","names":[]}
@@ -0,0 +1,58 @@
1
+ import models from "../../models.js";
2
+ import { gql } from "../../modules/graphql.js";
3
+ const cacheType = gql`
4
+ type Cache {
5
+ id: ID!
6
+ key: String!
7
+ value: String!
8
+ }
9
+ `;
10
+ const cacheQuery = gql`
11
+ type Query {
12
+ allCaches: [Cache!]!
13
+ cache(key: String!): Cache!
14
+ }
15
+ `;
16
+ const cacheMutation = gql`
17
+ type Mutation {
18
+ setCache(key: String, value: String): Cache!
19
+ deleteCache(key: String!): Boolean!
20
+ }
21
+ `;
22
+ const cacheTypeDefs = `
23
+ ${cacheType}
24
+ ${cacheQuery}
25
+ ${cacheMutation}
26
+ `;
27
+ const cacheResolvers = {
28
+ Query: {
29
+ allCaches: models.cache.findMany,
30
+ cache: (_, { key }) => models.cache.findUnique({ where: { key } })
31
+ },
32
+ Mutation: {
33
+ setCache: async (_, { key, value }) => {
34
+ const cache = await models.cache.findFirst({ where: { key } });
35
+ if (cache) {
36
+ return models.cache.update({
37
+ where: { key },
38
+ data: { value: decodeURIComponent(value) }
39
+ });
40
+ }
41
+ return models.cache.create({
42
+ data: {
43
+ key,
44
+ value: decodeURIComponent(value)
45
+ }
46
+ });
47
+ },
48
+ deleteCache: (_, { key }) => models.cache.delete({ where: { key } }).then(() => true)
49
+ }
50
+ };
51
+ export {
52
+ cacheMutation,
53
+ cacheQuery,
54
+ cacheResolvers,
55
+ cacheType,
56
+ cacheTypeDefs
57
+ };
58
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/schema/cache/index.ts"],"sourcesContent":["import type { IResolvers } from '@graphql-tools/utils';\n\nimport models, { type Cache } from '~/models.js';\nimport { gql } from '~/modules/graphql.js';\n\nexport const cacheType = gql`\n type Cache {\n id: ID!\n key: String!\n value: String!\n }\n`;\n\nexport const cacheQuery = gql`\n type Query {\n allCaches: [Cache!]!\n cache(key: String!): Cache!\n }\n`;\n\nexport const cacheMutation = gql`\n type Mutation {\n setCache(key: String, value: String): Cache!\n deleteCache(key: String!): Boolean!\n }\n`;\n\nexport const cacheTypeDefs = `\n ${cacheType}\n ${cacheQuery}\n ${cacheMutation}\n`;\n\nexport const cacheResolvers: IResolvers = {\n Query: {\n allCaches: models.cache.findMany,\n cache: (_, { key }: Cache) => models.cache.findUnique({ where: { key } })\n },\n Mutation: {\n setCache: async (_, { key, value }: Cache) => {\n const cache = await models.cache.findFirst({ where: { key } });\n if (cache) {\n return models.cache.update({\n where: { key },\n data: { value: decodeURIComponent(value) }\n });\n }\n return models.cache.create({\n data: {\n key,\n value: decodeURIComponent(value)\n }\n });\n },\n deleteCache: (_, { key }: Cache) => models.cache.delete({ where: { key } }).then(() => true)\n }\n};\n"],"mappings":"AAEA,OAAO,YAA4B;AACnC,SAAS,WAAW;AAEb,MAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQlB,MAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAOnB,MAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAOtB,MAAM,gBAAgB;AAAA,MACvB,SAAS;AAAA,MACT,UAAU;AAAA,MACV,aAAa;AAAA;AAGZ,MAAM,iBAA6B;AAAA,EACtC,OAAO;AAAA,IACH,WAAW,OAAO,MAAM;AAAA,IACxB,OAAO,CAAC,GAAG,EAAE,IAAI,MAAa,OAAO,MAAM,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAAA,EAC5E;AAAA,EACA,UAAU;AAAA,IACN,UAAU,OAAO,GAAG,EAAE,KAAK,MAAM,MAAa;AAC1C,YAAM,QAAQ,MAAM,OAAO,MAAM,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC7D,UAAI,OAAO;AACP,eAAO,OAAO,MAAM,OAAO;AAAA,UACvB,OAAO,EAAE,IAAI;AAAA,UACb,MAAM,EAAE,OAAO,mBAAmB,KAAK,EAAE;AAAA,QAC7C,CAAC;AAAA,MACL;AACA,aAAO,OAAO,MAAM,OAAO;AAAA,QACvB,MAAM;AAAA,UACF;AAAA,UACA,OAAO,mBAAmB,KAAK;AAAA,QACnC;AAAA,MACJ,CAAC;AAAA,IACL;AAAA,IACA,aAAa,CAAC,GAAG,EAAE,IAAI,MAAa,OAAO,MAAM,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,MAAM,IAAI;AAAA,EAC/F;AACJ;","names":[]}
@@ -0,0 +1,88 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import models from "../../models.js";
4
+ import { gql } from "../../modules/graphql.js";
5
+ import { paths } from "../../paths.js";
6
+ const imageType = gql`
7
+ input PaginationInput {
8
+ limit: Int!
9
+ offset: Int!
10
+ }
11
+
12
+ type Image {
13
+ id: ID!
14
+ url: String!
15
+ referenceCount: Int!
16
+ }
17
+
18
+ type Images {
19
+ totalCount: Int!
20
+ images: [Image!]!
21
+ }
22
+ `;
23
+ const imageQuery = gql`
24
+ type Query {
25
+ allImages(pagination: PaginationInput): Images!
26
+ image(id: ID!): Image!
27
+ }
28
+ `;
29
+ const imageMutation = gql`
30
+ type Mutation {
31
+ deleteImage(id: ID!): Boolean!
32
+ }
33
+ `;
34
+ const imageTypeDefs = `
35
+ ${imageType}
36
+ ${imageQuery}
37
+ ${imageMutation}
38
+ `;
39
+ const imageResolvers = {
40
+ Query: {
41
+ allImages: async (_, { pagination }) => {
42
+ const $images = models.image.findMany({
43
+ skip: pagination.offset,
44
+ take: pagination.limit,
45
+ orderBy: { createdAt: "desc" }
46
+ });
47
+ return {
48
+ totalCount: models.image.count(),
49
+ images: $images
50
+ };
51
+ },
52
+ image: async (_, { id }) => {
53
+ return models.image.findFirst({ where: { id: Number(id) } });
54
+ }
55
+ },
56
+ Mutation: {
57
+ deleteImage: async (_, { id }) => {
58
+ try {
59
+ const $image = await models.image.findFirst({ where: { id: Number(id) } });
60
+ if (!$image) {
61
+ return false;
62
+ }
63
+ const imagePath = path.resolve(paths.imageDir, $image.url.replace("/assets/images/", ""));
64
+ if (fs.existsSync(imagePath)) {
65
+ fs.unlinkSync(imagePath);
66
+ }
67
+ await models.image.delete({ where: { id: Number(id) } });
68
+ return true;
69
+ } catch (error) {
70
+ console.log(error);
71
+ return false;
72
+ }
73
+ }
74
+ },
75
+ Image: {
76
+ referenceCount: async (image) => {
77
+ return models.note.count({ where: { content: { contains: image.url } } });
78
+ }
79
+ }
80
+ };
81
+ export {
82
+ imageMutation,
83
+ imageQuery,
84
+ imageResolvers,
85
+ imageType,
86
+ imageTypeDefs
87
+ };
88
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/schema/image/index.ts"],"sourcesContent":["import type { IResolvers } from '@graphql-tools/utils';\nimport fs from 'fs';\nimport path from 'path';\n\nimport models, { type Image } from '~/models.js';\nimport { gql } from '~/modules/graphql.js';\nimport { paths } from '~/paths.js';\nimport type { Pagination } from '~/types/index.js';\n\nexport const imageType = gql`\n input PaginationInput {\n limit: Int!\n offset: Int!\n }\n\n type Image {\n id: ID!\n url: String!\n referenceCount: Int!\n }\n\n type Images {\n totalCount: Int!\n images: [Image!]!\n }\n`;\n\nexport const imageQuery = gql`\n type Query {\n allImages(pagination: PaginationInput): Images!\n image(id: ID!): Image!\n }\n`;\n\nexport const imageMutation = gql`\n type Mutation {\n deleteImage(id: ID!): Boolean!\n }\n`;\n\nexport const imageTypeDefs = `\n ${imageType}\n ${imageQuery}\n ${imageMutation}\n`;\n\nexport const imageResolvers: IResolvers = {\n Query: {\n allImages: async (_, { pagination }: {\n pagination: Pagination;\n }) => {\n const $images = models.image.findMany({\n skip: pagination.offset,\n take: pagination.limit,\n orderBy: { createdAt: 'desc' }\n });\n return {\n totalCount: models.image.count(),\n images: $images\n };\n },\n image: async (_, { id }) => {\n return models.image.findFirst({ where: { id: Number(id) } });\n }\n },\n Mutation: {\n deleteImage: async (_, { id }) => {\n try {\n const $image = await models.image.findFirst({ where: { id: Number(id) } });\n\n if (!$image) {\n return false;\n }\n\n const imagePath = path.resolve(paths.imageDir, $image.url.replace('/assets/images/', ''));\n if (fs.existsSync(imagePath)) {\n fs.unlinkSync(imagePath);\n }\n\n await models.image.delete({ where: { id: Number(id) } });\n\n return true;\n } catch (error) {\n console.log(error);\n return false;\n }\n }\n },\n Image: {\n referenceCount: async (image: Image) => {\n return models.note.count({ where: { content: { contains: image.url } } });\n }\n }\n};\n"],"mappings":"AACA,OAAO,QAAQ;AACf,OAAO,UAAU;AAEjB,OAAO,YAA4B;AACnC,SAAS,WAAW;AACpB,SAAS,aAAa;AAGf,MAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBlB,MAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAOnB,MAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAMtB,MAAM,gBAAgB;AAAA,MACvB,SAAS;AAAA,MACT,UAAU;AAAA,MACV,aAAa;AAAA;AAGZ,MAAM,iBAA6B;AAAA,EACtC,OAAO;AAAA,IACH,WAAW,OAAO,GAAG,EAAE,WAAW,MAE5B;AACF,YAAM,UAAU,OAAO,MAAM,SAAS;AAAA,QAClC,MAAM,WAAW;AAAA,QACjB,MAAM,WAAW;AAAA,QACjB,SAAS,EAAE,WAAW,OAAO;AAAA,MACjC,CAAC;AACD,aAAO;AAAA,QACH,YAAY,OAAO,MAAM,MAAM;AAAA,QAC/B,QAAQ;AAAA,MACZ;AAAA,IACJ;AAAA,IACA,OAAO,OAAO,GAAG,EAAE,GAAG,MAAM;AACxB,aAAO,OAAO,MAAM,UAAU,EAAE,OAAO,EAAE,IAAI,OAAO,EAAE,EAAE,EAAE,CAAC;AAAA,IAC/D;AAAA,EACJ;AAAA,EACA,UAAU;AAAA,IACN,aAAa,OAAO,GAAG,EAAE,GAAG,MAAM;AAC9B,UAAI;AACA,cAAM,SAAS,MAAM,OAAO,MAAM,UAAU,EAAE,OAAO,EAAE,IAAI,OAAO,EAAE,EAAE,EAAE,CAAC;AAEzE,YAAI,CAAC,QAAQ;AACT,iBAAO;AAAA,QACX;AAEA,cAAM,YAAY,KAAK,QAAQ,MAAM,UAAU,OAAO,IAAI,QAAQ,mBAAmB,EAAE,CAAC;AACxF,YAAI,GAAG,WAAW,SAAS,GAAG;AAC1B,aAAG,WAAW,SAAS;AAAA,QAC3B;AAEA,cAAM,OAAO,MAAM,OAAO,EAAE,OAAO,EAAE,IAAI,OAAO,EAAE,EAAE,EAAE,CAAC;AAEvD,eAAO;AAAA,MACX,SAAS,OAAO;AACZ,gBAAQ,IAAI,KAAK;AACjB,eAAO;AAAA,MACX;AAAA,IACJ;AAAA,EACJ;AAAA,EACA,OAAO;AAAA,IACH,gBAAgB,OAAO,UAAiB;AACpC,aAAO,OAAO,KAAK,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,MAAM,IAAI,EAAE,EAAE,CAAC;AAAA,IAC5E;AAAA,EACJ;AACJ;","names":[]}
@@ -0,0 +1,30 @@
1
+ import { makeExecutableSchema } from "@graphql-tools/schema";
2
+ import { noteResolvers, noteTypeDefs } from "./note/index.js";
3
+ import { imageResolvers, imageTypeDefs } from "./image/index.js";
4
+ import { tagResolvers, tagTypeDefs } from "./tag/index.js";
5
+ import { placeholderResolvers, placeholderTypeDefs } from "./placeholder/index.js";
6
+ import { cacheResolvers, cacheTypeDefs } from "./cache/index.js";
7
+ import { reminderResolvers, reminderTypeDefs } from "./reminder/index.js";
8
+ const schema = makeExecutableSchema({
9
+ typeDefs: [
10
+ cacheTypeDefs,
11
+ noteTypeDefs,
12
+ imageTypeDefs,
13
+ tagTypeDefs,
14
+ placeholderTypeDefs,
15
+ reminderTypeDefs
16
+ ],
17
+ resolvers: [
18
+ cacheResolvers,
19
+ noteResolvers,
20
+ imageResolvers,
21
+ tagResolvers,
22
+ placeholderResolvers,
23
+ reminderResolvers
24
+ ]
25
+ });
26
+ var schema_default = schema;
27
+ export {
28
+ schema_default as default
29
+ };
30
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/schema/index.ts"],"sourcesContent":["import { makeExecutableSchema } from '@graphql-tools/schema';\nimport { noteResolvers, noteTypeDefs } from './note/index.js';\nimport { imageResolvers, imageTypeDefs } from './image/index.js';\nimport { tagResolvers, tagTypeDefs } from './tag/index.js';\nimport { placeholderResolvers, placeholderTypeDefs } from './placeholder/index.js';\nimport { cacheResolvers, cacheTypeDefs } from './cache/index.js';\nimport { reminderResolvers, reminderTypeDefs } from './reminder/index.js';\n\nconst schema = makeExecutableSchema({\n typeDefs: [\n cacheTypeDefs,\n noteTypeDefs,\n imageTypeDefs,\n tagTypeDefs,\n placeholderTypeDefs,\n reminderTypeDefs\n ],\n resolvers: [\n cacheResolvers,\n noteResolvers,\n imageResolvers,\n tagResolvers,\n placeholderResolvers,\n reminderResolvers\n ]\n});\n\nexport default schema;\n"],"mappings":"AAAA,SAAS,4BAA4B;AACrC,SAAS,eAAe,oBAAoB;AAC5C,SAAS,gBAAgB,qBAAqB;AAC9C,SAAS,cAAc,mBAAmB;AAC1C,SAAS,sBAAsB,2BAA2B;AAC1D,SAAS,gBAAgB,qBAAqB;AAC9C,SAAS,mBAAmB,wBAAwB;AAEpD,MAAM,SAAS,qBAAqB;AAAA,EAChC,UAAU;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AAAA,EACA,WAAW;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AACJ,CAAC;AAED,IAAO,iBAAQ;","names":[]}