Skip to content

Commit bfcb385

Browse files
committed
format
1 parent 8f30335 commit bfcb385

24 files changed

+1931
-1939
lines changed

.cdsprettier.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"maxDocCommentLine": 80,
3+
"formatDocComments": true,
4+
"tabSize": 2,
5+
"alignPostAnnotations": false,
6+
"alignColonsInAnnotations": false,
7+
"alignValuesInAnnotations": false
8+
}

.prettierrc.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module.exports = {
2+
tabWidth: 2,
3+
semi: true,
4+
printWidth: 100,
5+
trailingComma: "all",
6+
};

CHANGELOG.md

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,29 +36,26 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
3636
- Fixed handling of unmanaged composition of many
3737
- Proper casing of the operation enum type
3838

39-
4039
### Changed
4140

4241
- Added warning and mitigation for multi-tenant deployments with MTX
4342
- Added a disclaimer of upcoming new version having a minimum requirement of CDS 8.6 for multitenancy fix
4443
- Changed the default limit on non-HANA databases from 255 to 5000 characters for all String values
4544
- Updated peer dependency from CDS7 to CDS8
4645

47-
4846
## Version 1.0.7 - 20.08.24
4947

5048
### Added
5149

52-
- A global switch to preserve change logs for deleted data
53-
- For hierarchical entities, a method to determine their structure and a flag to indicate whether it is a root entity was introduced. For child entities, information about the parent is recorded.
54-
50+
- A global switch to preserve change logs for deleted data
51+
- For hierarchical entities, a method to determine their structure and a flag to indicate whether it is a root entity was introduced. For child entities, information about the parent is recorded.
5552

5653
### Fixed
5754

5855
- CDS 8 does not support queries for draft-enabled entities on the application service anymore. This was causing: SqliteError: NOT NULL constraint failed: (...).DraftAdministrativeData_DraftUUID
5956
- CDS 8 deprecated cds.transaction, causing change logs of nested documents to be wrong, replaced with req.event
6057
- CDS 8 rejects all direct CRUD requests for auto-exposed Compositions in non-draft cases. This was affecting test cases, since the ChangeView falls into this category
61-
- req._params and req.context are not official APIs and stopped working with CDS 8, replaced with official APIs
58+
- req.\_params and req.context are not official APIs and stopped working with CDS 8, replaced with official APIs
6259
- When running test cases in CDS 8, some requests failed with a status code of 404
6360
- ServiceEntity is not captured in the ChangeLog table in some cases
6461
- When modeling an inline entity, a non-existent association and parent ID was recorded
@@ -70,22 +67,21 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
7067
- Data marked as personal data using data privacy annotations won't get change-tracked anymore to satisfy product standards
7168
- Restructured Documentation
7269

73-
7470
## Version 1.0.6 - 29.04.24
7571

7672
### Fixed
7773

78-
- Storage of wrong ObjectID in some special scenarios
79-
- Missing localization of managed fields
80-
- Views without keys won't get the association and UI facet pushed anymore
74+
- Storage of wrong ObjectID in some special scenarios
75+
- Missing localization of managed fields
76+
- Views without keys won't get the association and UI facet pushed anymore
8177

8278
### Added
8379

84-
- A method to disable automatic generation of the UI Facet
80+
- A method to disable automatic generation of the UI Facet
8581

8682
### Changed
8783

88-
- Improved documentation of the @changelog Annotation
84+
- Improved documentation of the @changelog Annotation
8985

9086
## Version 1.0.5 - 15.01.24
9187

@@ -112,7 +108,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
112108

113109
### Added
114110

115-
- Added note about using `SAPUI5 v1.120.0` or later for proper lazy loading of the *Change History* table.
111+
- Added note about using `SAPUI5 v1.120.0` or later for proper lazy loading of the _Change History_ table.
116112
- In README, add warning about tracking personal data.
117113

118114
### Changed
@@ -141,4 +137,3 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
141137
### Added
142138

143139
- Initial release
144-

CONTRIBUTING.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ Instances of abusive, harassing, or otherwise unacceptable behavior may be repor
1010

1111
We use GitHub to manage reviews of pull requests.
1212

13-
* If you are a new contributor, see: [Steps to Contribute](#steps-to-contribute)
13+
- If you are a new contributor, see: [Steps to Contribute](#steps-to-contribute)
1414

15-
* Before implementing your change, create an issue that describes the problem you would like to solve or the code that should be enhanced. Please note that you are willing to work on that issue.
15+
- Before implementing your change, create an issue that describes the problem you would like to solve or the code that should be enhanced. Please note that you are willing to work on that issue.
1616

17-
* The team will review the issue and decide whether it should be implemented as a pull request. In that case, they will assign the issue to you. If the team decides against picking up the issue, the team will post a comment with an explanation.
17+
- The team will review the issue and decide whether it should be implemented as a pull request. In that case, they will assign the issue to you. If the team decides against picking up the issue, the team will post a comment with an explanation.
1818

1919
## Steps to Contribute
2020

@@ -28,11 +28,11 @@ You are welcome to contribute code in order to fix a bug or to implement a new f
2828

2929
The following rule governs code contributions:
3030

31-
* Contributions must be licensed under the [Apache 2.0 License](./LICENSE)
32-
* Due to legal reasons, contributors will be asked to accept a Developer Certificate of Origin (DCO) when they create the first pull request to this project. This happens in an automated fashion during the submission process. SAP uses [the standard DCO text of the Linux Foundation](https://developercertificate.org/).
31+
- Contributions must be licensed under the [Apache 2.0 License](./LICENSE)
32+
- Due to legal reasons, contributors will be asked to accept a Developer Certificate of Origin (DCO) when they create the first pull request to this project. This happens in an automated fashion during the submission process. SAP uses [the standard DCO text of the Linux Foundation](https://developercertificate.org/).
3333

3434
## Issues and Planning
3535

36-
* We use GitHub issues to track bugs and enhancement requests.
36+
- We use GitHub issues to track bugs and enhancement requests.
3737

38-
* Please provide as much context as possible when you open an issue. The information you provide must be comprehensive enough to reproduce that issue for the assignee.
38+
- Please provide as much context as possible when you open an issue. The information you provide must be comprehensive enough to reproduce that issue for the assignee.

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ Usage of this plugin requires a valid subscription of the [SAP Print Service](ht
2323
To use this plugin to print documents there are two main steps:
2424

2525
1. Add required annotations to your CDS model.
26-
a. Entity
27-
b. Action
26+
a. Entity
27+
b. Action
2828
2. Configure print queues to select from available options. (Optional, but recommended)
2929

3030
### Annotations in CDS model
@@ -47,6 +47,7 @@ entity Incidents : cuid {
4747
- `@print.fileName`: Annotates the field containing the name of the document
4848

4949
#### Annotation of actions
50+
5051
Sending a print request works via bound actions annotated with `@print`. The parameter of the action are used to define the print job details.
5152

5253
```cds
@@ -72,7 +73,7 @@ service IncidentService {
7273
qnameID: String,
7374
@print.numberOfCopies
7475
@UI.ParameterDefaultValue : 1
75-
copies: Integer
76+
copies: Integer
7677
);
7778
};
7879
}
@@ -82,7 +83,8 @@ service IncidentService {
8283
- `@print.queue`: Annotates the parameter specifying the print queue. It is recommended to use a value help for this parameter to select from available print queues. See TOOD
8384
- `@print.numberOfCopies`: Annotates the parameter specifying the number of copies to print
8485

85-
### Queues
86+
### Queues
87+
8688
Every print request needs to specify a print queue it is send to. It is recommended to provide a value help for the print queue selection. To enbale this, define an entity as projection on the `Queues` entity provided by the print service. When this projection is in place, the plugin automatically provides the available print queues coming from the print service.
8789

8890
```cds

cds-plugin.js

Lines changed: 88 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
const cds = require('@sap/cds');
2-
const LOG = cds.log('print');
1+
const cds = require("@sap/cds");
2+
const LOG = cds.log("print");
33

44
const PRINT = "@print";
55
const PRINT_NUMBER_OF_COPIES = "@print.numberOfCopies";
@@ -10,100 +10,96 @@ const PRINT_FILE_CONTENT = "@print.fileContent";
1010
const QUEUE_ENTITY_NAME = "sap.print.Queues";
1111

1212
cds.once("served", async () => {
13-
// Iterate over all services
14-
for (let srv of cds.services) {
15-
// Iterate over all entities in the service
16-
for (let entity of srv.entities) {
17-
18-
if (entity.projection?.from.ref[0] === QUEUE_ENTITY_NAME) {
19-
const printer = await cds.connect.to("print");
20-
21-
srv.after('READ', entity, async (_, req) => {
22-
const q = await printer.getQueues();
23-
q.forEach((item, index) => {
24-
req.results[index] = { ID: item.ID };
25-
});
26-
req.results.$count = q.length;
27-
return;
28-
});
29-
}
30-
31-
if(!entity.actions) continue
32-
33-
for(const action of entity.actions) {
34-
if(action[PRINT]) {
35-
36-
const printer = await cds.connect.to("print");
37-
38-
const { numberOfCopiesAttribute, queueIDAttribute, fileNameAttribute, contentAttribute } = getPrintParamsAttributeFromAction(entity, action);
39-
40-
srv.on(action.name, entity, async (req) => {
41-
42-
43-
const numberOfCopies = req.data[numberOfCopiesAttribute];
44-
const queueID = req.data[queueIDAttribute];
45-
46-
const object = await SELECT.one.from(req.subject).columns([fileNameAttribute, contentAttribute]);
47-
48-
if(!object) return req.reject(404, `Object not found for printing.`);
49-
if(!numberOfCopies) return req.reject(400, `Please specify number of copies to print.`);
50-
if(!queueID) return req.reject(400, `Please specify print queue.`);
51-
52-
const streamToBase64 = async (stream) => {
53-
const chunks = [];
54-
for await (const chunk of stream) {
55-
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
56-
}
57-
return Buffer.concat(chunks).toString('base64');
58-
};
59-
try {
60-
61-
await printer.print({
62-
qname: queueID,
63-
numberOfCopies: numberOfCopies,
64-
docsToPrint: [{
65-
fileName: object[fileNameAttribute],
66-
content: await streamToBase64(object[contentAttribute]),
67-
isMainDocument: true
68-
}]
69-
})
70-
71-
return req.info({
72-
status: 200,
73-
message: `Print job for file ${object[fileNameAttribute]} sent to queue ${queueID} for ${numberOfCopies} copies.`
74-
});
75-
76-
}
77-
catch (error) {
78-
return req.reject(500, `Error: ${error.message ?? "Unknown error"}`);
79-
}
80-
81-
82-
});
83-
}
13+
// Iterate over all services
14+
for (let srv of cds.services) {
15+
// Iterate over all entities in the service
16+
for (let entity of srv.entities) {
17+
if (entity.projection?.from.ref[0] === QUEUE_ENTITY_NAME) {
18+
const printer = await cds.connect.to("print");
19+
20+
srv.after("READ", entity, async (_, req) => {
21+
const q = await printer.getQueues();
22+
q.forEach((item, index) => {
23+
req.results[index] = { ID: item.ID };
24+
});
25+
req.results.$count = q.length;
26+
return;
27+
});
28+
}
29+
30+
if (!entity.actions) continue;
31+
32+
for (const action of entity.actions) {
33+
if (action[PRINT]) {
34+
const printer = await cds.connect.to("print");
35+
36+
const { numberOfCopiesAttribute, queueIDAttribute, fileNameAttribute, contentAttribute } =
37+
getPrintParamsAttributeFromAction(entity, action);
38+
39+
srv.on(action.name, entity, async (req) => {
40+
const numberOfCopies = req.data[numberOfCopiesAttribute];
41+
const queueID = req.data[queueIDAttribute];
42+
43+
const object = await SELECT.one
44+
.from(req.subject)
45+
.columns([fileNameAttribute, contentAttribute]);
46+
47+
if (!object) return req.reject(404, `Object not found for printing.`);
48+
if (!numberOfCopies)
49+
return req.reject(400, `Please specify number of copies to print.`);
50+
if (!queueID) return req.reject(400, `Please specify print queue.`);
51+
52+
const streamToBase64 = async (stream) => {
53+
const chunks = [];
54+
for await (const chunk of stream) {
55+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
56+
}
57+
return Buffer.concat(chunks).toString("base64");
58+
};
59+
try {
60+
await printer.print({
61+
qname: queueID,
62+
numberOfCopies: numberOfCopies,
63+
docsToPrint: [
64+
{
65+
fileName: object[fileNameAttribute],
66+
content: await streamToBase64(object[contentAttribute]),
67+
isMainDocument: true,
68+
},
69+
],
70+
});
71+
72+
return req.info({
73+
status: 200,
74+
message: `Print job for file ${object[fileNameAttribute]} sent to queue ${queueID} for ${numberOfCopies} copies.`,
75+
});
76+
} catch (error) {
77+
return req.reject(500, `Error: ${error.message ?? "Unknown error"}`);
8478
}
79+
});
8580
}
81+
}
8682
}
83+
}
8784
});
8885

8986
function getPrintParamsAttributeFromAction(entity, action) {
90-
91-
const copiesElement = Object.values(action.params).find(el => el[PRINT_NUMBER_OF_COPIES]);
92-
const queueElement = Object.values(action.params).find(el => el[PRINT_QUEUE]);
93-
94-
const fileName = Object.values(entity.elements).find(el => el[PRINT_FILE_NAME]);
95-
const content = Object.values(entity.elements).find(el => el[PRINT_FILE_CONTENT]);
96-
97-
98-
if(!copiesElement || !queueElement, !fileName || !content) {
99-
cds.error(`Print action ${action.name} is missing required annotations. Make sure @print.numberOfCopies, @print.queue are present in the action and @print.fileName and @print.fileContent are present in the entity.`);
100-
}
101-
102-
return {
103-
numberOfCopiesAttribute: copiesElement.name,
104-
queueIDAttribute: queueElement.name,
105-
fileNameAttribute: fileName.name,
106-
contentAttribute: content.name
107-
};
87+
const copiesElement = Object.values(action.params).find((el) => el[PRINT_NUMBER_OF_COPIES]);
88+
const queueElement = Object.values(action.params).find((el) => el[PRINT_QUEUE]);
89+
90+
const fileName = Object.values(entity.elements).find((el) => el[PRINT_FILE_NAME]);
91+
const content = Object.values(entity.elements).find((el) => el[PRINT_FILE_CONTENT]);
92+
93+
if ((!copiesElement || !queueElement, !fileName || !content)) {
94+
cds.error(
95+
`Print action ${action.name} is missing required annotations. Make sure @print.numberOfCopies, @print.queue are present in the action and @print.fileName and @print.fileContent are present in the entity.`,
96+
);
97+
}
98+
99+
return {
100+
numberOfCopiesAttribute: copiesElement.name,
101+
queueIDAttribute: queueElement.name,
102+
fileNameAttribute: fileName.name,
103+
contentAttribute: content.name,
104+
};
108105
}
109-

jest-integration.config.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const integrationconfig = {
2-
verbose: true,
3-
testTimeout: 100000,
4-
testMatch: ["**/test/integration/annotation.test.js"]
5-
};
6-
7-
module.exports = integrationconfig;
2+
verbose: true,
3+
testTimeout: 100000,
4+
testMatch: ["**/test/integration/annotation.test.js"],
5+
};
6+
7+
module.exports = integrationconfig;

jest.config.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
const config = {
22
verbose: true,
33
testTimeout: 100000,
4-
testMatch: ["**/test/lib/**/*.test.js","**/test/srv/**/*.test.js"],
5-
collectCoverageFrom: ["**/lib/**/*","srv/**/*"],
4+
testMatch: ["**/test/lib/**/*.test.js", "**/test/srv/**/*.test.js"],
5+
collectCoverageFrom: ["**/lib/**/*", "srv/**/*"],
66
coveragePathIgnorePatterns: ["node_modules", "<rootDir>/lib/persistence"],
77
coverageReporters: ["lcov", "text", "text-summary"],
88
coverageThreshold: {
99
global: {
1010
branches: 90,
1111
lines: 90,
1212
statements: 90,
13-
functions: 90
13+
functions: 90,
1414
},
15-
}
15+
},
1616
};
1717

18-
module.exports = config;
18+
module.exports = config;

lib/printUtil.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
21
module.exports = { print, getQueues };

0 commit comments

Comments
 (0)