@things-factory/board-service 10.0.0-beta.7 → 10.0.0-beta.72
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/dist-server/controllers/fonts.js +2 -2
- package/dist-server/controllers/fonts.js.map +1 -1
- package/dist-server/controllers/headless-model.js +4 -4
- package/dist-server/controllers/headless-model.js.map +1 -1
- package/dist-server/controllers/headless-playlist.js +2 -2
- package/dist-server/controllers/headless-playlist.js.map +1 -1
- package/dist-server/controllers/headless-render.d.ts +18 -0
- package/dist-server/controllers/headless-render.js +119 -0
- package/dist-server/controllers/headless-render.js.map +1 -0
- package/dist-server/controllers/index.d.ts +2 -2
- package/dist-server/controllers/label-command.js +25 -20
- package/dist-server/controllers/label-command.js.map +1 -1
- package/dist-server/controllers/pdf.d.ts +2 -10
- package/dist-server/controllers/pdf.js +3 -111
- package/dist-server/controllers/pdf.js.map +1 -1
- package/dist-server/controllers/screenshot.d.ts +2 -2
- package/dist-server/controllers/screenshot.js +3 -107
- package/dist-server/controllers/screenshot.js.map +1 -1
- package/dist-server/controllers/thumbnail.d.ts +1 -1
- package/dist-server/index.d.ts +6 -1
- package/dist-server/index.js +8 -13
- package/dist-server/index.js.map +1 -1
- package/dist-server/migrations/1762190000000-AddSourceImportSessionToBoard.d.ts +11 -0
- package/dist-server/migrations/1762190000000-AddSourceImportSessionToBoard.js +45 -0
- package/dist-server/migrations/1762190000000-AddSourceImportSessionToBoard.js.map +1 -0
- package/dist-server/routes.js +0 -1
- package/dist-server/routes.js.map +1 -1
- package/dist-server/service/board/board-mutation.d.ts +1 -0
- package/dist-server/service/board/board-mutation.js +125 -13
- package/dist-server/service/board/board-mutation.js.map +1 -1
- package/dist-server/service/board/board-query.d.ts +2 -1
- package/dist-server/service/board/board-query.js +34 -4
- package/dist-server/service/board/board-query.js.map +1 -1
- package/dist-server/service/board/board-reorder.test.d.ts +4 -0
- package/dist-server/service/board/board-reorder.test.js +347 -0
- package/dist-server/service/board/board-reorder.test.js.map +1 -0
- package/dist-server/service/board/board.d.ts +7 -0
- package/dist-server/service/board/board.js +11 -0
- package/dist-server/service/board/board.js.map +1 -1
- package/dist-server/service/board-template/board-template-mutation.js +5 -5
- package/dist-server/service/board-template/board-template-mutation.js.map +1 -1
- package/dist-server/service/group/group-mutation.js +2 -2
- package/dist-server/service/group/group-mutation.js.map +1 -1
- package/dist-server/service/index.js +2 -5
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -7
- package/views/internal-board-service-view.html +2 -1
|
@@ -23,8 +23,8 @@ const fonts = async (domain) => {
|
|
|
23
23
|
.addSelect('FONT.uri', 'uri')
|
|
24
24
|
.where({ active: true })
|
|
25
25
|
.getRawMany();
|
|
26
|
-
var googleFonts = fonts.filter(({ provider }) => provider
|
|
27
|
-
var customFonts = fonts.filter(({ provider }) => provider
|
|
26
|
+
var googleFonts = fonts.filter(({ provider }) => provider === 'google');
|
|
27
|
+
var customFonts = fonts.filter(({ provider }) => provider === 'custom');
|
|
28
28
|
var customFontCSS = '';
|
|
29
29
|
for (const font of customFonts) {
|
|
30
30
|
var files = domain
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fonts.js","sourceRoot":"","sources":["../../server/controllers/fonts.ts"],"names":[],"mappings":";;;AAEA,yDAAgD;AAChD,qEAA4D;AAC5D,iDAA6D;AAEtD,MAAM,KAAK,GAAG,KAAK,EAAE,MAAe,EAAE,EAAE;IAC7C,MAAM,EAAE,GAA6B,MAAM,IAAA,qBAAa,EAAC,gBAAI,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAA;IAEzF,IAAI,KAAK,GAAG,MAAM;QAChB,CAAC,CAAC,MAAM,EAAE;aACL,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC;aAC3B,QAAQ,CAAC,IAAI,CAAC;aACd,SAAS,CAAC,eAAe,EAAE,UAAU,CAAC;aACtC,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC;aAC1B,SAAS,CAAC,UAAU,EAAE,KAAK,CAAC;aAC5B,KAAK,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;aAClD,UAAU,EAAE;QACjB,CAAC,CAAC,MAAM,EAAE;aACL,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC;aAC3B,QAAQ,CAAC,IAAI,CAAC;aACd,SAAS,CAAC,eAAe,EAAE,UAAU,CAAC;aACtC,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC;aAC1B,SAAS,CAAC,UAAU,EAAE,KAAK,CAAC;aAC5B,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;aACvB,UAAU,EAAE,CAAA;IAEnB,IAAI,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,QAAQ,
|
|
1
|
+
{"version":3,"file":"fonts.js","sourceRoot":"","sources":["../../server/controllers/fonts.ts"],"names":[],"mappings":"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","sourcesContent":["import { SelectQueryBuilder } from 'typeorm'\n\nimport { Font } from '@things-factory/font-base'\nimport { Attachment } from '@things-factory/attachment-base'\nimport { getRepository, Domain } from '@things-factory/shell'\n\nexport const fonts = async (domain?: Domain) => {\n const qb: SelectQueryBuilder<Font> = await getRepository(Font).createQueryBuilder('FONT')\n\n var fonts = domain\n ? await qb\n .select('FONT.name', 'name')\n .distinct(true)\n .addSelect('FONT.provider', 'provider')\n .addSelect('FONT.id', 'id')\n .addSelect('FONT.uri', 'uri')\n .where({ domain: { id: domain.id }, active: true })\n .getRawMany()\n : await qb\n .select('FONT.name', 'name')\n .distinct(true)\n .addSelect('FONT.provider', 'provider')\n .addSelect('FONT.id', 'id')\n .addSelect('FONT.uri', 'uri')\n .where({ active: true })\n .getRawMany()\n\n var googleFonts = fonts.filter(({ provider }) => provider === 'google')\n var customFonts = fonts.filter(({ provider }) => provider === 'custom')\n\n var customFontCSS: string = ''\n\n for (const font of customFonts) {\n var files: Attachment[] = domain\n ? await getRepository(Attachment).findBy({\n domain: { id: domain.id },\n refBy: font.id\n })\n : await getRepository(Attachment).findBy({\n refBy: font.id\n })\n\n if (files && files.length > 0) {\n customFontCSS += files\n .map(file => {\n const { name: filename, fullpath } = file\n const bold = filename.toUpperCase().indexOf('BOLD') !== -1\n\n return `@font-face {\n font-family: '${font.name}';\n src: local('${font.name}'), url(${fullpath});\n font-weight: ${bold ? 'bold' : 'normal'};\n }\n `\n })\n .join('\\n')\n } else {\n customFontCSS += `@font-face {\n font-family: '${font.name}';\n src: local('${font.name}')${font.uri ? `, url(${font.uri})` : ''};\n }\n `\n }\n }\n\n return googleFonts.length > 0 || customFonts.length > 0\n ? [\n {\n ...(googleFonts.length > 0 && {\n google: {\n families: googleFonts.map(({ name }) => name)\n }\n }),\n ...(customFonts.length > 0 && {\n custom: {\n families: customFonts.map(({ name }) => name)\n }\n })\n },\n customFonts.length > 0 ? customFontCSS : null\n ]\n : []\n}\n"]}
|
|
@@ -8,11 +8,11 @@ const board_history_js_1 = require("../service/board/board-history.js");
|
|
|
8
8
|
const headlessModel = async (target, draft = false) => {
|
|
9
9
|
var { domain, id, model, name } = target || {};
|
|
10
10
|
if (model) {
|
|
11
|
-
if (typeof model
|
|
11
|
+
if (typeof model === 'string') {
|
|
12
12
|
model = JSON.parse(model);
|
|
13
13
|
}
|
|
14
14
|
else if (typeof model !== 'object') {
|
|
15
|
-
throw 'model should be a string or object';
|
|
15
|
+
throw new Error('model should be a string or object');
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
else {
|
|
@@ -27,10 +27,10 @@ const headlessModel = async (target, draft = false) => {
|
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
29
|
else {
|
|
30
|
-
throw 'parameter model or id mandatory';
|
|
30
|
+
throw new Error('parameter model or id mandatory');
|
|
31
31
|
}
|
|
32
32
|
if (!draft && board) {
|
|
33
|
-
const latestReleased = board.state
|
|
33
|
+
const latestReleased = board.state === 'released'
|
|
34
34
|
? board
|
|
35
35
|
: await (0, shell_1.getRepository)(board_history_js_1.BoardHistory)
|
|
36
36
|
.createQueryBuilder('history')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"headless-model.js","sourceRoot":"","sources":["../../server/controllers/headless-model.ts"],"names":[],"mappings":";;;AAAA,qCAA4B;AAC5B,iDAAqE;AAErE,wDAAiD;AACjD,wEAAgE;AAEzD,MAAM,aAAa,GAAG,KAAK,EAAE,MAAM,EAAE,QAAiB,KAAK,EAAE,EAAE;IACpE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,EAAE,CAAA;IAE9C,IAAI,KAAK,EAAE,CAAC;QACV,IAAI,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"headless-model.js","sourceRoot":"","sources":["../../server/controllers/headless-model.ts"],"names":[],"mappings":";;;AAAA,qCAA4B;AAC5B,iDAAqE;AAErE,wDAAiD;AACjD,wEAAgE;AAEzD,MAAM,aAAa,GAAG,KAAK,EAAE,MAAM,EAAE,QAAiB,KAAK,EAAE,EAAE;IACpE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,EAAE,CAAA;IAE9C,IAAI,KAAK,EAAE,CAAC;QACV,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAC3B,CAAC;aAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAA;QACvD,CAAC;IACH,CAAC;SAAM,CAAC;QACN,IAAI,EAAE,EAAE,CAAC;YACP,IAAI,KAAK,GAAG,MAAM,IAAA,qBAAa,EAAC,gBAAK,CAAC,CAAC,OAAO,CAAC;gBAC7C,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,IAAA,YAAE,EAAC,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE;aAChF,CAAC,CAAA;QACJ,CAAC;aAAM,IAAI,IAAI,EAAE,CAAC;YAChB,IAAI,KAAK,GAAG,MAAM,IAAA,qBAAa,EAAC,gBAAK,CAAC,CAAC,OAAO,CAAC;gBAC7C,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,IAAA,YAAE,EAAC,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE;aAClF,CAAC,CAAA;QACJ,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;QACpD,CAAC;QAED,IAAI,CAAC,KAAK,IAAI,KAAK,EAAE,CAAC;YACpB,MAAM,cAAc,GAClB,KAAK,CAAC,KAAK,KAAK,UAAU;gBACxB,CAAC,CAAC,KAAK;gBACP,CAAC,CAAC,MAAM,IAAA,qBAAa,EAAC,+BAAY,CAAC;qBAC9B,kBAAkB,CAAC,SAAS,CAAC;qBAC7B,KAAK,CAAC,kCAAkC,EAAE,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;qBACnE,OAAO,CAAC,iBAAiB,EAAE,MAAM,CAAC;qBAClC,KAAK,CAAC,CAAC,CAAC;qBACR,MAAM,EAAE,CAAA;YAEjB,KAAK,GAAG,CAAC,cAAc,IAAI,KAAK,CAAC,CAAC,KAAK,CAAA;QACzC,CAAC;aAAM,CAAC;YACN,KAAK,GAAG,KAAK,CAAC,KAAK,CAAA;QACrB,CAAC;QAED,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IAC3B,CAAC;IAED,OAAO;QACL,IAAI,EAAE,IAAA,sBAAc,EAAC,MAAM,CAAC;QAC5B,KAAK;QACL,KAAK;KACN,CAAA;AACH,CAAC,CAAA;AA9CY,QAAA,aAAa,iBA8CzB","sourcesContent":["import { In } from 'typeorm'\nimport { getContextPath, getRepository } from '@things-factory/shell'\n\nimport { Board } from '../service/board/board.js'\nimport { BoardHistory } from '../service/board/board-history.js'\n\nexport const headlessModel = async (target, draft: boolean = false) => {\n var { domain, id, model, name } = target || {}\n\n if (model) {\n if (typeof model === 'string') {\n model = JSON.parse(model)\n } else if (typeof model !== 'object') {\n throw new Error('model should be a string or object')\n }\n } else {\n if (id) {\n var board = await getRepository(Board).findOne({\n where: { domain: { id: In([domain.id, domain.parentId].filter(Boolean)) }, id }\n })\n } else if (name) {\n var board = await getRepository(Board).findOne({\n where: { domain: { id: In([domain.id, domain.parentId].filter(Boolean)) }, name }\n })\n } else {\n throw new Error('parameter model or id mandatory')\n }\n\n if (!draft && board) {\n const latestReleased =\n board.state === 'released'\n ? board\n : await getRepository(BoardHistory)\n .createQueryBuilder('history')\n .where('history.originalId = :originalId', { originalId: board.id })\n .orderBy('history.version', 'DESC')\n .limit(1)\n .getOne()\n\n model = (latestReleased || board).model\n } else {\n model = board.model\n }\n\n model = JSON.parse(model)\n }\n\n return {\n base: getContextPath(domain),\n model,\n board\n }\n}\n"]}
|
|
@@ -23,7 +23,7 @@ const headlessPlaylist = async (target, draft = false) => {
|
|
|
23
23
|
if (!draft && playGroup) {
|
|
24
24
|
const { boards } = playGroup;
|
|
25
25
|
for (let board of boards) {
|
|
26
|
-
const latestReleased = board.state
|
|
26
|
+
const latestReleased = board.state === 'released'
|
|
27
27
|
? board
|
|
28
28
|
: await (0, shell_1.getRepository)(board_history_js_1.BoardHistory)
|
|
29
29
|
.createQueryBuilder('history')
|
|
@@ -60,7 +60,7 @@ const headlessPlaylist = async (target, draft = false) => {
|
|
|
60
60
|
});
|
|
61
61
|
}
|
|
62
62
|
else {
|
|
63
|
-
throw 'parameter id or name mandatory';
|
|
63
|
+
throw new Error('parameter id or name mandatory');
|
|
64
64
|
}
|
|
65
65
|
return {
|
|
66
66
|
base: (0, shell_1.getContextPath)(domain),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"headless-playlist.js","sourceRoot":"","sources":["../../server/controllers/headless-playlist.ts"],"names":[],"mappings":";;;AAAA,iDAAqE;AAErE,uEAA+D;AAC/D,wEAAgE;AAEzD,MAAM,gBAAgB,GAAG,KAAK,EAAE,MAAM,EAAE,QAAiB,KAAK,EAAE,EAAE;IACvE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,EAAE,CAAA;IAEvC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;QACf,MAAM,UAAU,GAAG,IAAA,qBAAa,EAAC,yBAAS,CAAC,CAAA;QAE3C,IAAI,EAAE,EAAE,CAAC;YACP,IAAI,SAAS,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC;gBACvC,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE;gBACxC,SAAS,EAAE,CAAC,QAAQ,CAAC;aACtB,CAAC,CAAA;QACJ,CAAC;aAAM,IAAI,IAAI,EAAE,CAAC;YAChB,IAAI,SAAS,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC;gBACvC,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE;gBAC1C,SAAS,EAAE,CAAC,QAAQ,CAAC;aACtB,CAAC,CAAA;QACJ,CAAC;QAED,IAAI,CAAC,KAAK,IAAI,SAAS,EAAE,CAAC;YACxB,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAA;YAC5B,KAAK,IAAI,KAAK,IAAI,MAAM,EAAE,CAAC;gBACzB,MAAM,cAAc,GAClB,KAAK,CAAC,KAAK,
|
|
1
|
+
{"version":3,"file":"headless-playlist.js","sourceRoot":"","sources":["../../server/controllers/headless-playlist.ts"],"names":[],"mappings":"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","sourcesContent":["import { getContextPath, getRepository } from '@things-factory/shell'\n\nimport { PlayGroup } from '../service/play-group/play-group.js'\nimport { BoardHistory } from '../service/board/board-history.js'\n\nexport const headlessPlaylist = async (target, draft: boolean = false) => {\n var { domain, id, name } = target || {}\n\n if (id || name) {\n const repository = getRepository(PlayGroup)\n\n if (id) {\n var playGroup = await repository.findOne({\n where: { domain: { id: domain.id }, id },\n relations: ['boards']\n })\n } else if (name) {\n var playGroup = await repository.findOne({\n where: { domain: { id: domain.id }, name },\n relations: ['boards']\n })\n }\n\n if (!draft && playGroup) {\n const { boards } = playGroup\n for (let board of boards) {\n const latestReleased =\n board.state === 'released'\n ? board\n : await getRepository(BoardHistory)\n .createQueryBuilder('history')\n .where('history.originalId = :originalId', { originalId: board.id })\n .orderBy('history.version', 'DESC')\n .limit(1)\n .getOne()\n\n if (latestReleased) {\n board.model = latestReleased.model\n }\n }\n }\n\n playGroup.boards = playGroup.boards.sort((a, b) => {\n // 배열 A에 포함된 아이디의 순서를 가져옵니다.\n const indexOfOrder = (playGroup.order || []).indexOf(a.id)\n const indexOfBoards = (playGroup.order || []).indexOf(b.id)\n\n // 두 아이디의 순서를 비교하여 정렬합니다.\n if (indexOfOrder === -1 && indexOfBoards === -1) {\n // 두 아이디 모두 배열 A에 없는 경우, 그대로 유지합니다.\n return 0\n } else if (indexOfOrder === -1) {\n // 아이디 A만 배열 A에 없는 경우, 아이디 B를 먼저 정렬합니다.\n return 1\n } else if (indexOfBoards === -1) {\n // 아이디 B만 배열 A에 없는 경우, 아이디 A를 먼저 정렬합니다.\n return -1\n } else {\n // 두 아이디 모두 배열 A에 있는 경우, 배열 A의 아이디 순서대로 정렬합니다.\n return indexOfOrder - indexOfBoards\n }\n })\n } else {\n throw new Error('parameter id or name mandatory')\n }\n\n return {\n base: getContextPath(domain),\n playGroup\n }\n}\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface HeadlessRenderOptions {
|
|
2
|
+
id?: string;
|
|
3
|
+
model?: any;
|
|
4
|
+
data?: any;
|
|
5
|
+
width?: number;
|
|
6
|
+
height?: number;
|
|
7
|
+
options?: any;
|
|
8
|
+
context?: any;
|
|
9
|
+
draft?: boolean;
|
|
10
|
+
/** true 이면 thumbnail 크기(400x300)로 축소 */
|
|
11
|
+
isThumbnail?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* headless 브라우저 페이지를 준비하고 renderFn 을 실행한 결과를 반환한다.
|
|
15
|
+
*
|
|
16
|
+
* 공통 처리: pool acquire → headlessModel → fonts → viewport → request intercept → goto → data 주입 → renderFn → cleanup
|
|
17
|
+
*/
|
|
18
|
+
export declare function withHeadlessPage<T>({ id, model, data, width: w, height: h, options, context, draft, isThumbnail }: HeadlessRenderOptions, renderFn: (page: any) => Promise<T>): Promise<T | null>;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withHeadlessPage = withHeadlessPage;
|
|
4
|
+
const fonts_js_1 = require("./fonts.js");
|
|
5
|
+
const headless_pool_for_board_js_1 = require("./headless-pool-for-board.js");
|
|
6
|
+
const headless_model_js_1 = require("./headless-model.js");
|
|
7
|
+
const protocol = 'http';
|
|
8
|
+
const host = 'localhost';
|
|
9
|
+
const path = '/internal-board-service-view';
|
|
10
|
+
/** headless page 에 console/error 이벤트 핸들러를 일괄 등록한다. */
|
|
11
|
+
function attachPageListeners(page) {
|
|
12
|
+
page.on('console', async (msg) => {
|
|
13
|
+
const args = await Promise.all(msg.args().map(arg => arg.jsonValue().catch(() => undefined)));
|
|
14
|
+
if (args.some(a => a !== undefined)) {
|
|
15
|
+
console.log(`[headless ${msg.type()}]`, ...args.filter(a => a !== undefined));
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
const text = msg.text();
|
|
19
|
+
if (text)
|
|
20
|
+
console.log(`[headless ${msg.type()}]`, text);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
page.on('pageerror', error => {
|
|
24
|
+
console.log(`[headless pageerror] ${error.message}`);
|
|
25
|
+
console.log(error.stack);
|
|
26
|
+
});
|
|
27
|
+
page.on('error', error => {
|
|
28
|
+
console.log(`[headless fault] ${error}`);
|
|
29
|
+
console.log(error.stack);
|
|
30
|
+
});
|
|
31
|
+
page.on('requestfailed', request => {
|
|
32
|
+
console.log('Request failed:', request.url());
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* headless 브라우저 페이지를 준비하고 renderFn 을 실행한 결과를 반환한다.
|
|
37
|
+
*
|
|
38
|
+
* 공통 처리: pool acquire → headlessModel → fonts → viewport → request intercept → goto → data 주입 → renderFn → cleanup
|
|
39
|
+
*/
|
|
40
|
+
async function withHeadlessPage({ id = '', model = null, data = null, width: w = 0, height: h = 0, options = {}, context = {}, draft = false, isThumbnail = false }, renderFn) {
|
|
41
|
+
const browser = (await (0, headless_pool_for_board_js_1.getHeadlessPool)().acquire());
|
|
42
|
+
if (!browser)
|
|
43
|
+
return null;
|
|
44
|
+
const { domain, user } = context.state;
|
|
45
|
+
var { model: resolvedModel, base } = await (0, headless_model_js_1.headlessModel)({ domain, id, model }, draft);
|
|
46
|
+
const [fontsToUse, fontStyles] = await (0, fonts_js_1.fonts)(domain);
|
|
47
|
+
resolvedModel.fonts = fontsToUse;
|
|
48
|
+
resolvedModel.fontStyles = fontStyles;
|
|
49
|
+
let { width, height } = resolvedModel;
|
|
50
|
+
if (isThumbnail) {
|
|
51
|
+
const ratio = Math.min(400 / width, 300 / height);
|
|
52
|
+
width = width * ratio;
|
|
53
|
+
height = height * ratio;
|
|
54
|
+
}
|
|
55
|
+
else if (w || h) {
|
|
56
|
+
const ratio = Math.min((w || width) / width, (h || height) / height);
|
|
57
|
+
width = width * ratio;
|
|
58
|
+
height = height * ratio;
|
|
59
|
+
}
|
|
60
|
+
width = Math.floor(w || Number(width));
|
|
61
|
+
height = Math.floor(h || Number(height));
|
|
62
|
+
const port = process.env.PORT ? `:${process.env.PORT}` : '';
|
|
63
|
+
const url = `${protocol}://${host}${port}${path}`;
|
|
64
|
+
const page = await browser.newPage();
|
|
65
|
+
let result = null;
|
|
66
|
+
try {
|
|
67
|
+
await page.setViewport({ width, height });
|
|
68
|
+
await page.setRequestInterception(true);
|
|
69
|
+
await page.setDefaultTimeout(10000);
|
|
70
|
+
attachPageListeners(page);
|
|
71
|
+
const token = await user?.sign();
|
|
72
|
+
page.on('request', request => {
|
|
73
|
+
if (request.url() === url) {
|
|
74
|
+
request.continue({
|
|
75
|
+
method: 'POST',
|
|
76
|
+
headers: {
|
|
77
|
+
'Content-Type': 'application/json',
|
|
78
|
+
'x-things-factory-domain': domain?.subdomain,
|
|
79
|
+
Authorization: 'Bearer ' + token
|
|
80
|
+
},
|
|
81
|
+
postData: JSON.stringify({ model: resolvedModel, base })
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
else if (request.url().startsWith(`${protocol}://${host}${port}`)) {
|
|
85
|
+
request.continue({
|
|
86
|
+
headers: {
|
|
87
|
+
...request.headers(),
|
|
88
|
+
'x-things-factory-domain': domain?.subdomain,
|
|
89
|
+
Authorization: 'Bearer ' + token
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
request.continue();
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
await page.goto(url);
|
|
98
|
+
await page.evaluate(async (data) => {
|
|
99
|
+
if (data) {
|
|
100
|
+
// @ts-ignore
|
|
101
|
+
s.data = data;
|
|
102
|
+
}
|
|
103
|
+
return new Promise(resolve => {
|
|
104
|
+
// @ts-ignore
|
|
105
|
+
requestAnimationFrame(() => resolve());
|
|
106
|
+
});
|
|
107
|
+
}, data);
|
|
108
|
+
result = await renderFn(page);
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
console.log(error);
|
|
112
|
+
}
|
|
113
|
+
finally {
|
|
114
|
+
await page.close();
|
|
115
|
+
(0, headless_pool_for_board_js_1.getHeadlessPool)().release(browser);
|
|
116
|
+
}
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=headless-render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headless-render.js","sourceRoot":"","sources":["../../server/controllers/headless-render.ts"],"names":[],"mappings":"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","sourcesContent":["import { fonts } from './fonts.js'\nimport { getHeadlessPool } from './headless-pool-for-board.js'\nimport { headlessModel } from './headless-model.js'\n\nconst protocol = 'http'\nconst host = 'localhost'\nconst path = '/internal-board-service-view'\n\n/** headless page 에 console/error 이벤트 핸들러를 일괄 등록한다. */\nfunction attachPageListeners(page: any) {\n page.on('console', async msg => {\n const args = await Promise.all(msg.args().map(arg => arg.jsonValue().catch(() => undefined)))\n\n if (args.some(a => a !== undefined)) {\n console.log(`[headless ${msg.type()}]`, ...args.filter(a => a !== undefined))\n } else {\n const text = msg.text()\n if (text) console.log(`[headless ${msg.type()}]`, text)\n }\n })\n\n page.on('pageerror', error => {\n console.log(`[headless pageerror] ${error.message}`)\n console.log(error.stack)\n })\n\n page.on('error', error => {\n console.log(`[headless fault] ${error}`)\n console.log(error.stack)\n })\n\n page.on('requestfailed', request => {\n console.log('Request failed:', request.url())\n })\n}\n\nexport interface HeadlessRenderOptions {\n id?: string\n model?: any\n data?: any\n width?: number\n height?: number\n options?: any\n context?: any\n draft?: boolean\n /** true 이면 thumbnail 크기(400x300)로 축소 */\n isThumbnail?: boolean\n}\n\n/**\n * headless 브라우저 페이지를 준비하고 renderFn 을 실행한 결과를 반환한다.\n *\n * 공통 처리: pool acquire → headlessModel → fonts → viewport → request intercept → goto → data 주입 → renderFn → cleanup\n */\nexport async function withHeadlessPage<T>(\n {\n id = '',\n model = null,\n data = null,\n width: w = 0,\n height: h = 0,\n options = {} as any,\n context = {} as any,\n draft = false,\n isThumbnail = false\n }: HeadlessRenderOptions,\n renderFn: (page: any) => Promise<T>\n): Promise<T | null> {\n const browser = (await getHeadlessPool().acquire()) as any\n if (!browser) return null\n\n const { domain, user } = context.state\n\n var { model: resolvedModel, base } = await headlessModel({ domain, id, model }, draft)\n const [fontsToUse, fontStyles] = await fonts(domain)\n\n resolvedModel.fonts = fontsToUse\n resolvedModel.fontStyles = fontStyles\n\n let { width, height } = resolvedModel\n\n if (isThumbnail) {\n const ratio = Math.min(400 / width, 300 / height)\n width = width * ratio\n height = height * ratio\n } else if (w || h) {\n const ratio = Math.min((w || width) / width, (h || height) / height)\n width = width * ratio\n height = height * ratio\n }\n\n width = Math.floor(w || Number(width))\n height = Math.floor(h || Number(height))\n\n const port = process.env.PORT ? `:${process.env.PORT}` : ''\n const url = `${protocol}://${host}${port}${path}`\n const page = await browser.newPage()\n\n let result: T | null = null\n\n try {\n await page.setViewport({ width, height })\n await page.setRequestInterception(true)\n await page.setDefaultTimeout(10000)\n\n attachPageListeners(page)\n\n const token = await user?.sign()\n\n page.on('request', request => {\n if (request.url() === url) {\n request.continue({\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-things-factory-domain': domain?.subdomain,\n Authorization: 'Bearer ' + token\n },\n postData: JSON.stringify({ model: resolvedModel, base })\n })\n } else if (request.url().startsWith(`${protocol}://${host}${port}`)) {\n request.continue({\n headers: {\n ...request.headers(),\n 'x-things-factory-domain': domain?.subdomain,\n Authorization: 'Bearer ' + token\n }\n })\n } else {\n request.continue()\n }\n })\n\n await page.goto(url)\n\n await page.evaluate(async data => {\n if (data) {\n // @ts-ignore\n s.data = data\n }\n return new Promise(resolve => {\n // @ts-ignore\n requestAnimationFrame(() => resolve())\n })\n }, data)\n\n result = await renderFn(page)\n } catch (error) {\n console.log(error)\n } finally {\n await page.close()\n getHeadlessPool().release(browser)\n }\n\n return result\n}\n"]}
|
|
@@ -9,7 +9,7 @@ export declare const BoardFunc: {
|
|
|
9
9
|
context: any;
|
|
10
10
|
draft?: boolean;
|
|
11
11
|
}) => Promise<string>;
|
|
12
|
-
boardToPdf: ({ id, model, data, width
|
|
12
|
+
boardToPdf: ({ id, model, data, width, height, options, context }?: {
|
|
13
13
|
id?: string;
|
|
14
14
|
model?: any;
|
|
15
15
|
data?: any;
|
|
@@ -17,7 +17,7 @@ export declare const BoardFunc: {
|
|
|
17
17
|
height?: number;
|
|
18
18
|
options?: any;
|
|
19
19
|
context?: any;
|
|
20
|
-
}) => Promise
|
|
20
|
+
}) => Promise<unknown>;
|
|
21
21
|
headlessModel: (target: any, draft?: boolean) => Promise<{
|
|
22
22
|
base: string;
|
|
23
23
|
model: any;
|
|
@@ -21,32 +21,37 @@ const labelcommand = async ({ id, model, data, orientation, mirror = false, upsi
|
|
|
21
21
|
if (!browser) {
|
|
22
22
|
return;
|
|
23
23
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
requestAnimationFrame(() => {
|
|
24
|
+
try {
|
|
25
|
+
const { page } = browser;
|
|
26
|
+
var { model } = await (0, headless_model_js_1.headlessModel)({ domain, model, id }, draft);
|
|
27
|
+
const grf = await page.evaluate(async (model, data, orientation, mirror, upsideDown) => {
|
|
28
|
+
//@ts-ignore
|
|
29
|
+
let s = createScene(model);
|
|
30
|
+
if (data) {
|
|
31
|
+
s.data = data;
|
|
32
|
+
}
|
|
33
|
+
return new Promise(resolve => {
|
|
35
34
|
// @ts-ignore
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
requestAnimationFrame(() => {
|
|
36
|
+
// @ts-ignore
|
|
37
|
+
let grf = imageDataToGrf(s, model, orientation, mirror, upsideDown);
|
|
38
|
+
resolve(grf);
|
|
39
|
+
// @ts-ignore
|
|
40
|
+
sceneContainer.removeChild(s.target);
|
|
41
|
+
s.dispose();
|
|
42
|
+
});
|
|
41
43
|
});
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
(0, headless_pool_for_label_js_1.getHeadlessPool)().release(browser);
|
|
45
|
-
return `
|
|
44
|
+
}, model, data, orientation, mirror, upsideDown);
|
|
45
|
+
return `
|
|
46
46
|
^XA
|
|
47
47
|
^GFA,${grf}
|
|
48
48
|
^FS
|
|
49
49
|
^XZ`;
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
// 에러 발생 시에도 반드시 풀에 브라우저를 반환
|
|
53
|
+
(0, headless_pool_for_label_js_1.getHeadlessPool)().release(browser);
|
|
54
|
+
}
|
|
50
55
|
};
|
|
51
56
|
exports.labelcommand = labelcommand;
|
|
52
57
|
//# sourceMappingURL=label-command.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"label-command.js","sourceRoot":"","sources":["../../server/controllers/label-command.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,6EAA8D;AAC9D,2DAAmD;AAEnD;;;;;;;;GAQG;AACI,MAAM,YAAY,GAAG,KAAK,EAAE,EACjC,EAAE,EACF,KAAK,EACL,IAAI,EACJ,WAAW,EACX,MAAM,GAAG,KAAK,EACd,UAAU,GAAG,KAAK,EAClB,OAAO,EACP,KAAK,GAAG,KAAK,EACd,EAAE,EAAE;IACH,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;IAEhC,MAAM,OAAO,GAAG,CAAC,MAAM,IAAA,4CAAe,GAAE,CAAC,OAAO,EAAE,CAAQ,CAAA;IAC1D,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAM;IACR,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"label-command.js","sourceRoot":"","sources":["../../server/controllers/label-command.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,6EAA8D;AAC9D,2DAAmD;AAEnD;;;;;;;;GAQG;AACI,MAAM,YAAY,GAAG,KAAK,EAAE,EACjC,EAAE,EACF,KAAK,EACL,IAAI,EACJ,WAAW,EACX,MAAM,GAAG,KAAK,EACd,UAAU,GAAG,KAAK,EAClB,OAAO,EACP,KAAK,GAAG,KAAK,EACd,EAAE,EAAE;IACH,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;IAEhC,MAAM,OAAO,GAAG,CAAC,MAAM,IAAA,4CAAe,GAAE,CAAC,OAAO,EAAE,CAAQ,CAAA;IAC1D,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAM;IACR,CAAC;IAED,IAAI,CAAC;QACH,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAA;QAExB,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAA,iCAAa,EAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,CAAA;QAEjE,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAC7B,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE;YACrD,YAAY;YACZ,IAAI,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,CAAA;YAC1B,IAAI,IAAI,EAAE,CAAC;gBACT,CAAC,CAAC,IAAI,GAAG,IAAI,CAAA;YACf,CAAC;YACD,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;gBAC3B,aAAa;gBACb,qBAAqB,CAAC,GAAG,EAAE;oBACzB,aAAa;oBACb,IAAI,GAAG,GAAG,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,CAAA;oBACnE,OAAO,CAAC,GAAG,CAAC,CAAA;oBACZ,aAAa;oBACb,cAAc,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;oBACpC,CAAC,CAAC,OAAO,EAAE,CAAA;gBACb,CAAC,CAAC,CAAA;YACJ,CAAC,CAAC,CAAA;QACJ,CAAC,EACD,KAAK,EACL,IAAI,EACJ,WAAW,EACX,MAAM,EACN,UAAU,CACX,CAAA;QAED,OAAO;;OAEJ,GAAG;;IAEN,CAAA;IACF,CAAC;YAAS,CAAC;QACT,4BAA4B;QAC5B,IAAA,4CAAe,GAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IACpC,CAAC;AACH,CAAC,CAAA;AAzDY,QAAA,YAAY,gBAyDxB","sourcesContent":["/*\n * Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { getHeadlessPool } from './headless-pool-for-label.js'\nimport { headlessModel } from './headless-model.js'\n\n/**\n * 라벨 출력\n *\n * @param {String} id 모델 ID\n * @param {Object} data 매핑할 데이터\n * @param {String} orientation (시계방향) N: 0, R: 90, I: 180, B: 270\n * @param {boolean} mirror 좌우반전\n * @param {boolean} upsideDown 상하반전\n */\nexport const labelcommand = async ({\n id,\n model,\n data,\n orientation,\n mirror = false,\n upsideDown = false,\n context,\n draft = false\n}) => {\n const { domain } = context.state\n\n const browser = (await getHeadlessPool().acquire()) as any\n if (!browser) {\n return\n }\n\n try {\n const { page } = browser\n\n var { model } = await headlessModel({ domain, model, id }, draft)\n\n const grf = await page.evaluate(\n async (model, data, orientation, mirror, upsideDown) => {\n //@ts-ignore\n let s = createScene(model)\n if (data) {\n s.data = data\n }\n return new Promise(resolve => {\n // @ts-ignore\n requestAnimationFrame(() => {\n // @ts-ignore\n let grf = imageDataToGrf(s, model, orientation, mirror, upsideDown)\n resolve(grf)\n // @ts-ignore\n sceneContainer.removeChild(s.target)\n s.dispose()\n })\n })\n },\n model,\n data,\n orientation,\n mirror,\n upsideDown\n )\n\n return `\n^XA\n^GFA,${grf}\n^FS\n^XZ`\n } finally {\n // 에러 발생 시에도 반드시 풀에 브라우저를 반환\n getHeadlessPool().release(browser)\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const pdf: ({ id, model, data, width
|
|
1
|
+
export declare const pdf: ({ id, model, data, width, height, options, context }?: {
|
|
2
2
|
id?: string;
|
|
3
3
|
model?: any;
|
|
4
4
|
data?: any;
|
|
@@ -6,12 +6,4 @@ export declare const pdf: ({ id, model, data, width: w, height: h, options, cont
|
|
|
6
6
|
height?: number;
|
|
7
7
|
options?: any;
|
|
8
8
|
context?: any;
|
|
9
|
-
}) => Promise<
|
|
10
|
-
id?: string;
|
|
11
|
-
model?: any;
|
|
12
|
-
data?: any;
|
|
13
|
-
width?: number;
|
|
14
|
-
height?: number;
|
|
15
|
-
options?: any;
|
|
16
|
-
context?: any;
|
|
17
|
-
}) => Promise</*elided*/ any>>;
|
|
9
|
+
}) => Promise<unknown>;
|
|
@@ -1,117 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.pdf = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
const protocol = 'http';
|
|
8
|
-
const host = 'localhost';
|
|
9
|
-
const path = '/internal-board-service-view';
|
|
10
|
-
const pdf = async ({ id = '', model = null, data = null, width: w = 0, height: h = 0, options = {}, context = {} } = {}) => {
|
|
11
|
-
const browser = (await (0, headless_pool_for_board_js_1.getHeadlessPool)().acquire());
|
|
12
|
-
if (!browser) {
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
const { domain, user } = context.state;
|
|
16
|
-
var { model, base } = await (0, headless_model_js_1.headlessModel)({ domain, id, model });
|
|
17
|
-
const [fontsToUse, fontStyles] = await (0, fonts_js_1.fonts)(domain);
|
|
18
|
-
model.fonts = fontsToUse;
|
|
19
|
-
model.fontStyles = fontStyles;
|
|
20
|
-
let { width, height } = model;
|
|
21
|
-
width = Number(width);
|
|
22
|
-
height = Number(height);
|
|
23
|
-
if (!w) {
|
|
24
|
-
w = width;
|
|
25
|
-
}
|
|
26
|
-
if (!h) {
|
|
27
|
-
h = height;
|
|
28
|
-
}
|
|
29
|
-
let ratio = Math.min(w / width, h / height);
|
|
30
|
-
width = Math.floor(width * ratio);
|
|
31
|
-
height = Math.floor(height * ratio);
|
|
32
|
-
const port = process.env.PORT ? `:${process.env.PORT}` : '';
|
|
33
|
-
const url = `${protocol}://${host}${port}${path}`;
|
|
34
|
-
const page = await browser.newPage();
|
|
35
|
-
try {
|
|
36
|
-
/* @remember-me width, height should be a integer */
|
|
37
|
-
await page.setViewport({ width, height });
|
|
38
|
-
await page.setRequestInterception(true);
|
|
39
|
-
page.on('console', async (msg) => {
|
|
40
|
-
const args = await Promise.all(msg.args().map(arg => arg.jsonValue().catch(() => undefined)));
|
|
41
|
-
if (args.some(a => a !== undefined)) {
|
|
42
|
-
console.log(`[headless ${msg.type()}]`, ...args.filter(a => a !== undefined));
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
const text = msg.text();
|
|
46
|
-
if (text)
|
|
47
|
-
console.log(`[headless ${msg.type()}]`, text);
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
page.on('pageerror', error => {
|
|
51
|
-
console.log(`[headless pageerror] ${error.message}`);
|
|
52
|
-
console.log(error.stack);
|
|
53
|
-
});
|
|
54
|
-
page.on('error', error => {
|
|
55
|
-
console.log(`[headless fault] ${error}`);
|
|
56
|
-
console.log(error.stack);
|
|
57
|
-
});
|
|
58
|
-
page.on('requestfailed', request => {
|
|
59
|
-
console.log('Request failed:', request.url());
|
|
60
|
-
});
|
|
61
|
-
const token = await user?.sign(); // TODO improve performance
|
|
62
|
-
page.on('request', request => {
|
|
63
|
-
if (request.url() === url) {
|
|
64
|
-
request.continue({
|
|
65
|
-
method: 'POST',
|
|
66
|
-
headers: {
|
|
67
|
-
'Content-Type': 'application/json',
|
|
68
|
-
'x-things-factory-domain': domain?.subdomain,
|
|
69
|
-
Authorization: 'Bearer ' + token
|
|
70
|
-
},
|
|
71
|
-
postData: JSON.stringify({
|
|
72
|
-
model,
|
|
73
|
-
base
|
|
74
|
-
})
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
else if (request.url().startsWith(`${protocol}://${host}${port}`)) {
|
|
78
|
-
request.continue({
|
|
79
|
-
headers: {
|
|
80
|
-
...request.headers(),
|
|
81
|
-
'x-things-factory-domain': domain?.subdomain,
|
|
82
|
-
Authorization: 'Bearer ' + token
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
request.continue();
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
await page.goto(url);
|
|
91
|
-
await page.evaluate(async (data) => {
|
|
92
|
-
if (data) {
|
|
93
|
-
// @ts-ignore
|
|
94
|
-
s.data = data;
|
|
95
|
-
}
|
|
96
|
-
// data 주입 후 강제 지연시킴.
|
|
97
|
-
return new Promise(resolve => {
|
|
98
|
-
// @ts-ignore
|
|
99
|
-
requestAnimationFrame(() => resolve());
|
|
100
|
-
});
|
|
101
|
-
}, data);
|
|
102
|
-
const pdf = await page.pdf({
|
|
103
|
-
format: 'A4',
|
|
104
|
-
...options
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
catch (error) {
|
|
108
|
-
console.log(error);
|
|
109
|
-
}
|
|
110
|
-
finally {
|
|
111
|
-
await page.close();
|
|
112
|
-
(0, headless_pool_for_board_js_1.getHeadlessPool)().release(browser);
|
|
113
|
-
}
|
|
114
|
-
return exports.pdf;
|
|
4
|
+
const headless_render_js_1 = require("./headless-render.js");
|
|
5
|
+
const pdf = async ({ id = '', model = null, data = null, width = 0, height = 0, options = {}, context = {} } = {}) => {
|
|
6
|
+
return (0, headless_render_js_1.withHeadlessPage)({ id, model, data, width, height, options, context }, page => page.pdf({ format: 'A4', ...options }));
|
|
115
7
|
};
|
|
116
8
|
exports.pdf = pdf;
|
|
117
9
|
//# sourceMappingURL=pdf.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pdf.js","sourceRoot":"","sources":["../../server/controllers/pdf.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"pdf.js","sourceRoot":"","sources":["../../server/controllers/pdf.ts"],"names":[],"mappings":";;;AAAA,6DAAuD;AAEhD,MAAM,GAAG,GAAG,KAAK,EAAE,EACxB,EAAE,GAAG,EAAE,EACP,KAAK,GAAG,IAAI,EACZ,IAAI,GAAG,IAAI,EACX,KAAK,GAAG,CAAC,EACT,MAAM,GAAG,CAAC,EACV,OAAO,GAAG,EAAS,EACnB,OAAO,GAAG,EAAS,KACjB,EAAE,EAAE,EAAE;IACR,OAAO,IAAA,qCAAgB,EACrB,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,EACpD,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC,CAC/C,CAAA;AACH,CAAC,CAAA;AAbY,QAAA,GAAG,OAaf","sourcesContent":["import { withHeadlessPage } from './headless-render.js'\n\nexport const pdf = async ({\n id = '',\n model = null,\n data = null,\n width = 0,\n height = 0,\n options = {} as any,\n context = {} as any\n} = {}) => {\n return withHeadlessPage(\n { id, model, data, width, height, options, context },\n page => page.pdf({ format: 'A4', ...options })\n )\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const screenshot: ({ id, model, data, width
|
|
1
|
+
export declare const screenshot: ({ id, model, data, width, height, options, isThumbnail, context, draft }?: {
|
|
2
2
|
id?: string;
|
|
3
3
|
model?: any;
|
|
4
4
|
data?: any;
|
|
@@ -8,4 +8,4 @@ export declare const screenshot: ({ id, model, data, width: w, height: h, option
|
|
|
8
8
|
isThumbnail?: boolean;
|
|
9
9
|
context?: any;
|
|
10
10
|
draft?: boolean;
|
|
11
|
-
}) => Promise<
|
|
11
|
+
}) => Promise<unknown>;
|