@onlineapps/cookbook-template-helpers 2.0.0 → 2.0.2
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/README.md +12 -1
- package/package.json +12 -6
- package/src/helpers/fileHelpers.js +44 -20
package/README.md
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
> Status: current
|
|
2
|
+
> Owns: the helper functions a cookbook template variable may call
|
|
3
|
+
|
|
4
|
+
<!-- BEGIN GENERATED: library-uniform — regenerate: npx oa-sync-template readme-uniform --all -->
|
|
5
|
+
Uniform: [library/orchestration](../../connector/conn-orch-validator/manifests/library.manifest.json)
|
|
6
|
+
|
|
7
|
+
Duty sections that apply:
|
|
8
|
+
|
|
9
|
+
- `all`: L-MAIN, L-ENGINES, L-TESTS, L-TEST-SCRIPT, L-PACK-TESTS, L-PINS, L-NO-FILE-RANGE, L-CHANGELOG, L-README, L-README-REGION, L-CONSUMER
|
|
10
|
+
<!-- END GENERATED: library-uniform -->
|
|
11
|
+
|
|
1
12
|
# @onlineapps/cookbook-template-helpers
|
|
2
13
|
|
|
3
14
|
Template helper functions for cookbook variable resolution. Helper functions enable data transformations directly in cookbook template variables.
|
|
@@ -100,7 +111,7 @@ if (typeof helperFn !== 'function') {
|
|
|
100
111
|
balíček exportuje. Neznámý helper je tvrdá chyba, ne prázdná hodnota.
|
|
101
112
|
|
|
102
113
|
Živý cookbook, který touhle cestou prochází:
|
|
103
|
-
[`infra/api_doorman/cookbooks/tester-helpers.json`](../../../infra/api_doorman/cookbooks/tester-helpers.json)
|
|
114
|
+
[`infra/api_doorman/static/cookbooks/tester-helpers.json`](../../../infra/api_doorman/static/cookbooks/tester-helpers.json)
|
|
104
115
|
— volá `normalizeString`, `webalizeString`, `string2file` i `file2string`.
|
|
105
116
|
|
|
106
117
|
## Adding a Helper
|
package/package.json
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onlineapps/cookbook-template-helpers",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "Template helper functions for cookbook variable resolution - string2file, file2string, and more",
|
|
5
|
+
"oa": {
|
|
6
|
+
"category": "orchestration"
|
|
7
|
+
},
|
|
5
8
|
"main": "src/index.js",
|
|
6
9
|
"scripts": {
|
|
7
|
-
"test": "
|
|
10
|
+
"test": "npm run test:unit",
|
|
11
|
+
"test:unit": "jest tests/unit",
|
|
8
12
|
"test:watch": "jest --watch",
|
|
9
13
|
"test:coverage": "jest --coverage",
|
|
10
|
-
"docs": "jsdoc2md --files src/**/*.js > API.md"
|
|
14
|
+
"docs": "jsdoc2md --files 'src/**/*.js' > API.md.tmp && mv API.md.tmp API.md || (rm -f API.md.tmp; exit 1)"
|
|
11
15
|
},
|
|
12
16
|
"keywords": [
|
|
13
17
|
"cookbook",
|
|
@@ -19,13 +23,15 @@
|
|
|
19
23
|
"author": "OnlineApps",
|
|
20
24
|
"license": "PROPRIETARY",
|
|
21
25
|
"dependencies": {
|
|
22
|
-
"@onlineapps/content-resolver": "
|
|
26
|
+
"@onlineapps/content-resolver": "4.0.1",
|
|
27
|
+
"@onlineapps/logger-contract": "2.0.0"
|
|
23
28
|
},
|
|
24
29
|
"devDependencies": {
|
|
25
|
-
"jest": "29.7.0"
|
|
30
|
+
"jest": "29.7.0",
|
|
31
|
+
"jsdoc-to-markdown": "^8.0.0"
|
|
26
32
|
},
|
|
27
33
|
"engines": {
|
|
28
|
-
"node": ">=
|
|
34
|
+
"node": ">=24.0.0 <25"
|
|
29
35
|
},
|
|
30
36
|
"files": [
|
|
31
37
|
"src"
|
|
@@ -6,10 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
const ContentResolver = require('@onlineapps/content-resolver');
|
|
9
|
-
|
|
10
|
-
// The logger methods `ContentResolver` requires of the object this module hands
|
|
11
|
-
// it — the order is the order the error message lists them in.
|
|
12
|
-
const LOGGER_METHODS = ['info', 'warn', 'error', 'debug'];
|
|
9
|
+
const { assertLogger } = require('@onlineapps/logger-contract');
|
|
13
10
|
|
|
14
11
|
/**
|
|
15
12
|
* Normalize string: remove control/unsafe chars, keep letters (incl. diacritics), numbers,
|
|
@@ -76,22 +73,11 @@ function getContentResolver(helperContext) {
|
|
|
76
73
|
// passed this gate and failed one frame down — delayed validation, forbidden
|
|
77
74
|
// by architecture-principles.md §4. Owner confirmation:
|
|
78
75
|
// api/docs/governance/confirmations/connector-logger-contract.md 001.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const missing = LOGGER_METHODS.filter((method) => typeof helperContext.logger[method] !== 'function');
|
|
88
|
-
if (missing.length > 0) {
|
|
89
|
-
throw new Error(
|
|
90
|
-
'[cookbook-template-helpers] logger is incomplete - Expected: info, warn, error, debug as functions; '
|
|
91
|
-
+ `missing: ${missing.join(', ')}. `
|
|
92
|
-
+ 'Fix: pass a logger implementing all four.'
|
|
93
|
-
);
|
|
94
|
-
}
|
|
76
|
+
assertLogger(
|
|
77
|
+
'cookbook-template-helpers',
|
|
78
|
+
helperContext.logger,
|
|
79
|
+
'the resolver this helper builds writes where the service writes'
|
|
80
|
+
);
|
|
95
81
|
|
|
96
82
|
return new ContentResolver({
|
|
97
83
|
context: { workflow_id, step_id },
|
|
@@ -99,8 +85,45 @@ function getContentResolver(helperContext) {
|
|
|
99
85
|
});
|
|
100
86
|
}
|
|
101
87
|
|
|
88
|
+
/**
|
|
89
|
+
* The declared type of an inline descriptor's bytes, refused here if it is not
|
|
90
|
+
* one.
|
|
91
|
+
*
|
|
92
|
+
* `string2file()` turns those bytes into an object in storage, and the
|
|
93
|
+
* descriptor it returns declares that object's type. A type nobody stated
|
|
94
|
+
* therefore cannot travel on: the frame below fills the hole from the filename
|
|
95
|
+
* extension, so the object ends up carrying a guess presented as a fact
|
|
96
|
+
* (measured 2026-09-08 on the live path — `{ filename: 'payload.json' }` with no
|
|
97
|
+
* `content_type` came back `application/json`, and `content_type: null` came
|
|
98
|
+
* back `text/plain`).
|
|
99
|
+
*
|
|
100
|
+
* Required input, then: not derived and not defaulted
|
|
101
|
+
* (`architecture-principles.md` §3), and stated by whoever knows what the bytes
|
|
102
|
+
* are — the caller.
|
|
103
|
+
*
|
|
104
|
+
* @private
|
|
105
|
+
* @param {*} contentType - The `content_type` the inline descriptor carries.
|
|
106
|
+
* @throws {Error} If it is not a non-empty string.
|
|
107
|
+
*/
|
|
108
|
+
function assertDeclaredContentType(contentType) {
|
|
109
|
+
if (typeof contentType === 'string' && contentType.trim() !== '') {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
throw new Error(
|
|
114
|
+
'[string2file] Missing required input - "content_type" is required on an inline descriptor: '
|
|
115
|
+
+ 'it is the type written to storage and it is never guessed. '
|
|
116
|
+
+ 'Fix: pass content_type (e.g. text/plain, application/json).'
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
102
120
|
/**
|
|
103
121
|
* Convert string or inline descriptor to file descriptor (uploads via ContentResolver).
|
|
122
|
+
*
|
|
123
|
+
* An inline descriptor MUST declare `content_type` (see
|
|
124
|
+
* `assertDeclaredContentType`). A raw string declares nothing, so the helper
|
|
125
|
+
* names the file itself and states the type of the file it named.
|
|
126
|
+
*
|
|
104
127
|
* @param {string|Object} input
|
|
105
128
|
* @param {Object} context
|
|
106
129
|
* @returns {Promise<Object>}
|
|
@@ -123,6 +146,7 @@ async function string2file(input, context) {
|
|
|
123
146
|
if (typeof content !== 'string') {
|
|
124
147
|
throw new Error('[string2file] Inline descriptor content must be a string');
|
|
125
148
|
}
|
|
149
|
+
assertDeclaredContentType(input.content_type);
|
|
126
150
|
return await resolver.createDescriptor(content, {
|
|
127
151
|
filename: input.filename,
|
|
128
152
|
content_type: input.content_type,
|