@opengis/fcore 0.0.1-beta.18 → 0.0.1-beta.19

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 (105) hide show
  1. package/dist/config.js +1 -1
  2. package/dist/context.js +1 -1
  3. package/dist/errors.js +1 -1
  4. package/dist/fastify.js +1 -1
  5. package/dist/fcore.js +1 -1
  6. package/dist/migrations/cli.js +1 -1
  7. package/dist/migrations/runner.js +1 -1
  8. package/dist/modules/auth/adduser-cli.js +1 -1
  9. package/dist/modules/auth/passwd-cli.js +1 -1
  10. package/dist/modules/auth/permission-cli.js +1 -1
  11. package/dist/modules/auth/route.js +1 -1
  12. package/dist/modules/auth/schema.js +1 -1
  13. package/dist/modules/auth/services/change-password.js +1 -1
  14. package/dist/modules/auth/services/get-current-user.js +1 -1
  15. package/dist/modules/auth/services/registration.js +1 -1
  16. package/dist/modules/auth/services/verify-two-factor.js +1 -1
  17. package/dist/modules/file/mime.js +1 -1
  18. package/dist/modules/file/route.js +1 -1
  19. package/dist/modules/file/schema.js +1 -1
  20. package/dist/modules/file/services/get-file.js +1 -1
  21. package/dist/modules/file/services/resize-file.js +1 -1
  22. package/dist/modules/file/services/upload-file.js +1 -1
  23. package/dist/modules/resource/route.js +1 -1
  24. package/dist/modules/resource/schema.js +1 -1
  25. package/dist/modules/resource/services/add-note.js +1 -1
  26. package/dist/modules/resource/services/add-resource-file.js +1 -1
  27. package/dist/modules/resource/services/create-resource-relation.js +1 -1
  28. package/dist/modules/resource/services/create-resource.js +1 -1
  29. package/dist/modules/resource/services/delete-resource-relation.js +1 -1
  30. package/dist/modules/resource/services/delete-resource.js +1 -1
  31. package/dist/modules/resource/services/export-resource.js +1 -1
  32. package/dist/modules/resource/services/get-resource.js +1 -1
  33. package/dist/modules/resource/services/list-resource-relation.js +1 -1
  34. package/dist/modules/resource/services/list-resources.js +1 -1
  35. package/dist/modules/resource/services/search-resource.js +1 -1
  36. package/dist/modules/resource/services/suggest-resource.js +1 -1
  37. package/dist/modules/resource/services/update-resource-relation.js +1 -1
  38. package/dist/modules/resource/services/update-resource.js +1 -1
  39. package/dist/modules/resource/services/upload-resource-file.js +1 -1
  40. package/dist/modules/system/route.js +1 -1
  41. package/dist/modules/system/schema.d.ts +3 -2
  42. package/dist/modules/system/schema.d.ts.map +1 -1
  43. package/dist/modules/system/schema.js +1 -1
  44. package/dist/modules/system/services/check-system.js +1 -1
  45. package/dist/modules/system/services/get-access.d.ts +1 -0
  46. package/dist/modules/system/services/get-access.d.ts.map +1 -1
  47. package/dist/modules/system/services/get-access.js +1 -1
  48. package/dist/modules/system/services/get-api-list.js +1 -1
  49. package/dist/modules/system/services/get-audit-log.js +1 -1
  50. package/dist/modules/system/services/get-dictionary.js +1 -1
  51. package/dist/modules/system/services/get-system-log.js +1 -1
  52. package/dist/modules/system/services/get-system-settings.js +1 -1
  53. package/dist/modules/system/services/list-dictionaries.js +1 -1
  54. package/dist/modules/system/services/set-access.d.ts +2 -1
  55. package/dist/modules/system/services/set-access.d.ts.map +1 -1
  56. package/dist/modules/system/services/set-access.js +1 -1
  57. package/dist/modules/system/services/update-dictionary.js +1 -1
  58. package/dist/modules/system/services/update-system-settings.js +1 -1
  59. package/dist/modules/utils/require-admin.js +1 -1
  60. package/dist/modules/utils/safe-user.js +1 -1
  61. package/dist/modules/utils/unsupported.js +1 -1
  62. package/dist/plugins/audit/audit.js +1 -1
  63. package/dist/plugins/audit/audit.types.d.ts +1 -1
  64. package/dist/plugins/audit/audit.types.d.ts.map +1 -1
  65. package/dist/plugins/audit/services/write-audit.js +1 -1
  66. package/dist/plugins/auth/get-user-permissions.js +1 -1
  67. package/dist/plugins/auth/index.js +1 -1
  68. package/dist/plugins/auth/verifyUser.js +1 -1
  69. package/dist/plugins/dictionary.js +1 -1
  70. package/dist/plugins/file.js +1 -1
  71. package/dist/plugins/jwt.js +1 -1
  72. package/dist/plugins/logger/index.js +1 -1
  73. package/dist/plugins/logger/transport.js +1 -1
  74. package/dist/plugins/pg.js +1 -1
  75. package/dist/plugins/redis.js +1 -1
  76. package/dist/plugins/resource/resource.js +1 -1
  77. package/dist/plugins/resource/resource.registry.js +1 -1
  78. package/dist/plugins/resource/resource.types.d.ts +3 -1
  79. package/dist/plugins/resource/resource.types.d.ts.map +1 -1
  80. package/dist/plugins/resource/services/add-dictionary-lookup-data.js +1 -1
  81. package/dist/plugins/resource/services/add-file-token.js +1 -1
  82. package/dist/plugins/resource/services/add-table-lookup-data.js +1 -1
  83. package/dist/plugins/resource/services/create-relation.js +1 -1
  84. package/dist/plugins/resource/services/create.js +1 -1
  85. package/dist/plugins/resource/services/delete-relation.js +1 -1
  86. package/dist/plugins/resource/services/delete.d.ts.map +1 -1
  87. package/dist/plugins/resource/services/delete.js +1 -1
  88. package/dist/plugins/resource/services/find-one.d.ts.map +1 -1
  89. package/dist/plugins/resource/services/find-one.js +1 -1
  90. package/dist/plugins/resource/services/find-relation.d.ts.map +1 -1
  91. package/dist/plugins/resource/services/find-relation.js +1 -1
  92. package/dist/plugins/resource/services/find.d.ts.map +1 -1
  93. package/dist/plugins/resource/services/find.js +1 -1
  94. package/dist/plugins/resource/services/update-relation.js +1 -1
  95. package/dist/plugins/resource/services/update.d.ts.map +1 -1
  96. package/dist/plugins/resource/services/update.js +1 -1
  97. package/dist/plugins/resource/utils/auto-index.js +1 -1
  98. package/dist/plugins/resource/utils/fields.js +1 -1
  99. package/dist/plugins/resource/utils/filters.js +1 -1
  100. package/dist/plugins/resource/utils/permissions.js +1 -1
  101. package/dist/plugins/resource/utils/sort.js +1 -1
  102. package/dist/plugins/resource/utils/sql.js +1 -1
  103. package/dist/shared/getIP.js +1 -1
  104. package/migrations/20260905120000_add_user_foreign_keys.sql +42 -42
  105. package/package.json +93 -93
package/dist/config.js CHANGED
@@ -1 +1 @@
1
- import'dotenv/config';const DEFAULT_LOG_RESPONSE_STATUS_CODES=[0x193,0x199,0x19d,0x19f,0x1ad];function D(){const s=['true','false','cwd','localhost','x5y30KBsEKCENT04tu6549Vxx3No1ztJ2q2K8r79S59420RaZ5','none','logger','redis','auth'];D=function(){return s;};return D();}function required(d){const X=process.env[d];if(!X)throw new Error('Missing\x20environment\x20variable:\x20'+d);return X;}function p(d,X){d=d-0xfa;const F=D();let a=F[d];return a;}export function loadConfig(d={}){const a=p,X={'env':process.env.NODE_ENV??'development','debug':process.env.DEBUG===a(0xfa),'port':Number(process.env.PORT??0xbb8),'maxFileSize':+(process.env.MAX_FILE_SIZE||0x200),'rateLimit':{'disabled':process.env.RATE_LIMIT===a(0xfb),'max':+(process.env.RATE_LIMIT_MAX||0x64),'timeWindow':+(process.env.RATE_LIMIT_TIME_WINDOW||0xea60)},'storagePath':process.env.STORAGE_PATH??'./storage','redactionList':(process.env.REDACTION_LIST||'password')['split'](','),'logger':{'level':process.env.LOG_LEVEL??'info','responses':process.env.LOG_RESPONSES==='true'?!![]:![],'responseCodes':process.env.LOG_RESPONSE_STATUS_CODES?process.env.LOG_RESPONSE_STATUS_CODES['split'](',')['map'](F=>F-0x0):DEFAULT_LOG_RESPONSE_STATUS_CODES,'directory':process.env.LOG_DIRECTORY||process[a(0xfc)]()+'/log'},'pg':{'host':process.env.PG_HOST??a(0xfd),'port':Number(process.env.PG_PORT??0x1538),'database':process.env.PG_DATABASE??'','user':process.env.PG_USER??'','password':process.env.PG_PASSWORD??''},'redis':{'host':process.env.REDIS_HOST??'','port':Number(process.env.REDIS_PORT??0x18eb),'password':process.env.REDIS_PASSWORD,'lazyConnect':!![],'db':process.env.REDIS_DB?Number(process.env.REDIS_DB):undefined},'s3':{'endpoint':process.env.S3_ENDPOINT,'region':process.env.S3_REGION??'us-east-1','bucket':process.env.S3_BUCKET??'','accessKey':process.env.S3_ACCESS_KEY,'secretKey':process.env.S3_SECRET_KEY,'folder':process.env.S3_FOLDER,'forcePathStyle':process.env.S3_FORCE_PATH_STYLE!=='false','tokenSecret':process.env.FILE_TOKEN_SECRET,'tokenTtl':Number(process.env.FILE_TOKEN_TTL??0xe10)},'auth':{'accessToken':process.env.AUTH_ACCESS_TOKEN||'Ch7QR4e73Jg0wx0xOjm','user':process.env.AUTH_USER?JSON['parse'](process.env.AUTH_USER):undefined,'sessionTimeout':+(process.env.AUTH_SESSION_TIMEOUT||0x258),'secret':process.env.AUTH_SECRET??a(0xfe),'cookieName':process.env.AUTH_COOKIE_NAME??'session_user_auth','jwtSecret':process.env.AUTH_JWT_SECRET??'0ua4b1Tz21m47z13U3EO0uN9e0WE7hqRFbcZ72cbdWqZBzemf9cAU865xan1s81TdNpUKKfF','redirect':process.env.AUTH_REDIRECT??'/','twoFactorRedirect':process.env.AUTH_TWOFACTOR_REDIRECT??'/','cookieOptions':process.env.AUTH_COOKIE_OPTIONS_DOMAIN?{'domain':process.env.AUTH_COOKIE_OPTIONS_DOMAIN,'path':process.env.AUTH_COOKIE_OPTIONS_PATH||'/','httpOnly':Boolean(process.env.AUTH_COOKIE_OPTIONS_HTTP_ONLY||'true'),'secure':Boolean(process.env.AUTH_COOKIE_OPTIONS_SECURE||a(0xfa)),'sameSite':process.env.AUTH_COOKIE_OPTIONS_SAME_SITE&&['lax','strict',a(0xff)]['includes'](process.env.AUTH_COOKIE_OPTIONS_SAME_SITE)?process.env.AUTH_COOKIE_OPTIONS_SAME_SITE:Boolean(process.env.AUTH_COOKIE_OPTIONS_SAME_SITE||'true')}:{'path':'/','httpOnly':!![],'secure':![],'sameSite':!![]}}};return{...X,...d,'logger':{...X['logger'],...d[a(0x100)]},'pg':{...X['pg'],...d['pg']},'redis':{...X['redis'],...d[a(0x101)]},'s3':{...X['s3'],...d['s3']},'auth':{...X[a(0x102)],...d['auth']}};}export{required as requireEnv};
1
+ import'dotenv/config';const DEFAULT_LOG_RESPONSE_STATUS_CODES=[0x193,0x199,0x19d,0x19f,0x1ad];function required(L){const t=O,E=process.env[L];if(!E)throw new Error(t(0x77)+L);return E;}function Z(){const B=['Missing\x20environment\x20variable:\x20','split','false','parse','strict','none','auth'];Z=function(){return B;};return Z();}function O(L,E){L=L-0x77;const c=Z();let t=c[L];return t;}export function loadConfig(L={}){const e=O,E={'env':process.env.NODE_ENV??'development','debug':process.env.DEBUG==='true','port':Number(process.env.PORT??0xbb8),'maxFileSize':+(process.env.MAX_FILE_SIZE||0x200),'rateLimit':{'disabled':process.env.RATE_LIMIT==='false','max':+(process.env.RATE_LIMIT_MAX||0x64),'timeWindow':+(process.env.RATE_LIMIT_TIME_WINDOW||0xea60)},'storagePath':process.env.STORAGE_PATH??'./storage','redactionList':(process.env.REDACTION_LIST||'password')[e(0x78)](','),'logger':{'level':process.env.LOG_LEVEL??'info','responses':process.env.LOG_RESPONSES==='true'?!![]:![],'responseCodes':process.env.LOG_RESPONSE_STATUS_CODES?process.env.LOG_RESPONSE_STATUS_CODES['split'](',')['map'](c=>c-0x0):DEFAULT_LOG_RESPONSE_STATUS_CODES,'directory':process.env.LOG_DIRECTORY||process['cwd']()+'/log'},'pg':{'host':process.env.PG_HOST??'localhost','port':Number(process.env.PG_PORT??0x1538),'database':process.env.PG_DATABASE??'','user':process.env.PG_USER??'','password':process.env.PG_PASSWORD??''},'redis':{'host':process.env.REDIS_HOST??'','port':Number(process.env.REDIS_PORT??0x18eb),'password':process.env.REDIS_PASSWORD,'lazyConnect':!![],'db':process.env.REDIS_DB?Number(process.env.REDIS_DB):undefined},'s3':{'endpoint':process.env.S3_ENDPOINT,'region':process.env.S3_REGION??'us-east-1','bucket':process.env.S3_BUCKET??'','accessKey':process.env.S3_ACCESS_KEY,'secretKey':process.env.S3_SECRET_KEY,'folder':process.env.S3_FOLDER,'forcePathStyle':process.env.S3_FORCE_PATH_STYLE!==e(0x79),'tokenSecret':process.env.FILE_TOKEN_SECRET,'tokenTtl':Number(process.env.FILE_TOKEN_TTL??0xe10)},'auth':{'accessToken':process.env.AUTH_ACCESS_TOKEN||'Ch7QR4e73Jg0wx0xOjm','user':process.env.AUTH_USER?JSON[e(0x7a)](process.env.AUTH_USER):undefined,'sessionTimeout':+(process.env.AUTH_SESSION_TIMEOUT||0x258),'secret':process.env.AUTH_SECRET??'x5y30KBsEKCENT04tu6549Vxx3No1ztJ2q2K8r79S59420RaZ5','cookieName':process.env.AUTH_COOKIE_NAME??'session_user_auth','jwtSecret':process.env.AUTH_JWT_SECRET??'0ua4b1Tz21m47z13U3EO0uN9e0WE7hqRFbcZ72cbdWqZBzemf9cAU865xan1s81TdNpUKKfF','redirect':process.env.AUTH_REDIRECT??'/','twoFactorRedirect':process.env.AUTH_TWOFACTOR_REDIRECT??'/','cookieOptions':process.env.AUTH_COOKIE_OPTIONS_DOMAIN?{'domain':process.env.AUTH_COOKIE_OPTIONS_DOMAIN,'path':process.env.AUTH_COOKIE_OPTIONS_PATH||'/','httpOnly':Boolean(process.env.AUTH_COOKIE_OPTIONS_HTTP_ONLY||'true'),'secure':Boolean(process.env.AUTH_COOKIE_OPTIONS_SECURE||'true'),'sameSite':process.env.AUTH_COOKIE_OPTIONS_SAME_SITE&&['lax',e(0x7b),e(0x7c)]['includes'](process.env.AUTH_COOKIE_OPTIONS_SAME_SITE)?process.env.AUTH_COOKIE_OPTIONS_SAME_SITE:Boolean(process.env.AUTH_COOKIE_OPTIONS_SAME_SITE||'true')}:{'path':'/','httpOnly':!![],'secure':![],'sameSite':!![]}}};return{...E,...L,'logger':{...E['logger'],...L['logger']},'pg':{...E['pg'],...L['pg']},'redis':{...E['redis'],...L['redis']},'s3':{...E['s3'],...L['s3']},'auth':{...E[e(0x7d)],...L['auth']}};}export{required as requireEnv};
package/dist/context.js CHANGED
@@ -1 +1 @@
1
- let defaultContext;export function setContext(d){defaultContext=d;}export function getContext(){if(!defaultContext)throw new Error('Application\x20context\x20is\x20not\x20initialized');return defaultContext;}function p(d,X){d=d-0x98;const F=D();let a=F[d];return a;}export function createContext(d){return{...d,async 'close'(){const X=p;await Promise[X(0x98)]([d['redis']?.[X(0x99)](),d['pg']?.[X(0x9a)]()]),await d['logger']['close']();}};}function D(){const F=['allSettled','close','end'];D=function(){return F;};return D();}
1
+ let defaultContext;export function setContext(L){defaultContext=L;}function Z(){const t=['Application\x20context\x20is\x20not\x20initialized','redis','end'];Z=function(){return t;};return Z();}export function getContext(){const E=O;if(!defaultContext)throw new Error(E(0x145));return defaultContext;}function O(L,E){L=L-0x145;const c=Z();let t=c[L];return t;}export function createContext(L){return{...L,async 'close'(){const c=O;await Promise['allSettled']([L[c(0x146)]?.['close'](),L['pg']?.[c(0x147)]()]),await L['logger']['close']();}};}
package/dist/errors.js CHANGED
@@ -1 +1 @@
1
- var s=p;export class FCoreError extends Error{[s(0x125)];['statusCode'];[s(0x126)];constructor(d,X,F=0x1f4,a){var y=s;super(X),this['code']=d,this[y(0x127)]=F,this[y(0x126)]=a,this[y(0x128)]=new.target.name;}}export class BadRequestError extends FCoreError{constructor(d,X){var k=s;super(k(0x129),d,0x190,X);}}export class UnauthorizedError extends FCoreError{constructor(d='Authentication\x20required'){super('UNAUTHORIZED',d,0x191);}}export class ForbiddenError extends FCoreError{constructor(d='Access\x20denied'){super('FORBIDDEN',d,0x193);}}export class NotFoundError extends FCoreError{constructor(d='Not\x20found'){var q=s;super(q(0x12a),d,0x194);}}export class ConflictError extends FCoreError{constructor(d=s(0x12b)){super('CONFLICT',d,0x199);}}export class ValidationError extends FCoreError{constructor(d,X){var f=s;super(f(0x12c),d,0x1a6,X);}}export class UnsupportedError extends FCoreError{constructor(d='Operation\x20is\x20not\x20configured'){super('UNSUPPORTED',d,0x1f5);}}function p(d,X){d=d-0x125;var F=D();var a=F[d];return a;}function D(){var G=['code','details','statusCode','name','BAD_REQUEST_ERROR','NOT_FOUND','Conflict','VALIDATION_ERROR'];D=function(){return G;};return D();}
1
+ var e=O;function Z(){var X=['details','statusCode','BAD_REQUEST_ERROR','Authentication\x20required','NOT_FOUND'];Z=function(){return X;};return Z();}export class FCoreError extends Error{['code'];['statusCode'];[e(0xdc)];constructor(L,E,c=0x1f4,t){var B=e;super(E),this['code']=L,this[B(0xdd)]=c,this['details']=t,this['name']=new.target.name;}}export class BadRequestError extends FCoreError{constructor(L,E){var g=e;super(g(0xde),L,0x190,E);}}export class UnauthorizedError extends FCoreError{constructor(L=e(0xdf)){super('UNAUTHORIZED',L,0x191);}}function O(L,E){L=L-0xdc;var c=Z();var t=c[L];return t;}export class ForbiddenError extends FCoreError{constructor(L='Access\x20denied'){super('FORBIDDEN',L,0x193);}}export class NotFoundError extends FCoreError{constructor(L='Not\x20found'){var r=e;super(r(0xe0),L,0x194);}}export class ConflictError extends FCoreError{constructor(L='Conflict'){super('CONFLICT',L,0x199);}}export class ValidationError extends FCoreError{constructor(L,E){super('VALIDATION_ERROR',L,0x1a6,E);}}export class UnsupportedError extends FCoreError{constructor(L='Operation\x20is\x20not\x20configured'){super('UNSUPPORTED',L,0x1f5);}}
package/dist/fastify.js CHANGED
@@ -1 +1 @@
1
- function D(){const V=['toString','reduce','addHook','isArray','fcore','summary','url','raw','headers','Bearer\x20','win32','config','auth','length','access','permissions','Missing\x20permission:\x20','maxFileSize','statusCode','code','send','logger','register','disabled','max','rateLimit','timeWindow','user'];D=function(){return V;};return D();}import d from'fastify-plugin';function p(d,X){d=d-0x1b0;const F=D();let a=F[d];return a;}import{FCoreError}from'./errors.js';import{authRoutes}from'./modules/auth/route.js';import{fileRoutes}from'./modules/file/route.js';import{resourceRoutes}from'./modules/resource/route.js';import{systemRoutes}from'./modules/system/route.js';import{createSessionStore}from'./plugins/auth/index.js';import{ForbiddenError}from'./errors.js';import{jwtVerifyToken}from'./plugins/jwt.js';function urlencodedContentParser(X,F,a){const W=p,s=decodeURIComponent(F[W(0x1b0)]())['split']('&')[W(0x1b1)]((y,k)=>{const [q,f]=k['split']('=');return{...y,[q]:f};},{});a(null,s);}export default function fcoreFastify(X,F){return d(async a=>{const P=p;a['decorate']('ctx',X);const {config:s}=X,y=new Map();a[P(0x1b2)]('onRoute',q=>{const v=P,f=q['schema'],G=Array[v(0x1b3)](q['method'])?q['method']:[q['method']];for(const b of G){if(b==='HEAD')continue;const H={'method':b,'endpoint':q['url'],'package':f?.['package']??v(0x1b4),'tags':f?.['tags']??[],'summary':f?.[v(0x1b5)]??'','description':f?.['description']??'','access':f?.['access']??'public','permissions':f?.['permissions']??[]};y['set'](b+'\x20'+q[v(0x1b6)],H);}}),a['addHook']('preHandler',async q=>{const J=P;if(q['routeOptions'][J(0x1b6)]==='*')return!![];const f=y['get'](q['method']+'\x20'+q['routeOptions']['url']),G=q[J(0x1b7)][J(0x1b8)]?.['authorization'],b=G?.['startsWith'](J(0x1b9))?G['slice'](0x7):null,H=q['user']??(b?await jwtVerifyToken(b):null);!q['user']&&b&&process.env.AUTH_JWT_SECRET&&(q['user']=await jwtVerifyToken(b));!q['user']&&process['platform']===J(0x1ba)&&X[J(0x1bb)]?.[J(0x1bc)]?.['user']&&(q['user']=X[J(0x1bb)][J(0x1bc)]['user']);if(!f?.['access'])throw new Error('Route\x20access\x20not\x20defined');if(f['access']==='public')return!![];if(!H)throw new ForbiddenError('User\x20required');if(f['access']==='user'&&!f['permissions']?.[J(0x1bd)])return!![];if(H['type']=='admin')return!![];if(f[J(0x1be)]==='admin')throw new ForbiddenError('Admin\x20access\x20required');for(const T of f[J(0x1bf)]){if(!H['permissions']?.['includes'](T))throw new ForbiddenError(J(0x1c0)+T);}return!![];}),await createSessionStore(a,X),await a['register'](import('@fastify/multipart'),{'limits':{'fileSize':s[P(0x1c1)]*0x400*0x400}}),a['setErrorHandler']((q,f,G)=>{const R=P;if(q instanceof FCoreError||q['code']==='FST_ERR_VALIDATION'||q[R(0x1c2)]<0x1f4)return q[R(0x1c2)]<0x1f4&&X['logger']['warn'](q),G[R(0x1c3)](q[R(0x1c2)])[R(0x1c4)]({'error':q['code'],'message':q['message'],'details':q['details']});return X[R(0x1c5)]['error'](q),(s['debug']||process.env.NODE_ENV==='test'||process.env.VITEST)&&console['error'](q),G['code'](0x1f4)[R(0x1c4)]({'error':'INTERNAL_ERROR','message':'Internal\x20server\x20error'});});const k=q=>!F||F['includes'](q);if(k('auth'))await a['register'](authRoutes(X));if(k('resource'))await a['register'](resourceRoutes(X));if(k('file'))await a['register'](fileRoutes(X));if(k('system'))await a[P(0x1c6)](systemRoutes(X,y));a['addContentTypeParser']('application/x-www-form-urlencoded',{'parseAs':'buffer'},urlencodedContentParser),!s['rateLimit']?.[P(0x1c7)]?a['register'](import('@fastify/rate-limit'),{'max':s['rateLimit']?.[P(0x1c8)]||0x64,'timeWindow':s[P(0x1c9)]?.[P(0x1ca)]||0xea60,'hook':'preHandler','global':!![],'keyGenerator':q=>(q[P(0x1cb)]?.['id']||q['ip'])+'-'+q['raw']['url']['split']('?')[0x0]}):console['log']('⚠️\x20rate\x20limit\x20is\x20disabled');});}
1
+ import L from'fastify-plugin';import{FCoreError}from'./errors.js';function Z(){const q=['reduce','ctx','method','fcore','public','set','url','addHook','routeOptions','raw','headers','authorization','Bearer\x20','user','auth','access','length','admin','permissions','includes','@fastify/multipart','FST_ERR_VALIDATION','logger','send','code','details','error','debug','test','register','resource','file','rateLimit','disabled','@fastify/rate-limit'];Z=function(){return q;};return Z();}import{authRoutes}from'./modules/auth/route.js';import{fileRoutes}from'./modules/file/route.js';import{resourceRoutes}from'./modules/resource/route.js';import{systemRoutes}from'./modules/system/route.js';import{createSessionStore}from'./plugins/auth/index.js';function O(L,E){L=L-0x106;const c=Z();let t=c[L];return t;}import{ForbiddenError}from'./errors.js';import{jwtVerifyToken}from'./plugins/jwt.js';function urlencodedContentParser(E,c,t){const f=O,e=decodeURIComponent(c['toString']())['split']('&')[f(0x106)]((B,g)=>{const [r,X]=g['split']('=');return{...B,[r]:X};},{});t(null,e);}export default function fcoreFastify(E,c){return L(async t=>{const A=O;t['decorate'](A(0x107),E);const {config:e}=E,B=new Map();t['addHook']('onRoute',r=>{const G=A,X=r['schema'],j=Array['isArray'](r['method'])?r[G(0x108)]:[r[G(0x108)]];for(const F of j){if(F==='HEAD')continue;const I={'method':F,'endpoint':r['url'],'package':X?.['package']??G(0x109),'tags':X?.['tags']??[],'summary':X?.['summary']??'','description':X?.['description']??'','access':X?.['access']??G(0x10a),'permissions':X?.['permissions']??[]};B[G(0x10b)](F+'\x20'+r[G(0x10c)],I);}}),t[A(0x10d)]('preHandler',async r=>{const x=A;if(r['routeOptions']['url']==='*')return!![];const X=B['get'](r['method']+'\x20'+r[x(0x10e)][x(0x10c)]),j=r[x(0x10f)][x(0x110)]?.[x(0x111)],F=j?.['startsWith'](x(0x112))?j['slice'](0x7):null,I=r[x(0x113)]??(F?await jwtVerifyToken(F):null);!r[x(0x113)]&&F&&process.env.AUTH_JWT_SECRET&&(r['user']=await jwtVerifyToken(F));!r['user']&&process['platform']==='win32'&&E['config']?.[x(0x114)]?.['user']&&(r[x(0x113)]=E['config']['auth']['user']);if(!X?.['access'])throw new Error('Route\x20access\x20not\x20defined');if(X[x(0x115)]==='public')return!![];if(!I)throw new ForbiddenError('User\x20required');if(X['access']==='user'&&!X['permissions']?.[x(0x116)])return!![];if(I['type']==x(0x117))return!![];if(X['access']==='admin')throw new ForbiddenError('Admin\x20access\x20required');for(const T of X[x(0x118)]){if(!I['permissions']?.[x(0x119)](T))throw new ForbiddenError('Missing\x20permission:\x20'+T);}return!![];}),await createSessionStore(t,E),await t['register'](import(A(0x11a)),{'limits':{'fileSize':e['maxFileSize']*0x400*0x400}}),t['setErrorHandler']((r,X,j)=>{const W=A;if(r instanceof FCoreError||r['code']===W(0x11b)||r['statusCode']<0x1f4)return r['statusCode']<0x1f4&&E[W(0x11c)]['warn'](r),j['code'](r['statusCode'])[W(0x11d)]({'error':r[W(0x11e)],'message':r['message'],'details':r[W(0x11f)]});return E['logger'][W(0x120)](r),(e[W(0x121)]||process.env.NODE_ENV===W(0x122)||process.env.VITEST)&&console[W(0x120)](r),j['code'](0x1f4)['send']({'error':'INTERNAL_ERROR','message':'Internal\x20server\x20error'});});const g=r=>!c||c[A(0x119)](r);if(g('auth'))await t[A(0x123)](authRoutes(E));if(g(A(0x124)))await t['register'](resourceRoutes(E));if(g(A(0x125)))await t[A(0x123)](fileRoutes(E));if(g('system'))await t['register'](systemRoutes(E,B));t['addContentTypeParser']('application/x-www-form-urlencoded',{'parseAs':'buffer'},urlencodedContentParser),!e[A(0x126)]?.[A(0x127)]?t['register'](import(A(0x128)),{'max':e[A(0x126)]?.['max']||0x64,'timeWindow':e[A(0x126)]?.['timeWindow']||0xea60,'hook':'preHandler','global':!![],'keyGenerator':r=>(r['user']?.['id']||r['ip'])+'-'+r[A(0x10f)][A(0x10c)]['split']('?')[0x0]}):console['log']('⚠️\x20rate\x20limit\x20is\x20disabled');});}
package/dist/fcore.js CHANGED
@@ -1 +1 @@
1
- import{loadConfig}from'./config.js';import{createContext,setContext}from'./context.js';import{createAudit,createDatabase,createDictionary,createFileS3,createLogger,createRedis,createResource}from'./plugins/index.js';function p(d,X){d=d-0x122;const F=D();let a=F[d];return a;}export async function createFCore(d={}){const b=p,X=loadConfig(d['config']),F=createRedis(X[b(0x122)]),a=createLogger(),s=createDatabase(X['pg']),y=createFileS3({'endpoint':X['s3']['endpoint'],'region':X['s3']['region'],'bucket':X['s3']['bucket'],'accessKey':X['s3']['accessKey'],'secretKey':X['s3']['secretKey'],'folder':X['s3']['folder'],'forcePathStyle':X['s3']['forcePathStyle'],'tokenSecret':X['s3']['tokenSecret'],'tokenTtl':X['s3']['tokenTtl']}),k=createAudit({'pg':s,'logger':a}),q=createDictionary({'pg':s,'dictionaries':d[b(0x123)]}),f=createResource({'pg':s,'logger':a,'audit':k,'dictionary':q,'file':y});d[b(0x124)]?.['length']&&f['register'](d[b(0x124)]);const G=createContext({'config':X,'logger':a,'redis':F,'pg':s,'file':y,'resource':f,'audit':k,'dictionary':q});return setContext(G),G;}function D(){const H=['redis','dictionaries','resources'];D=function(){return H;};return D();}
1
+ import{loadConfig}from'./config.js';import{createContext,setContext}from'./context.js';import{createAudit,createDatabase,createDictionary,createFileS3,createLogger,createRedis,createResource}from'./plugins/index.js';function Z(){const I=['redis','endpoint','accessKey'];Z=function(){return I;};return Z();}function O(L,E){L=L-0xfe;const c=Z();let t=c[L];return t;}export async function createFCore(L={}){const F=O,E=loadConfig(L['config']),c=createRedis(E[F(0xfe)]),t=createLogger(),e=createDatabase(E['pg']),B=createFileS3({'endpoint':E['s3'][F(0xff)],'region':E['s3']['region'],'bucket':E['s3']['bucket'],'accessKey':E['s3'][F(0x100)],'secretKey':E['s3']['secretKey'],'folder':E['s3']['folder'],'forcePathStyle':E['s3']['forcePathStyle'],'tokenSecret':E['s3']['tokenSecret'],'tokenTtl':E['s3']['tokenTtl']}),g=createAudit({'pg':e,'logger':t}),r=createDictionary({'pg':e,'dictionaries':L['dictionaries']}),X=createResource({'pg':e,'logger':t,'audit':g,'dictionary':r,'file':B});L['resources']?.['length']&&X['register'](L['resources']);const j=createContext({'config':E,'logger':t,'redis':c,'pg':e,'file':B,'resource':X,'audit':g,'dictionary':r});return setContext(j),j;}
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- function D(){const F=['log','Loaded\x20configuration:','run','OK\x20\x20'];D=function(){return F;};return D();}const X=p;import{runMigrations}from'./runner.js';import{loadConfig}from'../config.js';function p(d,X){d=d-0xc1;const F=D();let a=F[d];return a;}try{const config=loadConfig();console[X(0xc1)](X(0xc2),config['pg']);for(const r of await runMigrations({'database':config['pg']}))console[X(0xc1)]((r['status']===X(0xc3)?X(0xc4):'SKIP')+'\x20'+r['file']);}catch(d){console['error'](d),process['exitCode']=0x1;}
2
+ function Z(){const F=['--dir','--dir\x20requires\x20a\x20folder\x20path','--fcore','slice','****'];Z=function(){return F;};return Z();}const j=O;import{runMigrations}from'./runner.js';import{loadConfig}from'../config.js';import L from'node:path';import{fileURLToPath}from'node:url';function O(L,E){L=L-0x136;const c=Z();let t=c[L];return t;}const packageMigrations=fileURLToPath(new URL('../../migrations',import.meta.url));function migrationDirectory(E){const X=O,c=E['indexOf'](X(0x136));if(c>=0x0){const e=E[c+0x1];if(!e)throw new Error(X(0x137));return L['resolve'](e);}if(E['includes'](X(0x138)))return packageMigrations;const t=E['find'](B=>!B['startsWith']('--'));return L['resolve'](t??'migrations');}try{const config=loadConfig(),dir=migrationDirectory(process['argv'][j(0x139)](0x2));console['log']('Loaded\x20configuration:',{...config['pg'],'user':'****','password':j(0x13a)}),console['log']('Using\x20migration\x20directory:',dir,process['argv']['slice'](0x2));for(const r of await runMigrations({'database':config['pg'],'dir':dir}))console['log']((r['status']==='run'?'OK\x20\x20':'SKIP')+'\x20'+r['file']);}catch(g){console['error'](g),process['exitCode']=0x1;}
@@ -1 +1 @@
1
- import d from'node:fs/promises';function D(){const J=['databaseUrl','empty\x20pg','\x0a\x20\x20\x20\x20\x20\x20CREATE\x20TABLE\x20IF\x20NOT\x20EXISTS\x20schema_migrations\x20(\x0a\x20\x20\x20\x20\x20\x20\x20\x20version\x20varchar(255)\x20PRIMARY\x20KEY,\x0a\x20\x20\x20\x20\x20\x20\x20\x20applied_at\x20timestamptz\x20NOT\x20NULL\x20DEFAULT\x20now()\x0a\x20\x20\x20\x20\x20\x20)\x0a\x20\x20\x20\x20','SELECT\x20version\x20FROM\x20schema_migrations','.sql','has','readFile','connect','query','ROLLBACK','username','password'];D=function(){return J;};return D();}import X from'node:path';function p(d,X){d=d-0x1bd;const F=D();let a=F[d];return a;}import{createDatabase}from'../plugins/pg.js';export async function runMigrations(F={}){const P=p,a=X['resolve'](F['dir']??'migrations'),s=F['database']??databaseFromUrl(F[P(0x1bd)]??process.env.DATABASE_URL);if(!s)throw new Error('DATABASE_URL\x20or\x20database\x20config\x20is\x20required');const y=createDatabase(s);if(!y)throw new Error(P(0x1be));const k=[];try{await y['query'](P(0x1bf));const q=await y['query'](P(0x1c0)),f=new Set(q['rows']['map'](b=>b['version'])),G=(await d['readdir'](a))['filter'](b=>b['endsWith'](P(0x1c1)))['sort']();for(const b of G){if(f[P(0x1c2)](b)){k['push']({'file':b,'status':'skip'});continue;}const H=await d[P(0x1c3)](X['join'](a,b),'utf8'),T=await y[P(0x1c4)]();try{await T[P(0x1c5)]('BEGIN'),await T[P(0x1c5)](H),await T['query']('INSERT\x20INTO\x20schema_migrations(version)\x20VALUES\x20($1)',[b]),await T[P(0x1c5)]('COMMIT');}catch(W){await T['query'](P(0x1c6));throw W;}finally{T['release']();}k['push']({'file':b,'status':'run'});}return k;}finally{await y['end']();}}function databaseFromUrl(F){const v=p;if(!F)return undefined;const a=new URL(F);return{'host':a['hostname'],'port':Number(a['port']||0x1538),'database':a['pathname']['slice'](0x1),'user':decodeURIComponent(a[v(0x1c7)]),'password':decodeURIComponent(a[v(0x1c8)])};}
1
+ import L from'node:fs/promises';function O(L,E){L=L-0x10d;const c=Z();let t=c[L];return t;}import E from'node:path';import{createDatabase}from'../plugins/pg.js';export async function runMigrations(c={}){const A=O,t=E['resolve'](c['dir']??'migrations'),e=c['database']??databaseFromUrl(c['databaseUrl']??process.env.DATABASE_URL);if(!e)throw new Error('DATABASE_URL\x20or\x20database\x20config\x20is\x20required');const B=createDatabase(e);if(!B)throw new Error(A(0x10d));const g=[];try{await B['query'](A(0x10e));const r=await B['query'](A(0x10f)),X=new Set(r[A(0x110)]['map'](F=>F['version'])),j=(await L['readdir'](t))[A(0x111)](F=>F['endsWith']('.sql'))[A(0x112)]();for(const F of j){if(X['has'](F)){g['push']({'file':F,'status':A(0x113)});continue;}const I=await L['readFile'](E['join'](t,F),A(0x114)),T=await B[A(0x115)]();try{await T['query']('BEGIN'),await T['query'](I),await T[A(0x116)]('INSERT\x20INTO\x20schema_migrations(version)\x20VALUES\x20($1)',[F]),await T['query']('COMMIT');}catch(f){await T['query']('ROLLBACK');throw f;}finally{T[A(0x117)]();}g['push']({'file':F,'status':A(0x118)});}return g;}finally{await B['end']();}}function Z(){const x=['empty\x20pg','\x0a\x20\x20\x20\x20\x20\x20CREATE\x20TABLE\x20IF\x20NOT\x20EXISTS\x20schema_migrations\x20(\x0a\x20\x20\x20\x20\x20\x20\x20\x20version\x20varchar(255)\x20PRIMARY\x20KEY,\x0a\x20\x20\x20\x20\x20\x20\x20\x20applied_at\x20timestamptz\x20NOT\x20NULL\x20DEFAULT\x20now()\x0a\x20\x20\x20\x20\x20\x20)\x0a\x20\x20\x20\x20','SELECT\x20version\x20FROM\x20schema_migrations','rows','filter','sort','skip','utf8','connect','query','release','run','hostname'];Z=function(){return x;};return Z();}function databaseFromUrl(c){const G=O;if(!c)return undefined;const t=new URL(c);return{'host':t[G(0x119)],'port':Number(t['port']||0x1538),'database':t['pathname']['slice'](0x1),'user':decodeURIComponent(t['username']),'password':decodeURIComponent(t['password'])};}
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- const F=p;import{loadConfig}from'../../config.js';import{createDatabase}from'../../plugins/pg.js';import d from'./services/registration.js';const [user,password,type]=process['argv'][F(0x1c7)](0x2);function p(d,X){d=d-0x1c7;const F=D();let a=F[d];return a;}function D(){const a=['slice','Registered\x20user\x20','type','error','exitCode'];D=function(){return a;};return D();}if(!user||!password)console['error']('Usage:\x20fcore-registration\x20<login>\x20<password>\x20[type]'),process['exitCode']=0x1;else{const pg=createDatabase(loadConfig()['pg']);try{const {user:data}=await d({'user':user,'password':password,'type':type},{'pg':pg});console['log'](F(0x1c8)+data['id']+'\x20('+data[F(0x1c9)]+')');}catch(X){console[F(0x1ca)](X),process[F(0x1cb)]=0x1;}finally{await pg['end']();}}
2
+ const c=O;function O(L,E){L=L-0x16a;const c=Z();let t=c[L];return t;}import{loadConfig}from'../../config.js';import{createDatabase}from'../../plugins/pg.js';import L from'./services/registration.js';const [user,password,type]=process['argv']['slice'](0x2);function Z(){const t=['log','Registered\x20user\x20','exitCode','end'];Z=function(){return t;};return Z();}if(!user||!password)console['error']('Usage:\x20fcore-registration\x20<login>\x20<password>\x20[type]'),process['exitCode']=0x1;else{const pg=createDatabase(loadConfig()['pg']);try{const {user:data}=await L({'user':user,'password':password,'type':type},{'pg':pg});console[c(0x16a)](c(0x16b)+data['id']+'\x20('+data['type']+')');}catch(E){console['error'](E),process[c(0x16c)]=0x1;}finally{await pg[c(0x16d)]();}}
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- function p(d,X){d=d-0xbc;const F=D();let a=F[d];return a;}const F=p;import{loadConfig}from'../../config.js';import{createDatabase}from'../../plugins/pg.js';import d from'./services/change-password.js';function D(){const a=['query','User\x20not\x20found','end'];D=function(){return a;};return D();}const [login,password]=process['argv']['slice'](0x2);if(!login||!password)console['error']('Usage:\x20fcore-password\x20<login>\x20<password>'),process['exitCode']=0x1;else{const pg=createDatabase(loadConfig()['pg']);try{const result=await pg[F(0xbc)]('SELECT\x20uid\x20AS\x20id\x20FROM\x20admin.users\x20WHERE\x20$1\x20IN\x20(login,\x20email,\x20phone)\x20LIMIT\x201',[login]),user=result['rows'][0x0];if(!user)throw new Error(F(0xbd));await d({'userId':user['id'],'password':password},{'pg':pg}),console['log']('Password\x20changed\x20for\x20'+login);}catch(X){console['error'](X),process['exitCode']=0x1;}finally{await pg[F(0xbe)]();}}
2
+ const c=O;import{loadConfig}from'../../config.js';import{createDatabase}from'../../plugins/pg.js';function Z(){const t=['slice','query','rows'];Z=function(){return t;};return Z();}import L from'./services/change-password.js';const [login,password]=process['argv'][c(0x7d)](0x2);function O(L,E){L=L-0x7d;const c=Z();let t=c[L];return t;}if(!login||!password)console['error']('Usage:\x20fcore-password\x20<login>\x20<password>'),process['exitCode']=0x1;else{const pg=createDatabase(loadConfig()['pg']);try{const result=await pg[c(0x7e)]('SELECT\x20uid\x20AS\x20id\x20FROM\x20admin.users\x20WHERE\x20$1\x20IN\x20(login,\x20email,\x20phone)\x20LIMIT\x201',[login]),user=result[c(0x7f)][0x0];if(!user)throw new Error('User\x20not\x20found');await L({'userId':user['id'],'password':password},{'pg':pg}),console['log']('Password\x20changed\x20for\x20'+login);}catch(E){console['error'](E),process['exitCode']=0x1;}finally{await pg['end']();}}
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- const f=p;import{loadConfig}from'../../config.js';import{createDatabase}from'../../plugins/pg.js';function p(d,X){d=d-0x15a;const F=D();let a=F[d];return a;}const SYSTEM_ACTIONS=['logs',f(0x15a),'list',f(0x15b),'access',f(0x15c),f(0x15d)],RESOURCE_ACTIONS=['read','update','create','delete'],[login,permissionArg]=process['argv']['slice'](0x2);function expandPermissions(d){const G=f,X=d['split'](',')[G(0x15e)](a=>a[G(0x15f)]())[G(0x160)](Boolean),F=new Set();for(const a of X){if(a['includes'](':')){F['add'](a);continue;}const s=a==='system'?SYSTEM_ACTIONS:RESOURCE_ACTIONS;for(const y of s){F['add'](a+':'+y);}}return[...F];}if(!login||!permissionArg)console[f(0x161)]('Usage:\x20fcore-permission\x20<login>\x20<system|resource|resource:action[,...]|clear>'),process['exitCode']=0x1;else{const pg=createDatabase(loadConfig()['pg']);try{const result=await pg['query']('SELECT\x20uid\x20AS\x20id\x20FROM\x20admin.users\x20WHERE\x20$1\x20IN\x20(login,\x20email,\x20phone)\x20LIMIT\x201',[login]),user=result['rows'][0x0];if(!user)throw new Error('User\x20not\x20found');if(permissionArg['trim']()===f(0x162))await pg[f(0x163)]('DELETE\x20FROM\x20admin.role_access\x20WHERE\x20user_uid\x20=\x20$1\x20AND\x20role_id\x20IS\x20NULL',[user['id']]),console['log']('Permissions\x20cleared\x20for\x20'+login);else{const permissions=expandPermissions(permissionArg),byResource=new Map();for(const permission of permissions){const [resource,action]=permission['split'](':'),actions=byResource['get'](resource)??[];actions['push'](action),byResource['set'](resource,actions);}const client=await pg['connect']();try{await client[f(0x163)](f(0x164));for(const [resource,actions]of byResource){const existing=await client['query']('SELECT\x20access_id,\x20actions\x20FROM\x20admin.role_access\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20user_uid\x20=\x20$1\x20AND\x20role_id\x20IS\x20NULL\x20AND\x20resource\x20=\x20$2',[user['id'],resource]),row=existing['rows'][0x0];if(row){const merged=[...new Set([...row['actions']??[],...actions])];await client[f(0x163)]('UPDATE\x20admin.role_access\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20SET\x20actions\x20=\x20$1,\x20updated_by\x20=\x20$2,\x20updated_at\x20=\x20now()\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20access_id\x20=\x20$3',[merged,user['id'],row['access_id']]);}else await client['query'](f(0x165),[resource,actions,user['id'],user['id']]);}await client['query']('COMMIT');}catch(k){await client['query']('ROLLBACK');throw k;}finally{client['release']();}console[f(0x166)]('Granted\x20permissions\x20for\x20'+login+':\x20'+permissions['join'](',\x20'));}}catch(q){console['error'](q),process['exitCode']=0x1;}finally{await pg['end']();}}function D(){const b=['audit','check','settings','dictionaries','map','trim','filter','error','clear','query','BEGIN','INSERT\x20INTO\x20admin.role_access\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20(\x20resource,\x20actions,\x20user_uid,\x20created_by,\x20updated_by)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20VALUES\x20($1,\x20$2,\x20$3,\x20$4,\x20$4)','log'];D=function(){return b;};return D();}
2
+ const X=O;import{loadConfig}from'../../config.js';import{createDatabase}from'../../plugins/pg.js';const SYSTEM_ACTIONS=['logs','audit','list','check','access',X(0xa6),X(0xa7)],RESOURCE_ACTIONS=['read',X(0xa8),'create',X(0xa9)],[login,permissionArg]=process[X(0xaa)]['slice'](0x2);function O(L,E){L=L-0xa6;const c=Z();let t=c[L];return t;}function expandPermissions(L){const j=X,E=L['split'](',')[j(0xab)](t=>t['trim']())[j(0xac)](Boolean),c=new Set();for(const t of E){if(t['includes'](':')){c['add'](t);continue;}const e=t==='system'?SYSTEM_ACTIONS:RESOURCE_ACTIONS;for(const B of e){c[j(0xad)](t+':'+B);}}return[...c];}function Z(){const F=['settings','dictionaries','update','delete','argv','map','filter','add','exitCode','Permissions\x20cleared\x20for\x20','get','connect','UPDATE\x20admin.role_access\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20SET\x20actions\x20=\x20$1,\x20updated_by\x20=\x20$2,\x20updated_at\x20=\x20now()\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20access_id\x20=\x20$3','Granted\x20permissions\x20for\x20','join','error','end'];Z=function(){return F;};return Z();}if(!login||!permissionArg)console['error']('Usage:\x20fcore-permission\x20<login>\x20<system|resource|resource:action[,...]|clear>'),process[X(0xae)]=0x1;else{const pg=createDatabase(loadConfig()['pg']);try{const result=await pg['query']('SELECT\x20uid\x20AS\x20id\x20FROM\x20admin.users\x20WHERE\x20$1\x20IN\x20(login,\x20email,\x20phone)\x20LIMIT\x201',[login]),user=result['rows'][0x0];if(!user)throw new Error('User\x20not\x20found');if(permissionArg['trim']()==='clear')await pg['query']('DELETE\x20FROM\x20admin.role_access\x20WHERE\x20user_uid\x20=\x20$1\x20AND\x20role_id\x20IS\x20NULL',[user['id']]),console['log'](X(0xaf)+login);else{const permissions=expandPermissions(permissionArg),byResource=new Map();for(const permission of permissions){const [resource,action]=permission['split'](':'),actions=byResource[X(0xb0)](resource)??[];actions['push'](action),byResource['set'](resource,actions);}const client=await pg[X(0xb1)]();try{await client['query']('BEGIN');for(const [resource,actions]of byResource){const existing=await client['query']('SELECT\x20access_id,\x20actions\x20FROM\x20admin.role_access\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20user_uid\x20=\x20$1\x20AND\x20role_id\x20IS\x20NULL\x20AND\x20resource\x20=\x20$2',[user['id'],resource]),row=existing['rows'][0x0];if(row){const merged=[...new Set([...row['actions']??[],...actions])];await client['query'](X(0xb2),[merged,user['id'],row['access_id']]);}else await client['query']('INSERT\x20INTO\x20admin.role_access\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20(\x20resource,\x20actions,\x20user_uid,\x20created_by,\x20updated_by)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20VALUES\x20($1,\x20$2,\x20$3,\x20$4,\x20$4)',[resource,actions,user['id'],user['id']]);}await client['query']('COMMIT');}catch(g){await client['query']('ROLLBACK');throw g;}finally{client['release']();}console['log'](X(0xb3)+login+':\x20'+permissions[X(0xb4)](',\x20'));}}catch(r){console[X(0xb5)](r),process['exitCode']=0x1;}finally{await pg[X(0xb6)]();}}
@@ -1 +1 @@
1
- import{getUserPermissions,verifyUser}from'../../plugins/auth/index.js';import d from'./services/get-current-user.js';import X from'./services/registration.js';import F from'./services/change-password.js';import{authSchemas}from'./schema.js';import a from'../../shared/getIP.js';function p(d,X){d=d-0x142;const F=D();let a=F[d];return a;}import{UnauthorizedError}from'../../errors.js';export function authRoutes(s){return async y=>{const P=p,k=async q=>{const W=p,f=q['method']==='GET'?q['query']:q['body'],G=a(q),b=await verifyUser({...f,'ip':G},s);b['permissions']=await getUserPermissions(b['id'],s);const H=b['twofa']?s[W(0x142)]['auth']['twoFactorRedirect']:s[W(0x142)]['auth']['redirect'];await q['login'](b);const T=s['config']['auth']['sessionTimeout']*0x3e8*0x3c;return q['session']?.[W(0x143)]&&(q['session']['cookie']['maxAge']=T),await q['session']['save'](),await s['audit']?.['write']?.({'module':'auth','resource':'session','resourceId':q[W(0x144)][W(0x145)],'action':W(0x146),'userId':b['id'],'ipAddress':G}),{'user':{'id':b['id'],'type':b['type'],'permissions':b['permissions']},'redirectUrl':H};};y['get'](P(0x147),{'schema':{'tags':['fcore','auth'],'summary':'Sign\x20in','description':'Authenticates\x20a\x20user\x20and\x20returns\x20a\x20bearer\x20access\x20token.','access':'public','permissions':[],'querystring':authSchemas['credentials']}},k),y[P(0x148)]('/api/auth/login',{'schema':{'tags':['fcore','auth'],'summary':'Sign\x20in','description':'Authenticates\x20a\x20user\x20and\x20returns\x20a\x20bearer\x20access\x20token.','access':'public','permissions':[],'body':authSchemas['credentials']}},k),y[P(0x148)](P(0x149),{'schema':{'tags':['fcore',P(0x14a)],'summary':'Register','description':P(0x14b),'access':P(0x14c),'permissions':['user:create'],'body':authSchemas[P(0x14d)]}},async q=>X(q['body'],s)),y[P(0x148)]('/api/auth/password',{'schema':{'tags':['fcore','auth'],'summary':P(0x14e),'description':'Changes\x20the\x20password\x20for\x20the\x20current\x20user.','access':'user','permissions':[],'body':authSchemas['password']}},async q=>{if(!q['user'])throw new UnauthorizedError('Not\x20authorized');return await F({'userId':q['user']['id'],...q['body']},s),{'success':!![]};}),y['post']('/api/auth/logout',{'schema':{'tags':['fcore','auth'],'summary':'Sign\x20out','description':'Terminates\x20the\x20current\x20user\x20session.','access':'user','permissions':[]}},async(q,f)=>{const v=P,G={'redirectUrl':'/'};if(!q[v(0x14f)])return G;return await s['audit']?.['write']?.({'module':v(0x14a),'resource':v(0x144),'resourceId':q['session']['sessionId'],'action':'logout','userId':q['user']?.['id']}),await q['session']['destroy'](),f['clearCookie'](s['config']['auth']['cookieName']),Object['defineProperty'](q,'session',{'value':null,'writable':![],'configurable':![]}),G;}),y['get']('/api/auth/user',{'schema':{'tags':['fcore',P(0x14a)],'summary':'Get\x20current\x20user','description':'Returns\x20the\x20authenticated\x20user\x27s\x20safe\x20profile.','access':'user','permissions':[],'querystring':authSchemas['query']}},async q=>d({'user':q['user'],'token':q['query'][P(0x150)]}));};}function D(){const J=['config','cookie','session','sessionId','login','/api/auth/login','post','/api/auth/registration','auth','Creates\x20a\x20regular\x20user\x20account.','admin','credentials','Change\x20password','user','token'];D=function(){return J;};return D();}
1
+ import{getUserPermissions,verifyUser}from'../../plugins/auth/index.js';import L from'./services/get-current-user.js';import E from'./services/registration.js';import c from'./services/change-password.js';function O(L,E){L=L-0xcb;const c=Z();let t=c[L];return t;}function Z(){const x=['body','twofa','twoFactorRedirect','auth','config','sessionTimeout','session','type','fcore','public','credentials','post','Authenticates\x20a\x20user\x20and\x20returns\x20a\x20bearer\x20access\x20token.','Creates\x20a\x20regular\x20user\x20account.','clearCookie','get','Get\x20current\x20user','query','token'];Z=function(){return x;};return Z();}import{authSchemas}from'./schema.js';import t from'../../shared/getIP.js';import{UnauthorizedError}from'../../errors.js';export function authRoutes(e){return async B=>{const A=O,g=async r=>{const f=O,X=r['method']==='GET'?r['query']:r[f(0xcb)],j=t(r),F=await verifyUser({...X,'ip':j},e);F['permissions']=await getUserPermissions(F['id'],e);const I=F[f(0xcc)]?e['config']['auth'][f(0xcd)]:e['config'][f(0xce)]['redirect'];await r['login'](F);const T=e[f(0xcf)]['auth'][f(0xd0)]*0x3e8*0x3c;return r['session']?.['cookie']&&(r[f(0xd1)]['cookie']['maxAge']=T),await r['session']['save'](),await e['audit']?.['write']?.({'module':'auth','resource':'session','resourceId':r[f(0xd1)]['sessionId'],'action':'login','userId':F['id'],'ipAddress':j}),{'user':{'id':F['id'],'type':F[f(0xd2)],'permissions':F['permissions']},'redirectUrl':I};};B['get']('/api/auth/login',{'schema':{'tags':[A(0xd3),'auth'],'summary':'Sign\x20in','description':'Authenticates\x20a\x20user\x20and\x20returns\x20a\x20bearer\x20access\x20token.','access':A(0xd4),'permissions':[],'querystring':authSchemas[A(0xd5)]}},g),B[A(0xd6)]('/api/auth/login',{'schema':{'tags':['fcore',A(0xce)],'summary':'Sign\x20in','description':A(0xd7),'access':'public','permissions':[],'body':authSchemas['credentials']}},g),B[A(0xd6)]('/api/auth/registration',{'schema':{'tags':['fcore','auth'],'summary':'Register','description':A(0xd8),'access':'admin','permissions':['user:create'],'body':authSchemas[A(0xd5)]}},async r=>E(r['body'],e)),B['post']('/api/auth/password',{'schema':{'tags':['fcore','auth'],'summary':'Change\x20password','description':'Changes\x20the\x20password\x20for\x20the\x20current\x20user.','access':'user','permissions':[],'body':authSchemas['password']}},async r=>{if(!r['user'])throw new UnauthorizedError('Not\x20authorized');return await c({'userId':r['user']['id'],...r['body']},e),{'success':!![]};}),B[A(0xd6)]('/api/auth/logout',{'schema':{'tags':['fcore','auth'],'summary':'Sign\x20out','description':'Terminates\x20the\x20current\x20user\x20session.','access':'user','permissions':[]}},async(r,X)=>{const G=A,j={'redirectUrl':'/'};if(!r['user'])return j;return await e['audit']?.['write']?.({'module':'auth','resource':'session','resourceId':r['session']['sessionId'],'action':'logout','userId':r['user']?.['id']}),await r['session']['destroy'](),X[G(0xd9)](e['config']['auth']['cookieName']),Object['defineProperty'](r,'session',{'value':null,'writable':![],'configurable':![]}),j;}),B[A(0xda)]('/api/auth/user',{'schema':{'tags':['fcore','auth'],'summary':A(0xdb),'description':'Returns\x20the\x20authenticated\x20user\x27s\x20safe\x20profile.','access':'user','permissions':[],'querystring':authSchemas[A(0xdc)]}},async r=>L({'user':r['user'],'token':r['query'][A(0xdd)]}));};}
@@ -1 +1 @@
1
- const d=p;function p(d,X){d=d-0xf7;const F=D();let a=F[d];return a;}import{Type}from'@sinclair/typebox';export const authSchemas={'query':Type['Object']({'token':Type['Optional'](Type['Boolean']())}),'credentials':Type['Object']({'user':Type[d(0xf7)]({'minLength':0x1,'maxLength':0x64}),'password':Type['String']({'minLength':0x1,'maxLength':0x64}),'type':Type[d(0xf8)](Type['String']({'minLength':0x1,'maxLength':0x64}))}),'password':Type['Object']({'password':Type[d(0xf7)]({'minLength':0x1,'maxLength':0x64}),'id':Type[d(0xf8)](Type['String']({'minLength':0x1,'maxLength':0x64}))}),'twoFactor':Type[d(0xf9)]({'code':Type['String']({'minLength':0x1})})};function D(){const X=['String','Optional','Object'];D=function(){return X;};return D();}
1
+ const L=O;function Z(){const E=['Object','Optional','String'];Z=function(){return E;};return Z();}function O(L,E){L=L-0x192;const c=Z();let t=c[L];return t;}import{Type}from'@sinclair/typebox';export const authSchemas={'query':Type[L(0x192)]({'token':Type['Optional'](Type['Boolean']())}),'credentials':Type['Object']({'user':Type['String']({'minLength':0x1,'maxLength':0x64}),'password':Type['String']({'minLength':0x1,'maxLength':0x64}),'type':Type[L(0x193)](Type[L(0x194)]({'minLength':0x1,'maxLength':0x64}))}),'password':Type['Object']({'password':Type['String']({'minLength':0x1,'maxLength':0x64}),'id':Type[L(0x193)](Type['String']({'minLength':0x1,'maxLength':0x64}))}),'twoFactor':Type[L(0x192)]({'code':Type['String']({'minLength':0x1})})};
@@ -1 +1 @@
1
- import{hashPassword}from'../../../plugins/auth/index.js';export default async function changePassword({id:d,password:X,userId:F},{pg:a}){const s=await hashPassword(X);await a['query']('UPDATE\x20admin.users\x0a\x20\x20\x20\x20\x20SET\x20password_hash\x20=\x20$1,\x20updated_at\x20=\x20now(),\x20updated_by\x20=\x20$3\x0a\x20\x20\x20\x20\x20WHERE\x20uid\x20=\x20$2',[s,d||F,F]);}
1
+ function O(L,E){L=L-0xfa;const c=Z();let t=c[L];return t;}import{hashPassword}from'../../../plugins/auth/index.js';function Z(){const g=['UPDATE\x20admin.users\x0a\x20\x20\x20\x20\x20SET\x20password_hash\x20=\x20$1,\x20updated_at\x20=\x20now(),\x20updated_by\x20=\x20$3\x0a\x20\x20\x20\x20\x20WHERE\x20uid\x20=\x20$2'];Z=function(){return g;};return Z();}export default async function changePassword({id:L,password:E,userId:c},{pg:t}){const B=O,e=await hashPassword(E);await t['query'](B(0xfa),[e,L||c,c]);}
@@ -1 +1 @@
1
- import{safeUser}from'../../utils/safe-user.js';function p(d,X){d=d-0x180;const F=D();let a=F[d];return a;}export default async function getCurrentUser(d){const y=p,{user:X}=d;if(!X)return{};if(d['token']){const {jwtSignToken:F}=await import('../../../plugins/jwt.js'),a=await F(X);X['token']=a;}return X[y(0x180)]=[...new Set(X?.['permissions']['map'](s=>s[y(0x181)](':')[0x0]))],safeUser(X);}function D(){const k=['resources','split'];D=function(){return k;};return D();}
1
+ function O(L,E){L=L-0xcc;const c=Z();let t=c[L];return t;}function Z(){const g=['token','../../../plugins/jwt.js','permissions','map'];Z=function(){return g;};return Z();}import{safeUser}from'../../utils/safe-user.js';export default async function getCurrentUser(L){const B=O,{user:E}=L;if(!E)return{};if(L[B(0xcc)]){const {jwtSignToken:c}=await import(B(0xcd)),t=await c(E);E['token']=t;}return E['resources']=[...new Set(E?.[B(0xce)][B(0xcf)](e=>e['split'](':')[0x0]))],safeUser(E);}
@@ -1 +1 @@
1
- import{ConflictError}from'../../../errors.js';import{hashPassword}from'../../../plugins/auth/index.js';function p(d,X){d=d-0x84;const F=D();let a=F[d];return a;}function D(){const f=['rows'];D=function(){return f;};return D();}export default async function registration({user:d,password:X,type:F},{pg:a}){const q=p,s=await hashPassword(X),y=await a['query']('INSERT\x20INTO\x20admin.users\x20(login,\x20password_hash,\x20user_type)\x0a\x20\x20\x20\x20\x20SELECT\x20$1,\x20$2,\x20$3\x0a\x20\x20\x20\x20\x20WHERE\x20NOT\x20EXISTS\x20(SELECT\x201\x20FROM\x20admin.users\x20WHERE\x20login\x20=\x20$1)\x0a\x20\x20\x20\x20\x20RETURNING\x20uid\x20AS\x20id,\x20user_type\x20AS\x20type',[d,s,F||'regular']),k=y[q(0x84)][0x0];if(!k)throw new ConflictError('Login\x20is\x20already\x20in\x20use');return{'user':k};}
1
+ import{ConflictError}from'../../../errors.js';function Z(){const X=['query','Login\x20is\x20already\x20in\x20use'];Z=function(){return X;};return Z();}function O(L,E){L=L-0x17b;const c=Z();let t=c[L];return t;}import{hashPassword}from'../../../plugins/auth/index.js';export default async function registration({user:L,password:E,type:c},{pg:t}){const r=O,e=await hashPassword(E),B=await t[r(0x17b)]('INSERT\x20INTO\x20admin.users\x20(login,\x20password_hash,\x20user_type)\x0a\x20\x20\x20\x20\x20SELECT\x20$1,\x20$2,\x20$3\x0a\x20\x20\x20\x20\x20WHERE\x20NOT\x20EXISTS\x20(SELECT\x201\x20FROM\x20admin.users\x20WHERE\x20login\x20=\x20$1)\x0a\x20\x20\x20\x20\x20RETURNING\x20uid\x20AS\x20id,\x20user_type\x20AS\x20type',[L,e,c||'regular']),g=B['rows'][0x0];if(!g)throw new ConflictError(r(0x17c));return{'user':g};}
@@ -1 +1 @@
1
- import{unsupported}from'../../utils/unsupported.js';export default async function verifyTwoFactor(d,X){return unsupported('Two-factor\x20provider');}
1
+ import{unsupported}from'../../utils/unsupported.js';export default async function verifyTwoFactor(L,E){return unsupported('Two-factor\x20provider');}
@@ -1 +1 @@
1
- var d=p;function D(){var X=['application/pdf','application/vnd.openxmlformats-officedocument.wordprocessingml.document','application/vnd.ms-excel','application/vnd.openxmlformats-officedocument.spreadsheetml.sheet','application/vnd.oasis.opendocument.presentation','text/plain','text/xml','application/geo+json','application/vnd.google-earth.kmz','application/x-tar','audio/mpeg','audio/ogg','audio/mp4','application/octet-stream'];D=function(){return X;};return D();}function p(d,X){d=d-0xc7;var F=D();var a=F[d];return a;}export default new Set(['image/jpeg','image/png','image/gif','image/webp','image/bmp','image/tiff','image/svg+xml','image/x-icon','image/avif',d(0xc7),'application/msword',d(0xc8),d(0xc9),d(0xca),'application/vnd.ms-powerpoint','application/vnd.openxmlformats-officedocument.presentationml.presentation','application/vnd.oasis.opendocument.text','application/vnd.oasis.opendocument.spreadsheet',d(0xcb),d(0xcc),'text/csv','text/markdown','application/json','application/xml',d(0xcd),d(0xce),'application/vnd.google-earth.kml+xml',d(0xcf),'application/zip','application/x-zip-compressed','application/x-7z-compressed','application/x-rar-compressed','application/vnd.rar','application/gzip','application/x-gzip',d(0xd0),d(0xd1),'audio/wav',d(0xd2),'audio/webm',d(0xd3),'video/mp4','video/mpeg','video/webm','video/quicktime','video/x-msvideo',d(0xd4)]);
1
+ var L=O;function O(L,E){L=L-0x93;var c=Z();var t=c[L];return t;}export default new Set(['image/jpeg',L(0x93),L(0x94),'image/webp',L(0x95),L(0x96),'image/svg+xml','image/x-icon','image/avif','application/pdf','application/msword','application/vnd.openxmlformats-officedocument.wordprocessingml.document','application/vnd.ms-excel','application/vnd.openxmlformats-officedocument.spreadsheetml.sheet','application/vnd.ms-powerpoint',L(0x97),'application/vnd.oasis.opendocument.text','application/vnd.oasis.opendocument.spreadsheet',L(0x98),'text/plain',L(0x99),L(0x9a),L(0x9b),'application/xml',L(0x9c),L(0x9d),'application/vnd.google-earth.kml+xml',L(0x9e),'application/zip',L(0x9f),'application/x-7z-compressed',L(0xa0),'application/vnd.rar','application/gzip','application/x-gzip','application/x-tar','audio/mpeg','audio/wav',L(0xa1),L(0xa2),'audio/mp4','video/mp4','video/mpeg','video/webm','video/quicktime','video/x-msvideo','application/octet-stream']);function Z(){var E=['image/png','image/gif','image/bmp','image/tiff','application/vnd.openxmlformats-officedocument.presentationml.presentation','application/vnd.oasis.opendocument.presentation','text/csv','text/markdown','application/json','text/xml','application/geo+json','application/vnd.google-earth.kmz','application/x-zip-compressed','application/x-rar-compressed','audio/ogg','audio/webm'];Z=function(){return E;};return Z();}
@@ -1 +1 @@
1
- function D(){const v=['get','application/octet-stream','download','split','type','header','inline','user','file','path','value','/api/file/:token/resize','Resize\x20file','files:read','fileToken','resizeQuery','image/png','public,\x20max-age=86400,\x20immutable','send'];D=function(){return v;};return D();}function p(d,X){d=d-0x156;const F=D();let a=F[d];return a;}import{fileTypeFromBuffer}from'file-type';import{getFile}from'./services/get-file.js';import{uploadFile}from'./services/upload-file.js';import{resizeFile}from'./services/resize-file.js';import{fileSchemas}from'./schema.js';export function fileRoutes(d){return async X=>{const H=p;X[H(0x156)]('/api/file/:token',{'schema':{'tags':['fcore','file'],'summary':'Get\x20file\x20by\x20token','description':'Returns\x20a\x20file\x20after\x20verifying\x20its\x20signed\x20access\x20token.','access':'public','permissions':[],'params':fileSchemas['fileToken'],'querystring':fileSchemas['fileDownloadQuery']}},async(F,a)=>{const T=H,s=d['file']['verify'](F['params']['token']),y=await getFile({'pathOrToken':s},d),k=await fileTypeFromBuffer(y),q=k?.['mime']??T(0x157),f=F['query'][T(0x158)]===!![],G=q['startsWith']('image/')||q==='application/pdf',b=s[T(0x159)]('/')['pop']()?.['replace'](/[^A-Za-z0-9._-]/g,'_')??'file';return a[T(0x15a)](q),a[T(0x15b)]('Content-Disposition',(f||!G?'attachment':T(0x15c))+';\x20filename=\x22'+b+'\x22')['header']('Cache-Control','public,\x20max-age=86400,\x20immutable'),a['send'](y);}),X['post']('/api/file/upload',{'schema':{'tags':['fcore','file'],'summary':'Upload\x20file','description':'Uploads\x20a\x20file\x20and\x20stores\x20its\x20metadata.','access':H(0x15d),'permissions':['files:create']}},async F=>{const W=H,a=await F[W(0x15e)]();if(!a)throw new Error('File\x20is\x20required');return uploadFile({'file':a,'metadata':{'name':a['filename'],'path':a['fields'][W(0x15f)]?.[W(0x160)],'resource':a['fields']['resource']?.['value'],'resourceId':a['fields']['resourceId']?.['value']},'user':F['user']},d);}),X['get'](H(0x161),{'schema':{'tags':['fcore',H(0x15e)],'summary':H(0x162),'description':'Returns\x20a\x20resized\x20image\x20file.','access':H(0x15d),'permissions':[H(0x163)],'params':fileSchemas[H(0x164)],'querystring':fileSchemas[H(0x165)]}},async(F,a)=>{const P=H,s=await resizeFile({'pathOrToken':d['file']?.['verify'](F['params']['token']),...F['query']},d),y=await fileTypeFromBuffer(s);return a['type'](y?.['mime']??P(0x166)),a[P(0x15b)]('Content-Disposition','inline')['header']('Cache-Control',P(0x167)),a[P(0x168)](s);});};}
1
+ import{fileTypeFromBuffer}from'file-type';function O(L,E){L=L-0xf9;const c=Z();let t=c[L];return t;}import{getFile}from'./services/get-file.js';function Z(){const G=['get','fcore','file','Get\x20file\x20by\x20token','Returns\x20a\x20file\x20after\x20verifying\x20its\x20signed\x20access\x20token.','public','fileToken','fileDownloadQuery','query','pop','Cache-Control','post','user','File\x20is\x20required','fields','Returns\x20a\x20resized\x20image\x20file.','params','token','public,\x20max-age=86400,\x20immutable','send'];Z=function(){return G;};return Z();}import{uploadFile}from'./services/upload-file.js';import{resizeFile}from'./services/resize-file.js';import{fileSchemas}from'./schema.js';export function fileRoutes(L){return async E=>{const I=O;E[I(0xf9)]('/api/file/:token',{'schema':{'tags':[I(0xfa),I(0xfb)],'summary':I(0xfc),'description':I(0xfd),'access':I(0xfe),'permissions':[],'params':fileSchemas[I(0xff)],'querystring':fileSchemas[I(0x100)]}},async(c,t)=>{const T=I,e=L[T(0xfb)]['verify'](c['params']['token']),B=await getFile({'pathOrToken':e},L),g=await fileTypeFromBuffer(B),r=g?.['mime']??'application/octet-stream',X=c[T(0x101)]['download']===!![],j=r['startsWith']('image/')||r==='application/pdf',F=e['split']('/')[T(0x102)]()?.['replace'](/[^A-Za-z0-9._-]/g,'_')??T(0xfb);return t['type'](r),t['header']('Content-Disposition',(X||!j?'attachment':'inline')+';\x20filename=\x22'+F+'\x22')['header'](T(0x103),'public,\x20max-age=86400,\x20immutable'),t['send'](B);}),E[I(0x104)]('/api/file/upload',{'schema':{'tags':['fcore','file'],'summary':'Upload\x20file','description':'Uploads\x20a\x20file\x20and\x20stores\x20its\x20metadata.','access':I(0x105),'permissions':['files:create']}},async c=>{const f=I,t=await c['file']();if(!t)throw new Error(f(0x106));return uploadFile({'file':t,'metadata':{'name':t['filename'],'path':t[f(0x107)]['path']?.['value'],'resource':t['fields']['resource']?.['value'],'resourceId':t['fields']['resourceId']?.['value']},'user':c['user']},L);}),E['get']('/api/file/:token/resize',{'schema':{'tags':['fcore','file'],'summary':'Resize\x20file','description':I(0x108),'access':'user','permissions':['files:read'],'params':fileSchemas['fileToken'],'querystring':fileSchemas['resizeQuery']}},async(c,t)=>{const A=I,e=await resizeFile({'pathOrToken':L['file']?.['verify'](c[A(0x109)][A(0x10a)]),...c[A(0x101)]},L),B=await fileTypeFromBuffer(e);return t['type'](B?.['mime']??'image/png'),t['header']('Content-Disposition','inline')['header']('Cache-Control',A(0x10b)),t[A(0x10c)](e);});};}
@@ -1 +1 @@
1
- const d=p;import{Type}from'@sinclair/typebox';function D(){const X=['Object','String','Union','Literal'];D=function(){return X;};return D();}function p(d,X){d=d-0xd4;const F=D();let a=F[d];return a;}export const fileSchemas={'fileId':Type[d(0xd4)]({'id':Type['String']({'minLength':0x1,'maxLength':0x80})}),'fileToken':Type['Object']({'token':Type[d(0xd5)]({'minLength':0x1,'maxLength':0x800})}),'fileDownloadQuery':Type['Object']({'download':Type['Optional'](Type['Boolean']())}),'filePath':Type['Object']({'*':Type['String']({'minLength':0x1,'maxLength':0x400})}),'upload':Type['Object']({'file':Type['Any'](),'metadata':Type['Object']({'name':Type['Optional'](Type['String']({'minLength':0x1})),'path':Type['Optional'](Type['String']({'minLength':0x1})),'entityType':Type['Optional'](Type['String']({'minLength':0x1})),'entityId':Type['Optional'](Type[d(0xd5)]({'minLength':0x1}))})}),'filePatch':Type['Object']({'entityType':Type['Optional'](Type['String']({'minLength':0x1})),'entityId':Type['Optional'](Type['String']({'minLength':0x1}))}),'resizeQuery':Type['Object']({'width':Type['Optional'](Type['Integer']({'minimum':0x1,'default':0xc8})),'height':Type['Optional'](Type['Integer']({'minimum':0x1})),'fit':Type['Optional'](Type[d(0xd6)]([Type['Literal']('cover'),Type[d(0xd7)]('contain'),Type['Literal']('fill'),Type['Literal']('inside'),Type['Literal']('outside')]))})};
1
+ const L=O;import{Type}from'@sinclair/typebox';function O(L,E){L=L-0x144;const c=Z();let t=c[L];return t;}export const fileSchemas={'fileId':Type['Object']({'id':Type['String']({'minLength':0x1,'maxLength':0x80})}),'fileToken':Type['Object']({'token':Type[L(0x144)]({'minLength':0x1,'maxLength':0x800})}),'fileDownloadQuery':Type[L(0x145)]({'download':Type['Optional'](Type[L(0x146)]())}),'filePath':Type[L(0x145)]({'*':Type['String']({'minLength':0x1,'maxLength':0x400})}),'upload':Type['Object']({'file':Type['Any'](),'metadata':Type['Object']({'name':Type['Optional'](Type[L(0x144)]({'minLength':0x1})),'path':Type['Optional'](Type['String']({'minLength':0x1})),'entityType':Type[L(0x147)](Type['String']({'minLength':0x1})),'entityId':Type['Optional'](Type[L(0x144)]({'minLength':0x1}))})}),'filePatch':Type['Object']({'entityType':Type['Optional'](Type['String']({'minLength':0x1})),'entityId':Type['Optional'](Type[L(0x144)]({'minLength':0x1}))}),'resizeQuery':Type[L(0x145)]({'width':Type['Optional'](Type['Integer']({'minimum':0x1,'default':0xc8})),'height':Type['Optional'](Type['Integer']({'minimum':0x1})),'fit':Type['Optional'](Type['Union']([Type[L(0x148)](L(0x149)),Type['Literal']('contain'),Type['Literal']('fill'),Type['Literal'](L(0x14a)),Type[L(0x148)]('outside')]))})};function Z(){const E=['String','Object','Boolean','Optional','Literal','cover','inside'];Z=function(){return E;};return Z();}
@@ -1 +1 @@
1
- import{NotFoundError}from'../../../errors.js';export async function getFile(d,X){var F=p;if(!X['file'])throw new Error(F(0x116));if(!await X['file'][F(0x117)](d['pathOrToken']))throw new NotFoundError(F(0x118)+d[F(0x119)]);return X['file']['get'](d['pathOrToken']);}function p(d,X){d=d-0x116;var F=D();var a=F[d];return a;}function D(){var a=['empty\x20file','exists','File\x20not\x20found','pathOrToken'];D=function(){return a;};return D();}
1
+ function O(L,E){L=L-0x115;var c=Z();var t=c[L];return t;}import{NotFoundError}from'../../../errors.js';export async function getFile(L,E){var c=O;if(!E['file'])throw new Error('empty\x20file');if(!await E[c(0x115)]['exists'](L['pathOrToken']))throw new NotFoundError('File\x20not\x20found'+L[c(0x116)]);return E['file']['get'](L['pathOrToken']);}function Z(){var t=['file','pathOrToken'];Z=function(){return t;};return Z();}
@@ -1 +1 @@
1
- import{NotFoundError,ValidationError}from'../../../errors.js';import{fileTypeFromBuffer}from'file-type';import{createHash}from'node:crypto';function p(d,X){d=d-0x1e4;const F=D();let a=F[d];return a;}import{mkdir,readFile,writeFile}from'node:fs/promises';import d from'node:path';function D(){const J=['File\x20path\x20is\x20required','width','height','sha256','resolve','resize','.jpg','file','startsWith','image/','isInteger'];D=function(){return J;};return D();}import X from'sharp';export async function resizeFile(F,a){const P=p,s=F['pathOrToken']??F['path'];if(!s)throw new ValidationError(P(0x1e4));const y=parseDimension(F[P(0x1e5)],'width')??0xc8,k=parseDimension(F['height'],P(0x1e6)),q=createHash(P(0x1e7))['update'](s+':'+y+':'+(k??'auto')+':'+(F['fit']??'cover'))['digest']('hex'),f=d[P(0x1e8)]('logs',P(0x1e9)),G=d['join'](f,q+P(0x1ea));try{return await readFile(G);}catch(W){if(W['code']!=='ENOENT')throw W;}if(!await a[P(0x1eb)]['exists'](s))throw new NotFoundError('File\x20not\x20found');const b=await a['file']['get'](s),H=await fileTypeFromBuffer(b);if(!H?.['mime'][P(0x1ec)](P(0x1ed)))throw new ValidationError('Only\x20image\x20files\x20can\x20be\x20resized');const T=await X(b)['resize']({'width':y,'height':k,'fit':F['fit']??'cover'})['toBuffer']();return await mkdir(f,{'recursive':!![]}),await writeFile(G,T),T;}function parseDimension(F,a){const v=p;if(F===undefined||F==='')return undefined;const s=Number(F);if(!Number[v(0x1ee)](s)||s<=0x0)throw new ValidationError(a+'\x20must\x20be\x20a\x20positive\x20integer');return s;}
1
+ function Z(){const x=['width','height','sha256','auto','fit','hex','logs','.jpg','code','file','resize','toBuffer','isInteger'];Z=function(){return x;};return Z();}import{NotFoundError,ValidationError}from'../../../errors.js';import{fileTypeFromBuffer}from'file-type';import{createHash}from'node:crypto';function O(L,E){L=L-0x1cf;const c=Z();let t=c[L];return t;}import{mkdir,readFile,writeFile}from'node:fs/promises';import L from'node:path';import E from'sharp';export async function resizeFile(c,t){const A=O,e=c['pathOrToken']??c['path'];if(!e)throw new ValidationError('File\x20path\x20is\x20required');const B=parseDimension(c['width'],A(0x1cf))??0xc8,g=parseDimension(c[A(0x1d0)],'height'),r=createHash(A(0x1d1))['update'](e+':'+B+':'+(g??A(0x1d2))+':'+(c[A(0x1d3)]??'cover'))['digest'](A(0x1d4)),X=L['resolve'](A(0x1d5),'resize'),j=L['join'](X,r+A(0x1d6));try{return await readFile(j);}catch(f){if(f[A(0x1d7)]!=='ENOENT')throw f;}if(!await t[A(0x1d8)]['exists'](e))throw new NotFoundError('File\x20not\x20found');const F=await t[A(0x1d8)]['get'](e),I=await fileTypeFromBuffer(F);if(!I?.['mime']['startsWith']('image/'))throw new ValidationError('Only\x20image\x20files\x20can\x20be\x20resized');const T=await E(F)[A(0x1d9)]({'width':B,'height':g,'fit':c['fit']??'cover'})[A(0x1da)]();return await mkdir(X,{'recursive':!![]}),await writeFile(j,T),T;}function parseDimension(c,t){const G=O;if(c===undefined||c==='')return undefined;const e=Number(c);if(!Number[G(0x1db)](e)||e<=0x0)throw new ValidationError(t+'\x20must\x20be\x20a\x20positive\x20integer');return e;}
@@ -1 +1 @@
1
- import{fileTypeFromBuffer}from'file-type';import d from'../mime.js';import{randomUUID}from'node:crypto';export async function uploadFile(X,F){const T=p,a=(X['metadata']['name']??randomUUID())[T(0x8d)](/[^a-zA-Z0-9._-]/g,'_'),s=new Date(),y=String(s[T(0x8e)]())[T(0x8f)](-0x2),k=String(s[T(0x90)]()+0x1)['padStart'](0x2,'0'),q=String(s['getDate']())['padStart'](0x2,'0'),f=X[T(0x91)]['path']??(X['metadata']['resource']?X['metadata']['resource']+'/'+(X[T(0x91)]['resourceId']??randomUUID())+'/'+a:null)??T(0x92)+y+'/'+k+'-'+q+'/'+a,G=await X['file']['toBuffer'](),b=await fileTypeFromBuffer(G);if(!d['has'](X['file'][T(0x93)])&&(b?.[T(0x94)]?!d['has'](b['mime']):!![]))throw new Error('Unsupported\x20file\x20type:\x20'+X[T(0x95)]['mimetype']);await F['file'][T(0x96)](f,G);const H=await F['pg']['query']('\x0a\x20\x20\x20\x20\x20\x20\x20\x20INSERT\x20INTO\x20admin.files\x20(resource,\x20resource_id,\x20file_path,\x20file_type,\x20size,uploaded_name,file_name,ext,created_by)\x0a\x20\x20\x20\x20\x20\x20\x20\x20VALUES\x20($1,\x20$2,\x20$3,\x20$4,\x20$5,\x20$6,\x20$7,\x20$8,\x20$9)\x0a\x20\x20\x20\x20\x20\x20\x20\x20RETURNING\x20*\x0a\x20\x20\x20\x20\x20\x20',[X[T(0x91)]['resource']??null,X[T(0x91)]['resourceId']??null,f,X['file'][T(0x93)],X['file']['file']['bytesRead'],X['metadata'][T(0x97)],a,X[T(0x95)]['mimetype']['split']('/')['pop']()??null,X['user']?.['id']??null]);return H[T(0x98)][0x0];}function p(d,X){d=d-0x8d;const F=D();let a=F[d];return a;}function D(){const W=['replace','getFullYear','slice','getMonth','metadata','uploads/','mimetype','mime','file','put','name','rows'];D=function(){return W;};return D();}
1
+ function Z(){const f=['replace','getFullYear','padStart','path','metadata','resource','mime','Unsupported\x20file\x20type:\x20','query','resourceId','file','user'];Z=function(){return f;};return Z();}function O(L,E){L=L-0x1c1;const c=Z();let t=c[L];return t;}import{fileTypeFromBuffer}from'file-type';import L from'../mime.js';import{randomUUID}from'node:crypto';export async function uploadFile(E,c){const T=O,t=(E['metadata']['name']??randomUUID())[T(0x1c1)](/[^a-zA-Z0-9._-]/g,'_'),e=new Date(),B=String(e[T(0x1c2)]())['slice'](-0x2),g=String(e['getMonth']()+0x1)['padStart'](0x2,'0'),r=String(e['getDate']())[T(0x1c3)](0x2,'0'),X=E['metadata'][T(0x1c4)]??(E[T(0x1c5)][T(0x1c6)]?E['metadata'][T(0x1c6)]+'/'+(E['metadata']['resourceId']??randomUUID())+'/'+t:null)??'uploads/'+B+'/'+g+'-'+r+'/'+t,j=await E['file']['toBuffer'](),F=await fileTypeFromBuffer(j);if(!L['has'](E['file']['mimetype'])&&(F?.[T(0x1c7)]?!L['has'](F[T(0x1c7)]):!![]))throw new Error(T(0x1c8)+E['file']['mimetype']);await c['file']['put'](X,j);const I=await c['pg'][T(0x1c9)]('\x0a\x20\x20\x20\x20\x20\x20\x20\x20INSERT\x20INTO\x20admin.files\x20(resource,\x20resource_id,\x20file_path,\x20file_type,\x20size,uploaded_name,file_name,ext,created_by)\x0a\x20\x20\x20\x20\x20\x20\x20\x20VALUES\x20($1,\x20$2,\x20$3,\x20$4,\x20$5,\x20$6,\x20$7,\x20$8,\x20$9)\x0a\x20\x20\x20\x20\x20\x20\x20\x20RETURNING\x20*\x0a\x20\x20\x20\x20\x20\x20',[E[T(0x1c5)]['resource']??null,E['metadata'][T(0x1ca)]??null,X,E['file']['mimetype'],E['file'][T(0x1cb)]['bytesRead'],E['metadata']['name'],t,E[T(0x1cb)]['mimetype']['split']('/')['pop']()??null,E[T(0x1cc)]?.['id']??null]);return I['rows'][0x0];}
@@ -1 +1 @@
1
- function p(d,X){d=d-0x185;const F=D();let a=F[d];return a;}import{ForbiddenError}from'../../errors.js';import{listResources}from'./services/list-resources.js';import{getResource}from'./services/get-resource.js';import{createResource}from'./services/create-resource.js';import{updateResource}from'./services/update-resource.js';function D(){const f=['resource','resourceField','params','Exports\x20readable\x20records\x20from\x20a\x20registered\x20resource.','get','/api/resource/:resource','fcore','query','post','Creates\x20a\x20record\x20in\x20a\x20registered\x20resource.','body','/api/resource/:resource/:id','user','resourceId','Upload\x20resource\x20file','file','Missing\x20permission:\x20','filename','fields','List\x20resource\x20relations','Create\x20resource\x20relation','Creates\x20a\x20relation\x20for\x20a\x20resource\x20record.','resourceIdRelation'];D=function(){return f;};return D();}import{deleteResource}from'./services/delete-resource.js';import{listResourceRelation}from'./services/list-resource-relation.js';import{createResourceRelation}from'./services/create-resource-relation.js';import{updateResourceRelation}from'./services/update-resource-relation.js';import{deleteResourceRelation}from'./services/delete-resource-relation.js';import{searchResource}from'./services/search-resource.js';import{exportResource}from'./services/export-resource.js';import{suggestResource}from'./services/suggest-resource.js';import{resourceSchemas}from'./schema.js';import{uploadFile}from'../file/services/upload-file.js';const user=d=>d['user'];export function resourceRoutes(d){return async X=>{const k=p;X['get']('/api/resource/:resource/search',{'schema':{'tags':['fcore','resource'],'summary':'Search\x20resource','description':'Searches\x20records\x20in\x20a\x20registered\x20resource.','access':'user','permissions':[],'params':resourceSchemas[k(0x185)]}},async F=>searchResource({...F['query'],...F['params'],'user':user(F)},d)),X['get']('/api/suggest/:resource/:field',{'schema':{'tags':['fcore','resource'],'summary':'Suggest\x20resource\x20values','description':'Returns\x20suggested\x20values\x20for\x20a\x20resource\x20field.','access':'user','permissions':[],'params':resourceSchemas[k(0x186)],'querystring':resourceSchemas['suggestQuery']}},async F=>suggestResource({...F['query'],...F[k(0x187)],'user':user(F)},d)),X['get']('/api/resource/:resource/export',{'schema':{'tags':['fcore',k(0x185)],'summary':'Export\x20resource\x20records','description':k(0x188),'access':'user','permissions':['*:read'],'params':resourceSchemas['exportResource'],'querystring':resourceSchemas['exportResourceQuery']}},async F=>exportResource({...F['query'],...F[k(0x187)],'user':user(F)},d)),X[k(0x189)](k(0x18a),{'schema':{'tags':[k(0x18b),'resource'],'summary':'List\x20resource\x20records','description':'Returns\x20records\x20from\x20a\x20registered\x20resource.','access':'user','permissions':[],'params':resourceSchemas['resource']}},async F=>listResources({...F[k(0x18c)],...F['params'],'user':user(F)},d)),X[k(0x18d)](k(0x18a),{'schema':{'tags':['fcore','resource'],'summary':'Create\x20resource\x20record','description':k(0x18e),'access':'user','permissions':[],'params':resourceSchemas['resource']}},async F=>createResource({...F['params'],'data':F[k(0x18f)],'user':user(F)},d)),X[k(0x189)](k(0x190),{'schema':{'tags':['fcore','resource'],'summary':'Get\x20resource\x20record','description':'Returns\x20one\x20record\x20from\x20a\x20registered\x20resource.','access':k(0x191),'permissions':[],'params':resourceSchemas[k(0x192)],'querystring':resourceSchemas['resourceIncludeQuery']}},async F=>getResource({...F['query'],...F['params'],'user':user(F)},d)),X['put']('/api/resource/:resource/:id',{'schema':{'tags':[k(0x18b),'resource'],'summary':'Update\x20resource\x20record','description':'Updates\x20a\x20record\x20in\x20a\x20registered\x20resource.','access':'user','permissions':[],'params':resourceSchemas['resourceId']}},async F=>updateResource({...F['params'],'patch':F['body'],'user':user(F)},d)),X['delete']('/api/resource/:resource/:id',{'schema':{'tags':['fcore','resource'],'summary':'Delete\x20resource\x20record','description':'Deletes\x20a\x20record\x20from\x20a\x20registered\x20resource.','access':k(0x191),'permissions':[],'params':resourceSchemas['resourceId']}},async F=>deleteResource({...F['params'],'user':user(F)},d)),X['post']('/api/resource/:resource/:id/upload',{'schema':{'tags':[k(0x18b),k(0x185)],'summary':k(0x193),'description':'Uploads\x20a\x20file\x20to\x20a\x20Resource\x20record\x20and\x20stores\x20its\x20metadata.','access':k(0x191),'permissions':[],'params':resourceSchemas['uploadResourceFile']}},async F=>{const q=k,a=await F[q(0x194)]();if(!a)throw new Error('File\x20is\x20required');const s=F['params'][q(0x185)],y=F[q(0x187)]['id'];if(F['user']?.['type']!=='admin'&&!F[q(0x191)]?.['permissions']['includes'](s+':update'))throw new ForbiddenError(q(0x195)+s+':update');return uploadFile({'file':a,'metadata':{'name':a[q(0x196)],'path':a[q(0x197)]['path']?.['value'],'resource':s,'resourceId':y},'user':F['user']},d);}),X['get']('/api/resource/:resource/:id/:relation',{'schema':{'tags':[k(0x18b),k(0x185)],'summary':k(0x198),'description':'Returns\x20related\x20records\x20for\x20a\x20resource\x20record.','access':'user','permissions':[],'schema':{'params':resourceSchemas['resourceIdRelation']}}},async F=>listResourceRelation({...F['query'],...F[k(0x187)],'user':user(F)},d)),X['post']('/api/resource/:resource/:id/:relation',{'schema':{'tags':['fcore','resource'],'summary':k(0x199),'description':k(0x19a),'access':'user','permissions':[],'params':resourceSchemas[k(0x19b)]}},async F=>createResourceRelation({...F[k(0x187)],'data':F[k(0x18f)],'user':user(F)},d)),X['delete']('/api/resource/:resource/:id/:relation/:relationId',{'schema':{'tags':['fcore','resource'],'summary':'Delete\x20resource\x20relation','description':'Deletes\x20a\x20relation\x20from\x20a\x20resource\x20record.','access':k(0x191),'permissions':[],'params':resourceSchemas['resourceIdRelationId']}},async F=>deleteResourceRelation({...F[k(0x187)],'user':user(F)},d)),X['put']('/api/resource/:resource/:id/:relation/:relationId',{'schema':{'tags':['fcore',k(0x185)],'summary':'Update\x20resource\x20relation','description':'Updates\x20a\x20related\x20resource\x20record.','access':'user','permissions':[],'params':resourceSchemas['resourceIdRelationId']}},async F=>updateResourceRelation({...F['params'],'data':F['body'],'user':user(F)},d));};}
1
+ import{ForbiddenError}from'../../errors.js';import{listResources}from'./services/list-resources.js';import{getResource}from'./services/get-resource.js';import{createResource}from'./services/create-resource.js';import{updateResource}from'./services/update-resource.js';import{deleteResource}from'./services/delete-resource.js';function Z(){const X=['get','Search\x20resource','/api/suggest/:resource/:field','fcore','resource','Returns\x20suggested\x20values\x20for\x20a\x20resource\x20field.','suggestQuery','*:read','exportResourceQuery','query','List\x20resource\x20records','Returns\x20records\x20from\x20a\x20registered\x20resource.','params','Creates\x20a\x20record\x20in\x20a\x20registered\x20resource.','body','/api/resource/:resource/:id','resourceId','resourceIncludeQuery','put','Update\x20resource\x20record','Updates\x20a\x20record\x20in\x20a\x20registered\x20resource.','user','Deletes\x20a\x20record\x20from\x20a\x20registered\x20resource.','/api/resource/:resource/:id/upload','uploadResourceFile','type',':update','filename','fields','Create\x20resource\x20relation','resourceIdRelationId','Updates\x20a\x20related\x20resource\x20record.'];Z=function(){return X;};return Z();}import{listResourceRelation}from'./services/list-resource-relation.js';import{createResourceRelation}from'./services/create-resource-relation.js';import{updateResourceRelation}from'./services/update-resource-relation.js';import{deleteResourceRelation}from'./services/delete-resource-relation.js';import{searchResource}from'./services/search-resource.js';import{exportResource}from'./services/export-resource.js';import{suggestResource}from'./services/suggest-resource.js';import{resourceSchemas}from'./schema.js';import{uploadFile}from'../file/services/upload-file.js';const user=L=>L['user'];function O(L,E){L=L-0x122;const c=Z();let t=c[L];return t;}export function resourceRoutes(L){return async E=>{const g=O;E[g(0x122)]('/api/resource/:resource/search',{'schema':{'tags':['fcore','resource'],'summary':g(0x123),'description':'Searches\x20records\x20in\x20a\x20registered\x20resource.','access':'user','permissions':[],'params':resourceSchemas['resource']}},async c=>searchResource({...c['query'],...c['params'],'user':user(c)},L)),E['get'](g(0x124),{'schema':{'tags':[g(0x125),g(0x126)],'summary':'Suggest\x20resource\x20values','description':g(0x127),'access':'user','permissions':[],'params':resourceSchemas['resourceField'],'querystring':resourceSchemas[g(0x128)]}},async c=>suggestResource({...c['query'],...c['params'],'user':user(c)},L)),E['get']('/api/resource/:resource/export',{'schema':{'tags':['fcore','resource'],'summary':'Export\x20resource\x20records','description':'Exports\x20readable\x20records\x20from\x20a\x20registered\x20resource.','access':'user','permissions':[g(0x129)],'params':resourceSchemas['exportResource'],'querystring':resourceSchemas[g(0x12a)]}},async c=>exportResource({...c[g(0x12b)],...c['params'],'user':user(c)},L)),E['get']('/api/resource/:resource',{'schema':{'tags':['fcore','resource'],'summary':g(0x12c),'description':g(0x12d),'access':'user','permissions':[],'params':resourceSchemas['resource']}},async c=>listResources({...c['query'],...c[g(0x12e)],'user':user(c)},L)),E['post']('/api/resource/:resource',{'schema':{'tags':[g(0x125),'resource'],'summary':'Create\x20resource\x20record','description':g(0x12f),'access':'user','permissions':[],'params':resourceSchemas[g(0x126)]}},async c=>createResource({...c['params'],'data':c[g(0x130)],'user':user(c)},L)),E[g(0x122)](g(0x131),{'schema':{'tags':[g(0x125),'resource'],'summary':'Get\x20resource\x20record','description':'Returns\x20one\x20record\x20from\x20a\x20registered\x20resource.','access':'user','permissions':[],'params':resourceSchemas[g(0x132)],'querystring':resourceSchemas[g(0x133)]}},async c=>getResource({...c[g(0x12b)],...c['params'],'user':user(c)},L)),E[g(0x134)]('/api/resource/:resource/:id',{'schema':{'tags':['fcore','resource'],'summary':g(0x135),'description':g(0x136),'access':g(0x137),'permissions':[],'params':resourceSchemas['resourceId']}},async c=>updateResource({...c[g(0x12e)],'patch':c['body'],'user':user(c)},L)),E['delete']('/api/resource/:resource/:id',{'schema':{'tags':['fcore','resource'],'summary':'Delete\x20resource\x20record','description':g(0x138),'access':'user','permissions':[],'params':resourceSchemas[g(0x132)]}},async c=>deleteResource({...c['params'],'user':user(c)},L)),E['post'](g(0x139),{'schema':{'tags':['fcore','resource'],'summary':'Upload\x20resource\x20file','description':'Uploads\x20a\x20file\x20to\x20a\x20Resource\x20record\x20and\x20stores\x20its\x20metadata.','access':g(0x137),'permissions':[],'params':resourceSchemas[g(0x13a)]}},async c=>{const r=g,t=await c['file']();if(!t)throw new Error('File\x20is\x20required');const e=c['params']['resource'],B=c['params']['id'];if(c['user']?.[r(0x13b)]!=='admin'&&!c[r(0x137)]?.['permissions']['includes'](e+r(0x13c)))throw new ForbiddenError('Missing\x20permission:\x20'+e+r(0x13c));return uploadFile({'file':t,'metadata':{'name':t[r(0x13d)],'path':t[r(0x13e)]['path']?.['value'],'resource':e,'resourceId':B},'user':c['user']},L);}),E[g(0x122)]('/api/resource/:resource/:id/:relation',{'schema':{'tags':['fcore','resource'],'summary':'List\x20resource\x20relations','description':'Returns\x20related\x20records\x20for\x20a\x20resource\x20record.','access':'user','permissions':[],'schema':{'params':resourceSchemas['resourceIdRelation']}}},async c=>listResourceRelation({...c['query'],...c[g(0x12e)],'user':user(c)},L)),E['post']('/api/resource/:resource/:id/:relation',{'schema':{'tags':['fcore',g(0x126)],'summary':g(0x13f),'description':'Creates\x20a\x20relation\x20for\x20a\x20resource\x20record.','access':'user','permissions':[],'params':resourceSchemas['resourceIdRelation']}},async c=>createResourceRelation({...c['params'],'data':c['body'],'user':user(c)},L)),E['delete']('/api/resource/:resource/:id/:relation/:relationId',{'schema':{'tags':['fcore',g(0x126)],'summary':'Delete\x20resource\x20relation','description':'Deletes\x20a\x20relation\x20from\x20a\x20resource\x20record.','access':'user','permissions':[],'params':resourceSchemas[g(0x140)]}},async c=>deleteResourceRelation({...c['params'],'user':user(c)},L)),E['put']('/api/resource/:resource/:id/:relation/:relationId',{'schema':{'tags':['fcore','resource'],'summary':'Update\x20resource\x20relation','description':g(0x141),'access':'user','permissions':[],'params':resourceSchemas['resourceIdRelationId']}},async c=>updateResourceRelation({...c['params'],'data':c['body'],'user':user(c)},L));};}
@@ -1 +1 @@
1
- const d=p;import{Type}from'@sinclair/typebox';function p(d,X){d=d-0x179;const F=D();let a=F[d];return a;}function D(){const X=['String','^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$','Object','Optional','Integer','Array'];D=function(){return X;};return D();}export const identifier=Type[d(0x179)]({'minLength':0x1,'maxLength':0x80,'pattern':d(0x17a)});export const resourceSchemas={'dictionaryName':Type['Object']({'name':identifier}),'resource':Type['Object']({'resource':identifier}),'exportResource':Type['Object']({'resource':identifier}),'resourceField':Type[d(0x17b)]({'resource':identifier,'field':identifier}),'suggestQuery':Type['Object']({'q':Type['Optional'](Type['String']()),'search':Type[d(0x17c)](Type['String']()),'limit':Type['Optional'](Type[d(0x17d)]({'minimum':0x1,'maximum':0xc8}))}),'resourceId':Type['Object']({'resource':identifier,'id':identifier}),'resourceIncludeQuery':Type[d(0x17b)]({'include':Type['Optional'](Type['String']({'minLength':0x1}))}),'resourceIdRelation':Type['Object']({'resource':identifier,'id':identifier,'relation':identifier}),'resourceIdRelationId':Type['Object']({'resource':identifier,'id':identifier,'relation':identifier,'relationId':identifier}),'uploadResourceFile':Type['Object']({'resource':identifier,'id':identifier}),'uploadResourceFileBody':Type[d(0x17b)]({'file':Type['Any'](),'fileName':Type[d(0x179)]({'minLength':0x1,'maxLength':0xff})}),'exportResourceQuery':Type['Object']({'filter':Type[d(0x17c)](Type['Record'](Type['String'](),Type['Unknown']())),'sort':Type['Optional'](Type['Array'](Type['String']({'minLength':0x1}))),'search':Type[d(0x17c)](Type['String']()),'limit':Type['Optional'](Type[d(0x17d)]({'minimum':0x1,'maximum':0xc8})),'offset':Type['Optional'](Type['Integer']({'minimum':0x0})),'fields':Type['Optional'](Type[d(0x17e)](identifier))})};
1
+ const L=O;function Z(){const E=['Object','String','Optional','Integer','Record'];Z=function(){return E;};return Z();}import{Type}from'@sinclair/typebox';export const identifier=Type['String']({'minLength':0x1,'maxLength':0x80,'pattern':'^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$'});function O(L,E){L=L-0x6f;const c=Z();let t=c[L];return t;}export const resourceSchemas={'dictionaryName':Type[L(0x6f)]({'name':identifier}),'resource':Type['Object']({'resource':identifier}),'exportResource':Type[L(0x6f)]({'resource':identifier}),'resourceField':Type[L(0x6f)]({'resource':identifier,'field':identifier}),'suggestQuery':Type[L(0x6f)]({'q':Type['Optional'](Type[L(0x70)]()),'search':Type[L(0x71)](Type['String']()),'limit':Type['Optional'](Type[L(0x72)]({'minimum':0x1,'maximum':0xc8}))}),'resourceId':Type['Object']({'resource':identifier,'id':identifier}),'resourceIncludeQuery':Type['Object']({'include':Type['Optional'](Type[L(0x70)]({'minLength':0x1}))}),'resourceIdRelation':Type[L(0x6f)]({'resource':identifier,'id':identifier,'relation':identifier}),'resourceIdRelationId':Type['Object']({'resource':identifier,'id':identifier,'relation':identifier,'relationId':identifier}),'uploadResourceFile':Type['Object']({'resource':identifier,'id':identifier}),'uploadResourceFileBody':Type[L(0x6f)]({'file':Type['Any'](),'fileName':Type[L(0x70)]({'minLength':0x1,'maxLength':0xff})}),'exportResourceQuery':Type['Object']({'filter':Type['Optional'](Type[L(0x73)](Type['String'](),Type['Unknown']())),'sort':Type[L(0x71)](Type['Array'](Type['String']({'minLength':0x1}))),'search':Type[L(0x71)](Type[L(0x70)]()),'limit':Type[L(0x71)](Type[L(0x72)]({'minimum':0x1,'maximum':0xc8})),'offset':Type['Optional'](Type[L(0x72)]({'minimum':0x0})),'fields':Type['Optional'](Type['Array'](identifier))})};
@@ -1 +1 @@
1
- export async function addNote(d,X){const a=p,F=await X['pg'][a(0xc7)]('INSERT\x20INTO\x20admin.notes(resource,resource_id,body)\x20VALUES\x20($1,$2,$3)\x20RETURNING\x20*',[d['resource'],String(d['id']),d['body']]);return F['rows'][0x0];}function p(d,X){d=d-0xc7;const F=D();let a=F[d];return a;}function D(){const s=['query'];D=function(){return s;};return D();}
1
+ function O(L,E){L=L-0xb7;const c=Z();let t=c[L];return t;}function Z(){const e=['query','INSERT\x20INTO\x20admin.notes(resource,resource_id,body)\x20VALUES\x20($1,$2,$3)\x20RETURNING\x20*','resource','rows'];Z=function(){return e;};return Z();}export async function addNote(L,E){const t=O,c=await E['pg'][t(0xb7)](t(0xb8),[L[t(0xb9)],String(L['id']),L['body']]);return c[t(0xba)][0x0];}
@@ -1 +1 @@
1
- export async function addResourceFile(d,X){const a=p,F=await X['pg'][a(0x1d5)]('\x0a\x20\x20\x20\x20\x20\x20\x20\x20INSERT\x20INTO\x20admin.files\x20(resource,\x20resource_id,\x20file_path,\x20size)\x0a\x20\x20\x20\x20\x20\x20\x20\x20VALUES\x20($1,\x20$2,\x20$3,\x20$4)\x0a\x20\x20\x20\x20\x20\x20\x20\x20RETURNING\x20*\x0a\x20\x20\x20\x20\x20\x20',[d[a(0x1d6)],String(d['id']),d[a(0x1d7)],d[a(0x1d8)]??null]);return F[a(0x1d9)][0x0];}function p(d,X){d=d-0x1d5;const F=D();let a=F[d];return a;}function D(){const s=['query','resource','filePath','size','rows'];D=function(){return s;};return D();}
1
+ function O(L,E){L=L-0xd3;const c=Z();let t=c[L];return t;}function Z(){const e=['filePath'];Z=function(){return e;};return Z();}export async function addResourceFile(L,E){const t=O,c=await E['pg']['query']('\x0a\x20\x20\x20\x20\x20\x20\x20\x20INSERT\x20INTO\x20admin.files\x20(resource,\x20resource_id,\x20file_path,\x20size)\x0a\x20\x20\x20\x20\x20\x20\x20\x20VALUES\x20($1,\x20$2,\x20$3,\x20$4)\x0a\x20\x20\x20\x20\x20\x20\x20\x20RETURNING\x20*\x0a\x20\x20\x20\x20\x20\x20',[L['resource'],String(L['id']),L[t(0xd3)],L['size']??null]);return c['rows'][0x0];}
@@ -1 +1 @@
1
- function D(){const f=['resource'];D=function(){return f;};return D();}function p(d,X){d=d-0x6a;const F=D();let a=F[d];return a;}export async function createResourceRelation(d,X){const q=p,{resource:F,id:a,relation:s,data:y,user:k}=d;return X[q(0x6a)]['createRelation']({'name':F,'id':a,'relation':s,'data':y,'user':k});}
1
+ export async function createResourceRelation(L,E){const r=O,{resource:c,id:t,relation:e,data:B,user:g}=L;return E[r(0x1f1)]['createRelation']({'name':c,'id':t,'relation':e,'data':B,'user':g});}function O(L,E){L=L-0x1f1;const c=Z();let t=c[L];return t;}function Z(){const X=['resource'];Z=function(){return X;};return Z();}
@@ -1 +1 @@
1
- export async function createResource(d,X){return X['resource']['create']({'name':d['resource'],'data':d['data'],'user':d['user']});}
1
+ export async function createResource(L,E){return E['resource']['create']({'name':L['resource'],'data':L['data'],'user':L['user']});}
@@ -1 +1 @@
1
- export async function deleteResourceRelation(d,X){const {resource:F,id:a,relation:s,relationId:y}=d;return X['resource']['deleteRelation']({'name':F,'id':a,'relation':s,'relationId':y});}
1
+ function O(L,E){L=L-0x15f;const c=Z();let t=c[L];return t;}export async function deleteResourceRelation(L,E){const g=O,{resource:c,id:t,relation:e,relationId:B}=L;return E[g(0x15f)]['deleteRelation']({'name':c,'id':t,'relation':e,'relationId':B});}function Z(){const r=['resource'];Z=function(){return r;};return Z();}
@@ -1 +1 @@
1
- export async function deleteResource(d,X){return X['resource']['delete']({'name':d['resource'],'id':d['id'],'user':d['user']});}
1
+ export async function deleteResource(L,E){return E['resource']['delete']({'name':L['resource'],'id':L['id'],'user':L['user']});}
@@ -1 +1 @@
1
- function D(){const s=['resource','find','sort'];D=function(){return s;};return D();}function p(d,X){d=d-0x1e8;const F=D();let a=F[d];return a;}import{parseFilterQuery}from'../../../plugins/resource/utils/filters.js';export async function exportResource(d,X){const a=p,F=await X[a(0x1e8)][a(0x1e9)]({'name':d['resource'],'query':{'filter':parseFilterQuery(d),'sort':d[a(0x1ea)],'search':d['search'],'limit':d['limit'],'offset':d['offset'],'fields':d['fields']},'user':d['user']});return F['rows'];}
1
+ function Z(){const e=['find','resource','search','rows'];Z=function(){return e;};return Z();}function O(L,E){L=L-0x1e1;const c=Z();let t=c[L];return t;}import{parseFilterQuery}from'../../../plugins/resource/utils/filters.js';export async function exportResource(L,E){const t=O,c=await E['resource'][t(0x1e1)]({'name':L[t(0x1e2)],'query':{'filter':parseFilterQuery(L),'sort':L['sort'],'search':L[t(0x1e3)],'limit':L['limit'],'offset':L['offset'],'fields':L['fields']},'user':L['user']});return c[t(0x1e4)];}
@@ -1 +1 @@
1
- function p(d,X){d=d-0x100;var F=D();var a=F[d];return a;}export async function getResource(d,X){var F=p;return X['resource'][F(0x100)]({'name':d['resource'],'id':d['id'],'query':{'include':d['include']},'user':d['user']});}function D(){var a=['findOne'];D=function(){return a;};return D();}
1
+ function O(L,E){L=L-0x1b1;var c=Z();var t=c[L];return t;}export async function getResource(L,E){var c=O;return E['resource']['findOne']({'name':L['resource'],'id':L['id'],'query':{'include':L[c(0x1b1)]},'user':L['user']});}function Z(){var t=['include'];Z=function(){return t;};return Z();}
@@ -1 +1 @@
1
- export async function listResourceRelation(d,X){const q=p,{resource:F,id:a,relation:s,query:y,user:k}=d;return X[q(0x161)]['findRelation']({'name':F,'id':a,'relation':s,'query':y,'user':k});}function p(d,X){d=d-0x161;const F=D();let a=F[d];return a;}function D(){const f=['resource'];D=function(){return f;};return D();}
1
+ export async function listResourceRelation(L,E){const {resource:c,id:t,relation:e,query:B,user:g}=L;return E['resource']['findRelation']({'name':c,'id':t,'relation':e,'query':B,'user':g});}
@@ -1 +1 @@
1
- import{parseFilterQuery}from'../../../plugins/resource/utils/filters.js';export async function listResources(d,X){var F=p;return X['resource']['find']({'name':d['resource'],'query':{'filter':parseFilterQuery(d),'sort':d[F(0x1c6)],'search':d[F(0x1c7)],'limit':d['limit'],'offset':d['offset']??(d['page']?Math['max'](d['page']-0x1,0x0):0x0)*(d['limit']??0x14)},'user':d['user']});}function p(d,X){d=d-0x1c6;var F=D();var a=F[d];return a;}function D(){var a=['sort','search'];D=function(){return a;};return D();}
1
+ import{parseFilterQuery}from'../../../plugins/resource/utils/filters.js';export async function listResources(L,E){var c=O;return E['resource']['find']({'name':L['resource'],'query':{'filter':parseFilterQuery(L),'sort':L['sort'],'search':L[c(0x1e3)],'limit':L['limit'],'offset':L['offset']??(L['page']?Math['max'](L['page']-0x1,0x0):0x0)*(L['limit']??0x14)},'user':L['user']});}function O(L,E){L=L-0x1e3;var c=Z();var t=c[L];return t;}function Z(){var t=['search'];Z=function(){return t;};return Z();}
@@ -1 +1 @@
1
- function D(){var a=['find'];D=function(){return a;};return D();}function p(d,X){d=d-0x198;var F=D();var a=F[d];return a;}import{parseFilterQuery}from'../../../plugins/resource/utils/filters.js';export async function searchResource(d,X){var F=p;return X['resource'][F(0x198)]({'name':d['resource'],'query':{...d,'filter':parseFilterQuery(d)},'user':d['user']});}
1
+ function O(L,E){L=L-0x1ab;var c=Z();var t=c[L];return t;}function Z(){var t=['resource'];Z=function(){return t;};return Z();}import{parseFilterQuery}from'../../../plugins/resource/utils/filters.js';export async function searchResource(L,E){var c=O;return E[c(0x1ab)]['find']({'name':L[c(0x1ab)],'query':{...L,'filter':parseFilterQuery(L)},'user':L['user']});}
@@ -1 +1 @@
1
- import{ValidationError}from'../../../errors.js';function p(d,X){d=d-0x19c;const F=D();let a=F[d];return a;}import{autoIndex}from'../../../plugins/resource/utils/auto-index.js';function D(){const J=['min','now','lookup','value','text','\x20as\x20id,\x20','\x20WHERE\x20lower(','length','get','slice','code'];D=function(){return J;};return D();}export async function suggestResource(d,X){const v=p,F=X['resource']['get'](d['resource']),a=String(d['search']??d['q']??'')['toLowerCase'](),s=Math[v(0x19c)](Math['max'](Number(d['limit']??0x14),0x1),0xc8),y=Date[v(0x19d)](),k=F['fields'][d['field']],q=k?.['dictionary'],f=k?.['lookup']?.['table'];if(f){const H=k[v(0x19e)]?.['text']??'name',T=k[v(0x19e)]?.[v(0x19f)]??'id';autoIndex(f,H,v(0x1a0),X['pg']);const W=await X['pg']['query']('SELECT\x20'+T+v(0x1a1)+H+'\x20as\x20text\x20FROM\x20'+f+v(0x1a2)+H+')\x20~\x20$1\x20LIMIT\x20$2',[''+a['toLowerCase'](),s])['then'](P=>P['rows']);return{'limit':s,'count':W[v(0x1a3)],'search':a,'time':Date['now']()-y,'data':W};}if(!q)throw new ValidationError('Field\x20has\x20no\x20lookup\x20dictionary:\x20'+d['field']);const G=await X['dictionary'][v(0x1a4)](q),b=G['filter'](P=>!a||P['code']['startsWith'](a)||P['name']['startsWith'](a))[v(0x1a5)](0x0,s)['map'](P=>({'id':P[v(0x1a6)]||P['id'],'text':P['name']||P[v(0x1a0)]}));return{'search':a,'limit':s,'count':b['length'],'time':Date[v(0x19d)]()-y,'data':b};}
1
+ import{ValidationError}from'../../../errors.js';function O(L,E){L=L-0x1ad;const c=Z();let t=c[L];return t;}import{autoIndex}from'../../../plugins/resource/utils/auto-index.js';export async function suggestResource(L,E){const G=O,c=E['resource']['get'](L['resource']),t=String(L['search']??L['q']??'')['toLowerCase'](),e=Math['min'](Math['max'](Number(L[G(0x1ad)]??0x14),0x1),0xc8),B=Date['now'](),g=c['fields'][L['field']],r=g?.['dictionary'],X=g?.['lookup']?.[G(0x1ae)];if(X){const I=g[G(0x1af)]?.['text']??'name',T=g['lookup']?.['value']??'id';autoIndex(X,I,G(0x1b0),E['pg']);const f=await E['pg']['query'](G(0x1b1)+T+G(0x1b2)+I+'\x20as\x20text\x20FROM\x20'+X+'\x20WHERE\x20lower('+I+G(0x1b3),[''+t['toLowerCase'](),e])['then'](A=>A['rows']);return{'limit':e,'count':f['length'],'search':t,'time':Date['now']()-B,'data':f};}if(!r)throw new ValidationError('Field\x20has\x20no\x20lookup\x20dictionary:\x20'+L['field']);const j=await E['dictionary']['get'](r),F=j['filter'](A=>!t||A['code']['startsWith'](t)||A['name']['startsWith'](t))['slice'](0x0,e)['map'](A=>({'id':A['code']||A['id'],'text':A['name']||A['text']}));return{'search':t,'limit':e,'count':F[G(0x1b4)],'time':Date['now']()-B,'data':F};}function Z(){const x=['limit','table','lookup','text','SELECT\x20','\x20as\x20id,\x20',')\x20~\x20$1\x20LIMIT\x20$2','length'];Z=function(){return x;};return Z();}
@@ -1 +1 @@
1
- function p(d,X){d=d-0x96;const F=D();let a=F[d];return a;}function D(){const G=['updateRelation'];D=function(){return G;};return D();}export async function updateResourceRelation(d,X){const f=p,{resource:F,id:a,relation:s,relationId:y,data:k,user:q}=d;return X['resource'][f(0x96)]({'name':F,'id':a,'relation':s,'relationId':y,'data':k,'user':q});}
1
+ export async function updateResourceRelation(L,E){const X=O,{resource:c,id:t,relation:e,relationId:B,data:g,user:r}=L;return E[X(0x11c)]['updateRelation']({'name':c,'id':t,'relation':e,'relationId':B,'data':g,'user':r});}function O(L,E){L=L-0x11c;const c=Z();let t=c[L];return t;}function Z(){const j=['resource'];Z=function(){return j;};return Z();}
@@ -1 +1 @@
1
- function D(){var a=['resource','update'];D=function(){return a;};return D();}function p(d,X){d=d-0x16f;var F=D();var a=F[d];return a;}export async function updateResource(d,X){var F=p;return X[F(0x16f)][F(0x170)]({'name':d[F(0x16f)],'id':d['id'],'data':d['patch'],'user':d['user']});}
1
+ export async function updateResource(L,E){var c=O;return E['resource'][c(0xb2)]({'name':L['resource'],'id':L['id'],'data':L['patch'],'user':L[c(0xb3)]});}function O(L,E){L=L-0xb2;var c=Z();var t=c[L];return t;}function Z(){var t=['update','user'];Z=function(){return t;};return Z();}
@@ -1 +1 @@
1
- function D(){const q=['admin','includes','File\x20is\x20required','replace','resource','Uploaded\x20file\x20not\x20found','\x0a\x20\x20\x20\x20\x20\x20\x20\x20INSERT\x20INTO\x20admin.files\x20(resource,\x20resource_id,\x20file_path,\x20size)\x0a\x20\x20\x20\x20\x20\x20\x20\x20VALUES\x20($1,\x20$2,\x20$3,\x20$4)\x0a\x20\x20\x20\x20\x20\x20\x20\x20RETURNING\x20*\x0a\x20\x20\x20\x20'];D=function(){return q;};return D();}import{ForbiddenError,NotFoundError,ValidationError}from'../../../errors.js';function p(d,X){d=d-0x1aa;const F=D();let a=F[d];return a;}export async function uploadResourceFile(d,X){const k=p,F=X['resource']['get'](d['resource']);if(F['access']===k(0x1aa)&&d['user']?.['type']!==k(0x1aa))throw new ForbiddenError('Admin\x20access\x20required');if(d['user']?.['type']!=='admin'&&!d['user']?.['permissions']?.[k(0x1ab)]((F['permission']??F['name'])+':update'))throw new ForbiddenError('Missing\x20permission:\x20'+(F['permission']??F['name'])+':update');if(!Buffer['isBuffer'](d['file'])||d['file']['length']===0x0)throw new ValidationError(k(0x1ac));const a=d['fileName'][k(0x1ad)](/[^A-Za-z0-9._-]/g,'_');if(!a)throw new ValidationError('File\x20name\x20is\x20required');const s='files/'+d[k(0x1ae)]+'/'+String(d['id'])+'/'+a;await X['file']['put'](s,d['file']);if(!await X['file']['exists'](s))throw new NotFoundError(k(0x1af));const y=await X['pg']['query'](k(0x1b0),[d[k(0x1ae)],String(d['id']),s,d['file']['length']]);return y['rows'][0x0];}
1
+ function O(L,E){L=L-0x103;const c=Z();let t=c[L];return t;}import{ForbiddenError,NotFoundError,ValidationError}from'../../../errors.js';function Z(){const r=['resource','get','admin','user','type','Admin\x20access\x20required','put','Uploaded\x20file\x20not\x20found'];Z=function(){return r;};return Z();}export async function uploadResourceFile(L,E){const g=O,c=E[g(0x103)][g(0x104)](L['resource']);if(c['access']===g(0x105)&&L[g(0x106)]?.[g(0x107)]!=='admin')throw new ForbiddenError(g(0x108));if(L['user']?.[g(0x107)]!=='admin'&&!L[g(0x106)]?.['permissions']?.['includes']((c['permission']??c['name'])+':update'))throw new ForbiddenError('Missing\x20permission:\x20'+(c['permission']??c['name'])+':update');if(!Buffer['isBuffer'](L['file'])||L['file']['length']===0x0)throw new ValidationError('File\x20is\x20required');const t=L['fileName']['replace'](/[^A-Za-z0-9._-]/g,'_');if(!t)throw new ValidationError('File\x20name\x20is\x20required');const e='files/'+L['resource']+'/'+String(L['id'])+'/'+t;await E['file'][g(0x109)](e,L['file']);if(!await E['file']['exists'](e))throw new NotFoundError(g(0x10a));const B=await E['pg']['query']('\x0a\x20\x20\x20\x20\x20\x20\x20\x20INSERT\x20INTO\x20admin.files\x20(resource,\x20resource_id,\x20file_path,\x20size)\x0a\x20\x20\x20\x20\x20\x20\x20\x20VALUES\x20($1,\x20$2,\x20$3,\x20$4)\x0a\x20\x20\x20\x20\x20\x20\x20\x20RETURNING\x20*\x0a\x20\x20\x20\x20',[L['resource'],String(L['id']),e,L['file']['length']]);return B['rows'][0x0];}