@verdaccio/hooks 9.0.0-next-9.21 → 9.0.0-next-9.22
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.
- package/build/notify-request.d.ts +1 -1
- package/build/notify-request.js +1 -0
- package/build/notify-request.js.map +1 -1
- package/build/notify-request.mjs +1 -1
- package/build/notify.d.ts +1 -1
- package/build/notify.js +1 -0
- package/build/notify.js.map +1 -1
- package/build/notify.mjs +1 -1
- package/build/notify.mjs.map +1 -1
- package/package.json +8 -8
package/build/notify-request.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notify-request.js","names":[],"sources":["../src/notify-request.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport type { Method } from 'got';\nimport got from 'got';\n\nimport { HTTP_STATUS } from '@verdaccio/core';\nimport { logger } from '@verdaccio/logger';\n\nconst debug = buildDebug('verdaccio:hooks:request');\n\nexport type FetchOptions = {\n body: string;\n headers?: {};\n method?: string;\n};\n\nexport function verifyMethod(value: any): Method {\n const valid: Method[] = ['GET', 'POST', 'PUT'];\n\n if (typeof value === 'string') {\n const upper = value.toUpperCase() as Method;\n\n if (valid.includes(upper)) {\n return upper;\n } else {\n logger.warn(\n { method: value },\n 'The notification method @{method} is not valid, using default POST method'\n );\n }\n }\n\n return 'POST';\n}\n\nconst baseHeaders = { 'Content-Type': 'application/json' };\nexport async function notifyRequest(url: string, options: FetchOptions): Promise<boolean> {\n let response;\n try {\n const method: Method = verifyMethod(options.method);\n debug('uri %o', url);\n debug('headers %o', options.headers);\n debug('method %o', method);\n\n let userHeaders: Record<string, any> = {};\n\n if (options.headers) {\n if (typeof options.headers === 'string') {\n userHeaders = JSON.parse(options.headers);\n } else if (typeof options.headers === 'object') {\n userHeaders = options.headers;\n }\n }\n\n const headers = { ...baseHeaders, ...userHeaders };\n const requestOptions: any = {\n method,\n headers,\n };\n\n let finalUrl = url;\n if (method === 'GET') {\n debug('using GET with query params');\n const urlObj = new URL(url);\n const params = new URLSearchParams(options.body);\n params.set('body', options.body);\n urlObj.search = params.toString();\n finalUrl = urlObj.toString();\n debug('final url with search params %o', finalUrl);\n } else if (options.body !== undefined) {\n requestOptions.body = options.body;\n } else {\n throw new Error('Notification body is undefined');\n }\n\n response = await got(finalUrl, {\n ...requestOptions,\n responseType: 'json',\n });\n\n const body = await response.body;\n debug('response.status %o', body.statusCode);\n\n if (body.statusCode >= HTTP_STATUS.BAD_REQUEST) {\n throw new Error(body);\n }\n\n logger.info(\n { content: options.body },\n 'The notification @{content} has been successfully dispatched'\n );\n return true;\n } catch (err: any) {\n debug('request error %o:', err?.message);\n logger.error(\n { errorMessage: err?.message },\n 'notify service has thrown an error: @{errorMessage}'\n );\n return false;\n }\n}\n"],"mappings":";;;;;;;;AAOA,IAAM,WAAA,GAAA,MAAA,
|
|
1
|
+
{"version":3,"file":"notify-request.js","names":[],"sources":["../src/notify-request.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport type { Method } from 'got';\nimport got from 'got';\n\nimport { HTTP_STATUS } from '@verdaccio/core';\nimport { logger } from '@verdaccio/logger';\n\nconst debug = buildDebug('verdaccio:hooks:request');\n\nexport type FetchOptions = {\n body: string;\n headers?: {};\n method?: string;\n};\n\nexport function verifyMethod(value: any): Method {\n const valid: Method[] = ['GET', 'POST', 'PUT'];\n\n if (typeof value === 'string') {\n const upper = value.toUpperCase() as Method;\n\n if (valid.includes(upper)) {\n return upper;\n } else {\n logger.warn(\n { method: value },\n 'The notification method @{method} is not valid, using default POST method'\n );\n }\n }\n\n return 'POST';\n}\n\nconst baseHeaders = { 'Content-Type': 'application/json' };\nexport async function notifyRequest(url: string, options: FetchOptions): Promise<boolean> {\n let response;\n try {\n const method: Method = verifyMethod(options.method);\n debug('uri %o', url);\n debug('headers %o', options.headers);\n debug('method %o', method);\n\n let userHeaders: Record<string, any> = {};\n\n if (options.headers) {\n if (typeof options.headers === 'string') {\n userHeaders = JSON.parse(options.headers);\n } else if (typeof options.headers === 'object') {\n userHeaders = options.headers;\n }\n }\n\n const headers = { ...baseHeaders, ...userHeaders };\n const requestOptions: any = {\n method,\n headers,\n };\n\n let finalUrl = url;\n if (method === 'GET') {\n debug('using GET with query params');\n const urlObj = new URL(url);\n const params = new URLSearchParams(options.body);\n params.set('body', options.body);\n urlObj.search = params.toString();\n finalUrl = urlObj.toString();\n debug('final url with search params %o', finalUrl);\n } else if (options.body !== undefined) {\n requestOptions.body = options.body;\n } else {\n throw new Error('Notification body is undefined');\n }\n\n response = await got(finalUrl, {\n ...requestOptions,\n responseType: 'json',\n });\n\n const body = await response.body;\n debug('response.status %o', body.statusCode);\n\n if (body.statusCode >= HTTP_STATUS.BAD_REQUEST) {\n throw new Error(body);\n }\n\n logger.info(\n { content: options.body },\n 'The notification @{content} has been successfully dispatched'\n );\n return true;\n } catch (err: any) {\n debug('request error %o:', err?.message);\n logger.error(\n { errorMessage: err?.message },\n 'notify service has thrown an error: @{errorMessage}'\n );\n return false;\n }\n}\n"],"mappings":";;;;;;;;AAOA,IAAM,WAAA,GAAA,MAAA,QAAA,CAAmB,yBAAyB;AAQlD,SAAgB,aAAa,OAAoB;CAC/C,MAAM,QAAkB;EAAC;EAAO;EAAQ;CAAK;CAE7C,IAAI,OAAO,UAAU,UAAU;EAC7B,MAAM,QAAQ,MAAM,YAAY;EAEhC,IAAI,MAAM,SAAS,KAAK,GACtB,OAAO;OAEP,kBAAA,OAAO,KACL,EAAE,QAAQ,MAAM,GAChB,2EACF;CAEJ;CAEA,OAAO;AACT;AAEA,IAAM,cAAc,EAAE,gBAAgB,mBAAmB;AACzD,eAAsB,cAAc,KAAa,SAAyC;CACxF,IAAI;CACJ,IAAI;EACF,MAAM,SAAiB,aAAa,QAAQ,MAAM;EAClD,QAAM,UAAU,GAAG;EACnB,QAAM,cAAc,QAAQ,OAAO;EACnC,QAAM,aAAa,MAAM;EAEzB,IAAI,cAAmC,CAAC;EAExC,IAAI,QAAQ;OACN,OAAO,QAAQ,YAAY,UAC7B,cAAc,KAAK,MAAM,QAAQ,OAAO;QACnC,IAAI,OAAO,QAAQ,YAAY,UACpC,cAAc,QAAQ;EAAA;EAK1B,MAAM,iBAAsB;GAC1B;GACA,SAAA;IAHgB,GAAG;IAAa,GAAG;GAGnC;EACF;EAEA,IAAI,WAAW;EACf,IAAI,WAAW,OAAO;GACpB,QAAM,6BAA6B;GACnC,MAAM,SAAS,IAAI,IAAI,GAAG;GAC1B,MAAM,SAAS,IAAI,gBAAgB,QAAQ,IAAI;GAC/C,OAAO,IAAI,QAAQ,QAAQ,IAAI;GAC/B,OAAO,SAAS,OAAO,SAAS;GAChC,WAAW,OAAO,SAAS;GAC3B,QAAM,mCAAmC,QAAQ;EACnD,OAAO,IAAI,QAAQ,SAAS,KAAA,GAC1B,eAAe,OAAO,QAAQ;OAE9B,MAAM,IAAI,MAAM,gCAAgC;EAGlD,WAAW,OAAA,GAAA,IAAA,QAAA,CAAU,UAAU;GAC7B,GAAG;GACH,cAAc;EAChB,CAAC;EAED,MAAM,OAAO,MAAM,SAAS;EAC5B,QAAM,sBAAsB,KAAK,UAAU;EAE3C,IAAI,KAAK,cAAc,gBAAA,YAAY,aACjC,MAAM,IAAI,MAAM,IAAI;EAGtB,kBAAA,OAAO,KACL,EAAE,SAAS,QAAQ,KAAK,GACxB,8DACF;EACA,OAAO;CACT,SAAS,KAAU;EACjB,QAAM,qBAAqB,KAAK,OAAO;EACvC,kBAAA,OAAO,MACL,EAAE,cAAc,KAAK,QAAQ,GAC7B,qDACF;EACA,OAAO;CACT;AACF"}
|
package/build/notify-request.mjs
CHANGED
package/build/notify.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Config, Manifest, Notification, RemoteUser } from '@verdaccio/types';
|
|
1
|
+
import type { Config, Manifest, Notification, RemoteUser } from '@verdaccio/types';
|
|
2
2
|
export declare function compileTemplate(content: any, metadata: any): Promise<unknown>;
|
|
3
3
|
export declare function handleNotify(metadata: Partial<Manifest>, notifyEntry: any, remoteUser: Partial<RemoteUser>, publishedPackage: string, publishType?: string): Promise<boolean>;
|
|
4
4
|
export declare function sendNotification(metadata: Partial<Manifest>, notify: Notification, remoteUser: Partial<RemoteUser>, publishedPackage: string, publishType?: string): Promise<boolean>;
|
package/build/notify.js
CHANGED
|
@@ -104,6 +104,7 @@ async function notify(metadata, config, remoteUser, publishedPackage, publishTyp
|
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
//#endregion
|
|
107
|
+
exports.compileTemplate = compileTemplate;
|
|
107
108
|
exports.handleNotify = handleNotify;
|
|
108
109
|
exports.notify = notify;
|
|
109
110
|
exports.sendNotification = sendNotification;
|
package/build/notify.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notify.js","names":[],"sources":["../src/notify.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport Handlebars from 'handlebars';\n\nimport { logger } from '@verdaccio/logger';\nimport type { Config, Manifest, Notification, RemoteUser } from '@verdaccio/types';\n\nimport type { FetchOptions } from './notify-request';\nimport { notifyRequest } from './notify-request';\n\nconst debug = buildDebug('verdaccio:hooks');\n\nexport function compileTemplate(content, metadata) {\n // FUTURE: multiple handlers\n return new Promise((resolve, reject) => {\n // eslint-disable-next-line no-unassigned-vars\n let handler;\n try {\n if (!handler) {\n debug('compile default template handler %o', content);\n const template: HandlebarsTemplateDelegate = Handlebars.compile(content);\n return resolve(template(metadata));\n }\n } catch (error: any) {\n debug('error template handler %o', error?.message);\n logger.error(\n { error: error.message },\n 'notification template compilation has failed: @{error}'\n );\n reject(error);\n }\n });\n}\n\nexport async function handleNotify(\n metadata: Partial<Manifest>,\n notifyEntry,\n remoteUser: Partial<RemoteUser>,\n publishedPackage: string,\n publishType?: string\n): Promise<boolean> {\n let regex;\n try {\n if (metadata.name && notifyEntry.packagePattern) {\n debug('checking package pattern %o', notifyEntry.packagePattern);\n debug('checking package pattern flags %o', notifyEntry.packagePatternFlags);\n regex = new RegExp(notifyEntry.packagePattern, notifyEntry.packagePatternFlags ?? '');\n if (!regex.test(metadata.name)) {\n logger.debug('Notification exclude does not match %o', metadata.name);\n return false;\n }\n debug('package pattern matched %o', metadata.name);\n }\n } catch (error: any) {\n logger.error('Invalid regex pattern or flags: %o', error?.message);\n return false;\n }\n\n const publishMetadata = {\n ...metadata,\n ...(typeof metadata.publisher === 'undefined' || metadata.publisher === null\n ? {\n // only expose the documented publisher fields, never the full remote\n // user object (it may carry the auth token, which must not leak to the\n // notification endpoint)\n publisher: {\n name: remoteUser.name,\n groups: remoteUser.groups,\n real_groups: remoteUser.real_groups,\n },\n }\n : {}),\n publishedPackage,\n publishType,\n };\n debug('template metadata %o', publishMetadata);\n const content = (await compileTemplate(notifyEntry.content, publishMetadata)) as string;\n\n const options: FetchOptions = {\n body: content,\n };\n\n // provides fallback support, it's accept an Object {} and Array of {}\n if (notifyEntry.headers && Array.isArray(notifyEntry.headers)) {\n const header = {};\n notifyEntry.headers.forEach((item): void => {\n if (item && typeof item === 'object') {\n Object.assign(header, item);\n }\n });\n options.headers = header;\n } else if (Object.is(notifyEntry.headers, notifyEntry.headers)) {\n options.headers = notifyEntry.headers;\n }\n\n if (!notifyEntry.endpoint) {\n debug('error due endpoint is missing');\n throw new Error('missing parameter');\n }\n\n return notifyRequest(notifyEntry.endpoint, {\n method: notifyEntry.method,\n ...options,\n });\n}\n\nexport function sendNotification(\n metadata: Partial<Manifest>,\n notify: Notification,\n remoteUser: Partial<RemoteUser>,\n publishedPackage: string,\n publishType?: string\n): Promise<boolean> {\n return handleNotify(metadata, notify, remoteUser, publishedPackage, publishType) as Promise<any>;\n}\n\nfunction isHasNotification(value: any): value is Notification {\n return value && typeof value === 'object' && 'endpoint' in value && 'content' in value;\n}\n\nexport async function notify(\n metadata: Partial<Manifest>,\n config: Config,\n remoteUser: RemoteUser,\n publishedPackage: string,\n publishType?: string\n): Promise<boolean[]> {\n debug('init send notification');\n const notification = config?.notify;\n if (!notification) {\n debug('no notify configuration detected');\n return [false];\n }\n\n const isSingle = isHasNotification(notification);\n debug('is single notify %o', isSingle);\n if (isSingle) {\n debug('send single notification');\n try {\n const response = await sendNotification(\n metadata,\n config.notify as Notification,\n remoteUser,\n publishedPackage,\n publishType\n );\n return [response];\n } catch {\n debug('error on sending single notification');\n return [false];\n }\n } else {\n try {\n debug('send multiples notification');\n const notificationEntries = Object.entries(notification).filter(([, item]) =>\n isHasNotification(item)\n );\n debug('valid notification entries %o', notificationEntries.length);\n if (notificationEntries.length === 0) {\n // No valid notifications, return false for each entry\n return Object.keys(notification).map(() => false);\n }\n debug('sending %o notifications', notificationEntries.length);\n const results = await Promise.allSettled(\n notificationEntries.map(([, item]) =>\n sendNotification(metadata, item, remoteUser, publishedPackage, publishType)\n )\n ).catch((error) => {\n logger.error({ error }, 'notify request has failed: @error');\n });\n if (!results) {\n return [];\n }\n return results.map((result) => (result.status === 'fulfilled' ? result.value : false));\n } catch (error) {\n debug('error on sending multiple notification %o', error);\n return Object.keys(notification).map(() => false);\n }\n }\n}\n"],"mappings":";;;;;;;;AASA,IAAM,WAAA,GAAA,MAAA,
|
|
1
|
+
{"version":3,"file":"notify.js","names":[],"sources":["../src/notify.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport Handlebars from 'handlebars';\n\nimport { logger } from '@verdaccio/logger';\nimport type { Config, Manifest, Notification, RemoteUser } from '@verdaccio/types';\n\nimport type { FetchOptions } from './notify-request';\nimport { notifyRequest } from './notify-request';\n\nconst debug = buildDebug('verdaccio:hooks');\n\nexport function compileTemplate(content, metadata) {\n // FUTURE: multiple handlers\n return new Promise((resolve, reject) => {\n // eslint-disable-next-line no-unassigned-vars\n let handler;\n try {\n if (!handler) {\n debug('compile default template handler %o', content);\n const template: HandlebarsTemplateDelegate = Handlebars.compile(content);\n return resolve(template(metadata));\n }\n } catch (error: any) {\n debug('error template handler %o', error?.message);\n logger.error(\n { error: error.message },\n 'notification template compilation has failed: @{error}'\n );\n reject(error);\n }\n });\n}\n\nexport async function handleNotify(\n metadata: Partial<Manifest>,\n notifyEntry,\n remoteUser: Partial<RemoteUser>,\n publishedPackage: string,\n publishType?: string\n): Promise<boolean> {\n let regex;\n try {\n if (metadata.name && notifyEntry.packagePattern) {\n debug('checking package pattern %o', notifyEntry.packagePattern);\n debug('checking package pattern flags %o', notifyEntry.packagePatternFlags);\n regex = new RegExp(notifyEntry.packagePattern, notifyEntry.packagePatternFlags ?? '');\n if (!regex.test(metadata.name)) {\n logger.debug('Notification exclude does not match %o', metadata.name);\n return false;\n }\n debug('package pattern matched %o', metadata.name);\n }\n } catch (error: any) {\n logger.error('Invalid regex pattern or flags: %o', error?.message);\n return false;\n }\n\n const publishMetadata = {\n ...metadata,\n ...(typeof metadata.publisher === 'undefined' || metadata.publisher === null\n ? {\n // only expose the documented publisher fields, never the full remote\n // user object (it may carry the auth token, which must not leak to the\n // notification endpoint)\n publisher: {\n name: remoteUser.name,\n groups: remoteUser.groups,\n real_groups: remoteUser.real_groups,\n },\n }\n : {}),\n publishedPackage,\n publishType,\n };\n debug('template metadata %o', publishMetadata);\n const content = (await compileTemplate(notifyEntry.content, publishMetadata)) as string;\n\n const options: FetchOptions = {\n body: content,\n };\n\n // provides fallback support, it's accept an Object {} and Array of {}\n if (notifyEntry.headers && Array.isArray(notifyEntry.headers)) {\n const header = {};\n notifyEntry.headers.forEach((item): void => {\n if (item && typeof item === 'object') {\n Object.assign(header, item);\n }\n });\n options.headers = header;\n } else if (Object.is(notifyEntry.headers, notifyEntry.headers)) {\n options.headers = notifyEntry.headers;\n }\n\n if (!notifyEntry.endpoint) {\n debug('error due endpoint is missing');\n throw new Error('missing parameter');\n }\n\n return notifyRequest(notifyEntry.endpoint, {\n method: notifyEntry.method,\n ...options,\n });\n}\n\nexport function sendNotification(\n metadata: Partial<Manifest>,\n notify: Notification,\n remoteUser: Partial<RemoteUser>,\n publishedPackage: string,\n publishType?: string\n): Promise<boolean> {\n return handleNotify(metadata, notify, remoteUser, publishedPackage, publishType) as Promise<any>;\n}\n\nfunction isHasNotification(value: any): value is Notification {\n return value && typeof value === 'object' && 'endpoint' in value && 'content' in value;\n}\n\nexport async function notify(\n metadata: Partial<Manifest>,\n config: Config,\n remoteUser: RemoteUser,\n publishedPackage: string,\n publishType?: string\n): Promise<boolean[]> {\n debug('init send notification');\n const notification = config?.notify;\n if (!notification) {\n debug('no notify configuration detected');\n return [false];\n }\n\n const isSingle = isHasNotification(notification);\n debug('is single notify %o', isSingle);\n if (isSingle) {\n debug('send single notification');\n try {\n const response = await sendNotification(\n metadata,\n config.notify as Notification,\n remoteUser,\n publishedPackage,\n publishType\n );\n return [response];\n } catch {\n debug('error on sending single notification');\n return [false];\n }\n } else {\n try {\n debug('send multiples notification');\n const notificationEntries = Object.entries(notification).filter(([, item]) =>\n isHasNotification(item)\n );\n debug('valid notification entries %o', notificationEntries.length);\n if (notificationEntries.length === 0) {\n // No valid notifications, return false for each entry\n return Object.keys(notification).map(() => false);\n }\n debug('sending %o notifications', notificationEntries.length);\n const results = await Promise.allSettled(\n notificationEntries.map(([, item]) =>\n sendNotification(metadata, item, remoteUser, publishedPackage, publishType)\n )\n ).catch((error) => {\n logger.error({ error }, 'notify request has failed: @error');\n });\n if (!results) {\n return [];\n }\n return results.map((result) => (result.status === 'fulfilled' ? result.value : false));\n } catch (error) {\n debug('error on sending multiple notification %o', error);\n return Object.keys(notification).map(() => false);\n }\n }\n}\n"],"mappings":"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"}
|
package/build/notify.mjs
CHANGED
|
@@ -101,6 +101,6 @@ async function notify(metadata, config, remoteUser, publishedPackage, publishTyp
|
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
//#endregion
|
|
104
|
-
export { handleNotify, notify, sendNotification };
|
|
104
|
+
export { compileTemplate, handleNotify, notify, sendNotification };
|
|
105
105
|
|
|
106
106
|
//# sourceMappingURL=notify.mjs.map
|
package/build/notify.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notify.mjs","names":[],"sources":["../src/notify.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport Handlebars from 'handlebars';\n\nimport { logger } from '@verdaccio/logger';\nimport type { Config, Manifest, Notification, RemoteUser } from '@verdaccio/types';\n\nimport type { FetchOptions } from './notify-request';\nimport { notifyRequest } from './notify-request';\n\nconst debug = buildDebug('verdaccio:hooks');\n\nexport function compileTemplate(content, metadata) {\n // FUTURE: multiple handlers\n return new Promise((resolve, reject) => {\n // eslint-disable-next-line no-unassigned-vars\n let handler;\n try {\n if (!handler) {\n debug('compile default template handler %o', content);\n const template: HandlebarsTemplateDelegate = Handlebars.compile(content);\n return resolve(template(metadata));\n }\n } catch (error: any) {\n debug('error template handler %o', error?.message);\n logger.error(\n { error: error.message },\n 'notification template compilation has failed: @{error}'\n );\n reject(error);\n }\n });\n}\n\nexport async function handleNotify(\n metadata: Partial<Manifest>,\n notifyEntry,\n remoteUser: Partial<RemoteUser>,\n publishedPackage: string,\n publishType?: string\n): Promise<boolean> {\n let regex;\n try {\n if (metadata.name && notifyEntry.packagePattern) {\n debug('checking package pattern %o', notifyEntry.packagePattern);\n debug('checking package pattern flags %o', notifyEntry.packagePatternFlags);\n regex = new RegExp(notifyEntry.packagePattern, notifyEntry.packagePatternFlags ?? '');\n if (!regex.test(metadata.name)) {\n logger.debug('Notification exclude does not match %o', metadata.name);\n return false;\n }\n debug('package pattern matched %o', metadata.name);\n }\n } catch (error: any) {\n logger.error('Invalid regex pattern or flags: %o', error?.message);\n return false;\n }\n\n const publishMetadata = {\n ...metadata,\n ...(typeof metadata.publisher === 'undefined' || metadata.publisher === null\n ? {\n // only expose the documented publisher fields, never the full remote\n // user object (it may carry the auth token, which must not leak to the\n // notification endpoint)\n publisher: {\n name: remoteUser.name,\n groups: remoteUser.groups,\n real_groups: remoteUser.real_groups,\n },\n }\n : {}),\n publishedPackage,\n publishType,\n };\n debug('template metadata %o', publishMetadata);\n const content = (await compileTemplate(notifyEntry.content, publishMetadata)) as string;\n\n const options: FetchOptions = {\n body: content,\n };\n\n // provides fallback support, it's accept an Object {} and Array of {}\n if (notifyEntry.headers && Array.isArray(notifyEntry.headers)) {\n const header = {};\n notifyEntry.headers.forEach((item): void => {\n if (item && typeof item === 'object') {\n Object.assign(header, item);\n }\n });\n options.headers = header;\n } else if (Object.is(notifyEntry.headers, notifyEntry.headers)) {\n options.headers = notifyEntry.headers;\n }\n\n if (!notifyEntry.endpoint) {\n debug('error due endpoint is missing');\n throw new Error('missing parameter');\n }\n\n return notifyRequest(notifyEntry.endpoint, {\n method: notifyEntry.method,\n ...options,\n });\n}\n\nexport function sendNotification(\n metadata: Partial<Manifest>,\n notify: Notification,\n remoteUser: Partial<RemoteUser>,\n publishedPackage: string,\n publishType?: string\n): Promise<boolean> {\n return handleNotify(metadata, notify, remoteUser, publishedPackage, publishType) as Promise<any>;\n}\n\nfunction isHasNotification(value: any): value is Notification {\n return value && typeof value === 'object' && 'endpoint' in value && 'content' in value;\n}\n\nexport async function notify(\n metadata: Partial<Manifest>,\n config: Config,\n remoteUser: RemoteUser,\n publishedPackage: string,\n publishType?: string\n): Promise<boolean[]> {\n debug('init send notification');\n const notification = config?.notify;\n if (!notification) {\n debug('no notify configuration detected');\n return [false];\n }\n\n const isSingle = isHasNotification(notification);\n debug('is single notify %o', isSingle);\n if (isSingle) {\n debug('send single notification');\n try {\n const response = await sendNotification(\n metadata,\n config.notify as Notification,\n remoteUser,\n publishedPackage,\n publishType\n );\n return [response];\n } catch {\n debug('error on sending single notification');\n return [false];\n }\n } else {\n try {\n debug('send multiples notification');\n const notificationEntries = Object.entries(notification).filter(([, item]) =>\n isHasNotification(item)\n );\n debug('valid notification entries %o', notificationEntries.length);\n if (notificationEntries.length === 0) {\n // No valid notifications, return false for each entry\n return Object.keys(notification).map(() => false);\n }\n debug('sending %o notifications', notificationEntries.length);\n const results = await Promise.allSettled(\n notificationEntries.map(([, item]) =>\n sendNotification(metadata, item, remoteUser, publishedPackage, publishType)\n )\n ).catch((error) => {\n logger.error({ error }, 'notify request has failed: @error');\n });\n if (!results) {\n return [];\n }\n return results.map((result) => (result.status === 'fulfilled' ? result.value : false));\n } catch (error) {\n debug('error on sending multiple notification %o', error);\n return Object.keys(notification).map(() => false);\n }\n }\n}\n"],"mappings":";;;;;AASA,IAAM,QAAQ,WAAW,iBAAiB;AAE1C,SAAgB,gBAAgB,SAAS,UAAU;CAEjD,OAAO,IAAI,SAAS,SAAS,WAAW;EAGtC,IAAI;GAEA,MAAM,uCAAuC,OAAO;GAEpD,OAAO,QADsC,WAAW,QAAQ,OACjD,
|
|
1
|
+
{"version":3,"file":"notify.mjs","names":[],"sources":["../src/notify.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport Handlebars from 'handlebars';\n\nimport { logger } from '@verdaccio/logger';\nimport type { Config, Manifest, Notification, RemoteUser } from '@verdaccio/types';\n\nimport type { FetchOptions } from './notify-request';\nimport { notifyRequest } from './notify-request';\n\nconst debug = buildDebug('verdaccio:hooks');\n\nexport function compileTemplate(content, metadata) {\n // FUTURE: multiple handlers\n return new Promise((resolve, reject) => {\n // eslint-disable-next-line no-unassigned-vars\n let handler;\n try {\n if (!handler) {\n debug('compile default template handler %o', content);\n const template: HandlebarsTemplateDelegate = Handlebars.compile(content);\n return resolve(template(metadata));\n }\n } catch (error: any) {\n debug('error template handler %o', error?.message);\n logger.error(\n { error: error.message },\n 'notification template compilation has failed: @{error}'\n );\n reject(error);\n }\n });\n}\n\nexport async function handleNotify(\n metadata: Partial<Manifest>,\n notifyEntry,\n remoteUser: Partial<RemoteUser>,\n publishedPackage: string,\n publishType?: string\n): Promise<boolean> {\n let regex;\n try {\n if (metadata.name && notifyEntry.packagePattern) {\n debug('checking package pattern %o', notifyEntry.packagePattern);\n debug('checking package pattern flags %o', notifyEntry.packagePatternFlags);\n regex = new RegExp(notifyEntry.packagePattern, notifyEntry.packagePatternFlags ?? '');\n if (!regex.test(metadata.name)) {\n logger.debug('Notification exclude does not match %o', metadata.name);\n return false;\n }\n debug('package pattern matched %o', metadata.name);\n }\n } catch (error: any) {\n logger.error('Invalid regex pattern or flags: %o', error?.message);\n return false;\n }\n\n const publishMetadata = {\n ...metadata,\n ...(typeof metadata.publisher === 'undefined' || metadata.publisher === null\n ? {\n // only expose the documented publisher fields, never the full remote\n // user object (it may carry the auth token, which must not leak to the\n // notification endpoint)\n publisher: {\n name: remoteUser.name,\n groups: remoteUser.groups,\n real_groups: remoteUser.real_groups,\n },\n }\n : {}),\n publishedPackage,\n publishType,\n };\n debug('template metadata %o', publishMetadata);\n const content = (await compileTemplate(notifyEntry.content, publishMetadata)) as string;\n\n const options: FetchOptions = {\n body: content,\n };\n\n // provides fallback support, it's accept an Object {} and Array of {}\n if (notifyEntry.headers && Array.isArray(notifyEntry.headers)) {\n const header = {};\n notifyEntry.headers.forEach((item): void => {\n if (item && typeof item === 'object') {\n Object.assign(header, item);\n }\n });\n options.headers = header;\n } else if (Object.is(notifyEntry.headers, notifyEntry.headers)) {\n options.headers = notifyEntry.headers;\n }\n\n if (!notifyEntry.endpoint) {\n debug('error due endpoint is missing');\n throw new Error('missing parameter');\n }\n\n return notifyRequest(notifyEntry.endpoint, {\n method: notifyEntry.method,\n ...options,\n });\n}\n\nexport function sendNotification(\n metadata: Partial<Manifest>,\n notify: Notification,\n remoteUser: Partial<RemoteUser>,\n publishedPackage: string,\n publishType?: string\n): Promise<boolean> {\n return handleNotify(metadata, notify, remoteUser, publishedPackage, publishType) as Promise<any>;\n}\n\nfunction isHasNotification(value: any): value is Notification {\n return value && typeof value === 'object' && 'endpoint' in value && 'content' in value;\n}\n\nexport async function notify(\n metadata: Partial<Manifest>,\n config: Config,\n remoteUser: RemoteUser,\n publishedPackage: string,\n publishType?: string\n): Promise<boolean[]> {\n debug('init send notification');\n const notification = config?.notify;\n if (!notification) {\n debug('no notify configuration detected');\n return [false];\n }\n\n const isSingle = isHasNotification(notification);\n debug('is single notify %o', isSingle);\n if (isSingle) {\n debug('send single notification');\n try {\n const response = await sendNotification(\n metadata,\n config.notify as Notification,\n remoteUser,\n publishedPackage,\n publishType\n );\n return [response];\n } catch {\n debug('error on sending single notification');\n return [false];\n }\n } else {\n try {\n debug('send multiples notification');\n const notificationEntries = Object.entries(notification).filter(([, item]) =>\n isHasNotification(item)\n );\n debug('valid notification entries %o', notificationEntries.length);\n if (notificationEntries.length === 0) {\n // No valid notifications, return false for each entry\n return Object.keys(notification).map(() => false);\n }\n debug('sending %o notifications', notificationEntries.length);\n const results = await Promise.allSettled(\n notificationEntries.map(([, item]) =>\n sendNotification(metadata, item, remoteUser, publishedPackage, publishType)\n )\n ).catch((error) => {\n logger.error({ error }, 'notify request has failed: @error');\n });\n if (!results) {\n return [];\n }\n return results.map((result) => (result.status === 'fulfilled' ? result.value : false));\n } catch (error) {\n debug('error on sending multiple notification %o', error);\n return Object.keys(notification).map(() => false);\n }\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@verdaccio/hooks",
|
|
3
|
-
"version": "9.0.0-next-9.
|
|
3
|
+
"version": "9.0.0-next-9.22",
|
|
4
4
|
"description": "Verdaccio Hooks",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -33,20 +33,20 @@
|
|
|
33
33
|
"node": ">=24"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@verdaccio/core": "9.0.0-next-9.
|
|
37
|
-
"@verdaccio/logger": "9.0.0-next-9.
|
|
36
|
+
"@verdaccio/core": "9.0.0-next-9.22",
|
|
37
|
+
"@verdaccio/logger": "9.0.0-next-9.22",
|
|
38
38
|
"debug": "4.4.3",
|
|
39
|
-
"got": "
|
|
39
|
+
"got": "15.1.0",
|
|
40
40
|
"handlebars": "4.7.9"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@verdaccio/config": "9.0.0-next-9.
|
|
44
|
-
"@verdaccio/test-helper": "5.0.0-next-9.
|
|
43
|
+
"@verdaccio/config": "9.0.0-next-9.22",
|
|
44
|
+
"@verdaccio/test-helper": "5.0.0-next-9.23",
|
|
45
45
|
"@verdaccio/types": "14.0.0-next-9.11",
|
|
46
46
|
"nock": "13.5.6",
|
|
47
47
|
"rimraf": "6.1.3",
|
|
48
|
-
"vite": "8.
|
|
49
|
-
"vitest": "4.1.
|
|
48
|
+
"vite": "8.1.4",
|
|
49
|
+
"vitest": "4.1.10"
|
|
50
50
|
},
|
|
51
51
|
"funding": {
|
|
52
52
|
"type": "opencollective",
|