@onlineapps/cookbook-template-helpers 1.0.15 → 2.0.1
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 +21 -1
- package/package.json +12 -6
- package/src/helpers/fileHelpers.js +50 -3
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.
|
|
@@ -49,6 +60,15 @@ Převede file/inline descriptor na string (přes ContentResolver). File stáhne
|
|
|
49
60
|
async function file2string(descriptor, context)
|
|
50
61
|
```
|
|
51
62
|
|
|
63
|
+
### Helper context — logger
|
|
64
|
+
|
|
65
|
+
Oba descriptor helpery si staví `ContentResolver`, pokud jim v kontextu nepředáš
|
|
66
|
+
hotový `context.contentResolver`. V tom případě je `context.logger` **povinný** a
|
|
67
|
+
musí mít všechny čtyři metody: `info()`, `warn()`, `error()`, `debug()` — přesně
|
|
68
|
+
to, co vyžaduje `@onlineapps/content-resolver` a za ním `@onlineapps/conn-base-storage`.
|
|
69
|
+
Chybějící logger i logger neúplný padají hned v `getContentResolver()` a hláška
|
|
70
|
+
jmenuje chybějící metodu; žádný `console` fallback neexistuje.
|
|
71
|
+
|
|
52
72
|
## Usage in Cookbook
|
|
53
73
|
|
|
54
74
|
Helpers jsou k dispozici při resolvování template proměnných:
|
|
@@ -91,7 +111,7 @@ if (typeof helperFn !== 'function') {
|
|
|
91
111
|
balíček exportuje. Neznámý helper je tvrdá chyba, ne prázdná hodnota.
|
|
92
112
|
|
|
93
113
|
Živý cookbook, který touhle cestou prochází:
|
|
94
|
-
[`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)
|
|
95
115
|
— volá `normalizeString`, `webalizeString`, `string2file` i `file2string`.
|
|
96
116
|
|
|
97
117
|
## Adding a Helper
|
package/package.json
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onlineapps/cookbook-template-helpers",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
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.0",
|
|
27
|
+
"@onlineapps/logger-contract": "1.1.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,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
const ContentResolver = require('@onlineapps/content-resolver');
|
|
9
|
+
const { assertLogger } = require('@onlineapps/logger-contract');
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Normalize string: remove control/unsafe chars, keep letters (incl. diacritics), numbers,
|
|
@@ -66,9 +67,17 @@ function getContentResolver(helperContext) {
|
|
|
66
67
|
helperContext.data?.step_id ||
|
|
67
68
|
null;
|
|
68
69
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
// The logger goes straight into `ContentResolver`, which demands all four
|
|
71
|
+
// methods (content-resolver src/index.js; conn-base-storage 3.0.0 behind it).
|
|
72
|
+
// Until 2026-09-03 only `warn()` was checked here, so a three-method logger
|
|
73
|
+
// passed this gate and failed one frame down — delayed validation, forbidden
|
|
74
|
+
// by architecture-principles.md §4. Owner confirmation:
|
|
75
|
+
// api/docs/governance/confirmations/connector-logger-contract.md 001.
|
|
76
|
+
assertLogger(
|
|
77
|
+
'cookbook-template-helpers',
|
|
78
|
+
helperContext.logger,
|
|
79
|
+
'the resolver this helper builds writes where the service writes'
|
|
80
|
+
);
|
|
72
81
|
|
|
73
82
|
return new ContentResolver({
|
|
74
83
|
context: { workflow_id, step_id },
|
|
@@ -76,8 +85,45 @@ function getContentResolver(helperContext) {
|
|
|
76
85
|
});
|
|
77
86
|
}
|
|
78
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
|
+
|
|
79
120
|
/**
|
|
80
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
|
+
*
|
|
81
127
|
* @param {string|Object} input
|
|
82
128
|
* @param {Object} context
|
|
83
129
|
* @returns {Promise<Object>}
|
|
@@ -100,6 +146,7 @@ async function string2file(input, context) {
|
|
|
100
146
|
if (typeof content !== 'string') {
|
|
101
147
|
throw new Error('[string2file] Inline descriptor content must be a string');
|
|
102
148
|
}
|
|
149
|
+
assertDeclaredContentType(input.content_type);
|
|
103
150
|
return await resolver.createDescriptor(content, {
|
|
104
151
|
filename: input.filename,
|
|
105
152
|
content_type: input.content_type,
|