@lowdefy/build 4.6.0 → 4.7.0

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/index.js CHANGED
@@ -12,7 +12,7 @@
12
12
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
- */ import { BuildError, LowdefyInternalError } from '@lowdefy/errors';
15
+ */ import { BuildError, ConfigError, LowdefyInternalError } from '@lowdefy/errors';
16
16
  import createContext from './createContext.js';
17
17
  import createPluginTypesMap from './utils/createPluginTypesMap.js';
18
18
  import logCollectedErrors from './utils/logCollectedErrors.js';
@@ -62,13 +62,15 @@ async function build(options) {
62
62
  context
63
63
  });
64
64
  } catch (err) {
65
- // Handle ConfigError from buildRefs (e.g., missing _ref files)
66
- if (err.isLowdefyError) {
67
- context.handleError(err);
68
- throw new BuildError('Build failed with 1 error(s). See above for details.');
65
+ // Root lowdefy.yaml failure still throws from buildRefs collect it
66
+ if (err instanceof ConfigError) {
67
+ context.errors.push(err);
68
+ } else {
69
+ throw err;
69
70
  }
70
- throw err;
71
71
  }
72
+ // Stop if buildRefs collected any errors (YAML parse, missing files, etc.)
73
+ logCollectedErrors(context);
72
74
  // Build steps - collect all errors before stopping
73
75
  // addKeys runs first so testSchema has ~k markers for error location info
74
76
  tryBuildStep(addKeys, 'addKeys', {
package/dist/indexDev.js CHANGED
@@ -16,3 +16,4 @@
16
16
  export { default as buildPageJit } from './build/jit/buildPageJit.js';
17
17
  export { default as createPageRegistry } from './build/jit/createPageRegistry.js';
18
18
  export { default as createContext } from './createContext.js';
19
+ export { default as makeId } from './utils/makeId.js';
@@ -574,7 +574,6 @@ export default {
574
574
  },
575
575
  '~r': {},
576
576
  '~l': {},
577
- '~shallow': {},
578
577
  id: {
579
578
  type: 'string',
580
579
  errorMessage: {
@@ -20,6 +20,9 @@
20
20
  reset() {
21
21
  this.counter = 0;
22
22
  }
23
+ setCounter(value) {
24
+ this.counter = value;
25
+ }
23
26
  constructor(){
24
27
  this.counter = 0;
25
28
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lowdefy/build",
3
- "version": "4.6.0",
3
+ "version": "4.7.0",
4
4
  "license": "Apache-2.0",
5
5
  "description": "",
6
6
  "homepage": "https://lowdefy.com",
@@ -45,15 +45,15 @@
45
45
  "dist/*"
46
46
  ],
47
47
  "dependencies": {
48
- "@lowdefy/ajv": "4.6.0",
49
- "@lowdefy/blocks-basic": "4.6.0",
50
- "@lowdefy/blocks-loaders": "4.6.0",
51
- "@lowdefy/errors": "4.6.0",
52
- "@lowdefy/helpers": "4.6.0",
53
- "@lowdefy/node-utils": "4.6.0",
54
- "@lowdefy/nunjucks": "4.6.0",
55
- "@lowdefy/operators": "4.6.0",
56
- "@lowdefy/operators-js": "4.6.0",
48
+ "@lowdefy/ajv": "4.7.0",
49
+ "@lowdefy/blocks-basic": "4.7.0",
50
+ "@lowdefy/blocks-loaders": "4.7.0",
51
+ "@lowdefy/errors": "4.7.0",
52
+ "@lowdefy/helpers": "4.7.0",
53
+ "@lowdefy/node-utils": "4.7.0",
54
+ "@lowdefy/nunjucks": "4.7.0",
55
+ "@lowdefy/operators": "4.7.0",
56
+ "@lowdefy/operators-js": "4.7.0",
57
57
  "ajv": "8.12.0",
58
58
  "json5": "2.2.3",
59
59
  "yaml": "2.3.4",
@@ -61,41 +61,41 @@
61
61
  },
62
62
  "devDependencies": {
63
63
  "@jest/globals": "28.1.3",
64
- "@lowdefy/actions-core": "4.6.0",
65
- "@lowdefy/actions-pdf-make": "4.6.0",
66
- "@lowdefy/blocks-aggrid": "4.6.0",
67
- "@lowdefy/blocks-algolia": "4.6.0",
68
- "@lowdefy/blocks-antd": "4.6.0",
69
- "@lowdefy/blocks-color-selectors": "4.6.0",
70
- "@lowdefy/blocks-echarts": "4.6.0",
71
- "@lowdefy/blocks-google-maps": "4.6.0",
72
- "@lowdefy/blocks-markdown": "4.6.0",
73
- "@lowdefy/blocks-qr": "4.6.0",
74
- "@lowdefy/connection-axios-http": "4.6.0",
75
- "@lowdefy/connection-elasticsearch": "4.6.0",
76
- "@lowdefy/connection-test": "4.6.0",
77
- "@lowdefy/connection-google-sheets": "4.6.0",
78
- "@lowdefy/connection-knex": "4.6.0",
79
- "@lowdefy/connection-mongodb": "4.6.0",
80
- "@lowdefy/connection-redis": "4.6.0",
81
- "@lowdefy/connection-sendgrid": "4.6.0",
82
- "@lowdefy/connection-stripe": "4.6.0",
83
- "@lowdefy/operators-change-case": "4.6.0",
84
- "@lowdefy/operators-diff": "4.6.0",
85
- "@lowdefy/operators-jsonata": "4.6.0",
86
- "@lowdefy/operators-moment": "4.6.0",
87
- "@lowdefy/operators-mql": "4.6.0",
88
- "@lowdefy/operators-nunjucks": "4.6.0",
89
- "@lowdefy/operators-uuid": "4.6.0",
90
- "@lowdefy/operators-yaml": "4.6.0",
91
- "@lowdefy/plugin-auth0": "4.6.0",
92
- "@lowdefy/plugin-aws": "4.6.0",
93
- "@lowdefy/plugin-csv": "4.6.0",
94
- "@lowdefy/plugin-next-auth": "4.6.0",
64
+ "@lowdefy/actions-core": "4.7.0",
65
+ "@lowdefy/actions-pdf-make": "4.7.0",
66
+ "@lowdefy/blocks-aggrid": "4.7.0",
67
+ "@lowdefy/blocks-algolia": "4.7.0",
68
+ "@lowdefy/blocks-antd": "4.7.0",
69
+ "@lowdefy/blocks-color-selectors": "4.7.0",
70
+ "@lowdefy/blocks-echarts": "4.7.0",
71
+ "@lowdefy/blocks-google-maps": "4.7.0",
72
+ "@lowdefy/blocks-markdown": "4.7.0",
73
+ "@lowdefy/blocks-qr": "4.7.0",
74
+ "@lowdefy/connection-axios-http": "4.7.0",
75
+ "@lowdefy/connection-elasticsearch": "4.7.0",
76
+ "@lowdefy/connection-test": "4.7.0",
77
+ "@lowdefy/connection-google-sheets": "4.7.0",
78
+ "@lowdefy/connection-knex": "4.7.0",
79
+ "@lowdefy/connection-mongodb": "4.7.0",
80
+ "@lowdefy/connection-redis": "4.7.0",
81
+ "@lowdefy/connection-sendgrid": "4.7.0",
82
+ "@lowdefy/connection-stripe": "4.7.0",
83
+ "@lowdefy/operators-change-case": "4.7.0",
84
+ "@lowdefy/operators-diff": "4.7.0",
85
+ "@lowdefy/operators-jsonata": "4.7.0",
86
+ "@lowdefy/operators-moment": "4.7.0",
87
+ "@lowdefy/operators-mql": "4.7.0",
88
+ "@lowdefy/operators-nunjucks": "4.7.0",
89
+ "@lowdefy/operators-uuid": "4.7.0",
90
+ "@lowdefy/operators-yaml": "4.7.0",
91
+ "@lowdefy/plugin-auth0": "4.7.0",
92
+ "@lowdefy/plugin-aws": "4.7.0",
93
+ "@lowdefy/plugin-csv": "4.7.0",
94
+ "@lowdefy/plugin-next-auth": "4.7.0",
95
95
  "@swc/cli": "0.1.63",
96
96
  "@swc/core": "1.3.99",
97
97
  "@swc/jest": "0.2.29",
98
- "@lowdefy/logger": "4.6.0",
98
+ "@lowdefy/logger": "4.7.0",
99
99
  "jest": "28.1.3",
100
100
  "pino": "8.16.2"
101
101
  },
@@ -1,28 +0,0 @@
1
- /*
2
- Copyright 2020-2026 Lowdefy, Inc
3
-
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
7
-
8
- http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
15
- */ import { type } from '@lowdefy/helpers';
16
- import setNonEnumerableProperty from '../../utils/setNonEnumerableProperty.js';
17
- // Returns a serializer.copy reviver that sets ~r on all objects
18
- // that don't already have it, preserving original file references.
19
- function createRefReviver(refId) {
20
- return (_, value)=>{
21
- if (!type.isObject(value) && !type.isArray(value)) return value;
22
- if (value['~r'] === undefined) {
23
- setNonEnumerableProperty(value, '~r', refId);
24
- }
25
- return value;
26
- };
27
- }
28
- export default createRefReviver;
@@ -1,53 +0,0 @@
1
- /*
2
- Copyright 2020-2026 Lowdefy, Inc
3
-
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
7
-
8
- http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
15
- */ import { BuildParser } from '@lowdefy/operators';
16
- import operators from '@lowdefy/operators-js/operators/build';
17
- import collectDynamicIdentifiers from '../collectDynamicIdentifiers.js';
18
- import validateOperatorsDynamic from '../validateOperatorsDynamic.js';
19
- import collectExceptions from '../../utils/collectExceptions.js';
20
- // Validate and collect dynamic identifiers once at module load
21
- validateOperatorsDynamic({
22
- operators
23
- });
24
- const dynamicIdentifiers = collectDynamicIdentifiers({
25
- operators
26
- });
27
- function evaluateBuildOperators({ context, input, refDef, typeNames }) {
28
- const operatorsParser = new BuildParser({
29
- env: process.env,
30
- operators,
31
- dynamicIdentifiers,
32
- ...typeNames ? {
33
- typeNames
34
- } : {}
35
- });
36
- const { output, errors } = operatorsParser.parse({
37
- input,
38
- operatorPrefix: '_build.'
39
- });
40
- if (errors.length > 0) {
41
- errors.forEach((error)=>{
42
- // Resolve source file path for error location.
43
- // Two call sites: (1) recursiveBuild per-file where refDef.path is correct
44
- // but ~r isn't set yet (createRefReviver runs after), and (2) buildRefs
45
- // top-level where refDef is root lowdefy.yaml but ~r identifies the real
46
- // source file via refMap. The fallback to refDef.path handles case (1).
47
- error.filePath = error.refId ? context.refMap[error.refId]?.path : refDef.path;
48
- collectExceptions(context, error);
49
- });
50
- }
51
- return output;
52
- }
53
- export default evaluateBuildOperators;
@@ -1,42 +0,0 @@
1
- /*
2
- Copyright 2020-2026 Lowdefy, Inc
3
-
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
7
-
8
- http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
15
- */ import { serializer, type } from '@lowdefy/helpers';
16
- import makeRefDefinition from './makeRefDefinition.js';
17
- function getRefsFromFile(fileContent, parentRefDefId, refMap) {
18
- const foundRefs = [];
19
- const reviver = (key, value)=>{
20
- if (type.isObject(value)) {
21
- if (!type.isUndefined(value._ref)) {
22
- // Capture line number from the object containing the _ref
23
- const lineNumber = value['~l'];
24
- const def = makeRefDefinition(value._ref, parentRefDefId, refMap, lineNumber);
25
- foundRefs.push(def);
26
- return {
27
- _ref: def
28
- };
29
- }
30
- }
31
- return value;
32
- };
33
- // Use serializer.copy to preserve non-enumerable properties like ~l
34
- const fileContentBuiltRefs = serializer.copy(fileContent, {
35
- reviver
36
- });
37
- return {
38
- foundRefs,
39
- fileContentBuiltRefs
40
- };
41
- }
42
- export default getRefsFromFile;
@@ -1,105 +0,0 @@
1
- /*
2
- Copyright 2020-2026 Lowdefy, Inc
3
-
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
7
-
8
- http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
15
- */ import { get, serializer, type } from '@lowdefy/helpers';
16
- /**
17
- * Copies a _var value while preserving source location markers.
18
- *
19
- * When _var copies a value from vars into a template, we need to preserve
20
- * the ~r (ref ID) and ~l (line number) from WHERE THE VALUE IS DEFINED
21
- * (the source file), not where _var is used (the template).
22
- *
23
- * The issue is that serializer.copy loses non-enumerable properties, and
24
- * recursiveBuild.js then sets ~r to the template file for objects without ~r.
25
- *
26
- * This function preserves the source location by making ~r enumerable on
27
- * the copied value, so it survives through subsequent serializer.copy calls.
28
- *
29
- * @param {*} value - The value to copy from vars
30
- * @param {string} sourceRefId - The ref ID of the source file where the var is defined
31
- * @returns {*} The copied value with preserved source location markers
32
- */ function copyVarValue(value, sourceRefId) {
33
- if (!type.isObject(value) && !type.isArray(value)) {
34
- return value;
35
- }
36
- // Copy the value, preserving ~l and setting ~r to the source file
37
- return serializer.copy(value, {
38
- reviver: (_, v)=>{
39
- if (type.isObject(v) || type.isArray(v)) {
40
- // Preserve the source file's ref ID by setting it explicitly
41
- // This prevents recursiveBuild from overwriting it with the template's ref ID
42
- if (sourceRefId && v['~r'] === undefined) {
43
- v['~r'] = sourceRefId;
44
- }
45
- }
46
- return v;
47
- }
48
- });
49
- }
50
- function refReviver(key, value) {
51
- if (type.isObject(value)) {
52
- if (!type.isUndefined(value._ref)) {
53
- const result = this.parsedFiles[value._ref.id];
54
- if (value._ref.ignoreBuildChecks !== undefined) {
55
- if (type.isObject(result)) {
56
- result['~ignoreBuildChecks'] = value._ref.ignoreBuildChecks;
57
- } else if (type.isArray(result)) {
58
- result.forEach((item)=>{
59
- if (type.isObject(item)) {
60
- item['~ignoreBuildChecks'] = value._ref.ignoreBuildChecks;
61
- }
62
- });
63
- }
64
- }
65
- return result;
66
- }
67
- if (value._var) {
68
- if (type.isString(value._var)) {
69
- const varValue = get(this.vars, value._var, {
70
- default: null
71
- });
72
- return copyVarValue(varValue, this.sourceRefId);
73
- }
74
- if (type.isObject(value._var) && type.isString(value._var.key)) {
75
- const varKey = value._var.key;
76
- const varFromParent = get(this.vars, varKey);
77
- // Check if var was explicitly provided (even if null) vs not provided at all (undefined)
78
- // - Var provided (including null): use parent's sourceRefId for location
79
- // - Var not provided (undefined): use default, preserve template's location
80
- if (!type.isUndefined(varFromParent)) {
81
- // Var was explicitly provided from parent file - use parent's location
82
- return copyVarValue(varFromParent, this.sourceRefId);
83
- }
84
- // Using default value defined in template - preserve template's location markers
85
- // Pass null for sourceRefId so we don't override the template file's ~r
86
- const defaultValue = type.isNone(value._var.default) ? null : value._var.default;
87
- return copyVarValue(defaultValue, null);
88
- }
89
- throw new Error('_var operator takes a string or object with "key" field as arguments.');
90
- }
91
- }
92
- return value;
93
- }
94
- function populateRefs({ parsedFiles, refDef, toPopulate }) {
95
- // Use serializer.copy to preserve non-enumerable properties like ~r, ~k, ~l
96
- // sourceRefId is the PARENT file's ref ID where vars are defined (not the template's ID)
97
- return serializer.copy(toPopulate, {
98
- reviver: refReviver.bind({
99
- parsedFiles,
100
- vars: refDef.vars,
101
- sourceRefId: refDef.parent
102
- })
103
- });
104
- }
105
- export default populateRefs;
@@ -1,133 +0,0 @@
1
- /*
2
- Copyright 2020-2026 Lowdefy, Inc
3
-
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
7
-
8
- http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
15
- */ import { serializer, type } from '@lowdefy/helpers';
16
- import { ConfigError } from '@lowdefy/errors';
17
- import createRefReviver from './createRefReviver.js';
18
- import evaluateBuildOperators from './evaluateBuildOperators.js';
19
- import getKey from './getKey.js';
20
- import getRefContent from './getRefContent.js';
21
- import getRefPositions from '../jit/getRefPositions.js';
22
- import getRefsFromFile from './getRefsFromFile.js';
23
- import populateRefs from './populateRefs.js';
24
- import runTransformer from './runTransformer.js';
25
- import isPageContentPath from '../jit/isPageContentPath.js';
26
- async function recursiveBuild({ context, refDef, count, content, referencedFrom, refChainSet = new Set(), refChainList = [], shallowOptions, jsonPath = '' }) {
27
- // Detect circular references by tracking the chain of files being resolved
28
- // Skip circular reference checking for refs without paths (e.g., resolver refs)
29
- const currentPath = refDef.path;
30
- if (currentPath) {
31
- if (refChainSet.has(currentPath)) {
32
- const chainDisplay = [
33
- ...refChainList,
34
- currentPath
35
- ].join('\n -> ');
36
- throw new ConfigError(`Circular reference detected. File "${currentPath}" references itself through:\n -> ${chainDisplay}`, {
37
- filePath: referencedFrom ?? null,
38
- lineNumber: referencedFrom ? refDef.lineNumber : null
39
- });
40
- }
41
- refChainSet.add(currentPath);
42
- refChainList.push(currentPath);
43
- }
44
- // Keep count as a fallback safety limit
45
- if (count > 10000) {
46
- throw new ConfigError('Maximum recursion depth of references exceeded (10000 levels). This likely indicates a circular reference.');
47
- }
48
- let fileContent = content ?? await getRefContent({
49
- context,
50
- refDef,
51
- referencedFrom
52
- });
53
- const { foundRefs, fileContentBuiltRefs } = getRefsFromFile(fileContent, refDef.id, context.refMap);
54
- const parsedFiles = {};
55
- // Compute the JSON path position of each ref within the current file's content.
56
- // This lets us check if a ref should be skipped during shallow builds.
57
- const refPositions = shallowOptions ? getRefPositions(fileContentBuiltRefs, jsonPath) : null;
58
- // Since we can have references in the variables of a reference, we need to first parse
59
- // the deeper nodes, so we can use those parsed files in references higher in the tree.
60
- // To do this, since foundRefs is an array of ref definitions that are in order of the
61
- // deepest nodes first we for loop over over foundRefs one by one, awaiting each result.
62
- for (const newRefDef of foundRefs.values()){
63
- // Check if this ref should be skipped (shallow build)
64
- const refJsonPath = refPositions?.get(newRefDef.id) ?? '';
65
- if (shallowOptions && isPageContentPath(refJsonPath)) {
66
- // Store shallow marker instead of resolving
67
- parsedFiles[newRefDef.id] = {
68
- '~shallow': true,
69
- _ref: newRefDef.original,
70
- _refId: newRefDef.id
71
- };
72
- continue;
73
- }
74
- // Parse vars and path before passing down to parse new file
75
- const parsedRefDef = populateRefs({
76
- toPopulate: newRefDef,
77
- parsedFiles,
78
- refDef
79
- });
80
- context.refMap[parsedRefDef.id].path = parsedRefDef.path;
81
- // Store original definition for resolver refs so JIT can re-run them
82
- if (!parsedRefDef.path) {
83
- context.refMap[parsedRefDef.id].original = newRefDef.original;
84
- }
85
- if (Object.keys(newRefDef.vars).length > 0) {
86
- context.unresolvedRefVars[newRefDef.id] = newRefDef.vars;
87
- }
88
- const parsedFile = await recursiveBuild({
89
- context,
90
- refDef: parsedRefDef,
91
- count: count + 1,
92
- referencedFrom: refDef.path ?? referencedFrom,
93
- refChainSet,
94
- refChainList,
95
- shallowOptions,
96
- jsonPath: refJsonPath
97
- });
98
- const transformedFile = await runTransformer({
99
- context,
100
- input: parsedFile,
101
- refDef: parsedRefDef
102
- });
103
- // Evaluated in recursive loop for better error messages
104
- const evaluatedOperators = await evaluateBuildOperators({
105
- context,
106
- input: transformedFile,
107
- refDef: parsedRefDef
108
- });
109
- const withRefKey = getKey({
110
- input: evaluatedOperators,
111
- refDef: parsedRefDef
112
- });
113
- // Use serializer.copy to preserve non-enumerable properties like ~l.
114
- // Only set ~r if not already present to preserve original file references from nested imports.
115
- // Use child file's ref ID (parsedRefDef.id) not parent's (refDef.id) for correct error tracing.
116
- const reviver = createRefReviver(parsedRefDef.id);
117
- parsedFiles[newRefDef.id] = serializer.copy(withRefKey, {
118
- reviver
119
- });
120
- }
121
- // Backtrack: remove current file from chain so sibling refs can use it
122
- // Only remove if it was added (i.e., if currentPath exists)
123
- if (currentPath) {
124
- refChainSet.delete(currentPath);
125
- refChainList.pop();
126
- }
127
- return populateRefs({
128
- toPopulate: fileContentBuiltRefs,
129
- parsedFiles,
130
- refDef
131
- });
132
- }
133
- export default recursiveBuild;
@@ -1,38 +0,0 @@
1
- /*
2
- Copyright 2020-2026 Lowdefy, Inc
3
-
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
7
-
8
- http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
15
- */ import { type } from '@lowdefy/helpers';
16
- function getRefPositions(content, basePath) {
17
- const positions = new Map();
18
- walk(content, basePath, positions);
19
- return positions;
20
- }
21
- function walk(node, path, positions) {
22
- if (type.isObject(node)) {
23
- if (node._ref && node._ref.id !== undefined) {
24
- positions.set(node._ref.id, path);
25
- return;
26
- }
27
- for (const key of Object.keys(node)){
28
- const childPath = path ? `${path}.${key}` : key;
29
- walk(node[key], childPath, positions);
30
- }
31
- } else if (type.isArray(node)) {
32
- for(let i = 0; i < node.length; i++){
33
- const childPath = path ? `${path}.${i}` : `${i}`;
34
- walk(node[i], childPath, positions);
35
- }
36
- }
37
- }
38
- export default getRefPositions;
@@ -1,23 +0,0 @@
1
- /*
2
- Copyright 2020-2026 Lowdefy, Inc
3
-
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
7
-
8
- http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
15
- */ import PAGE_CONTENT_KEYS from './pageContentKeys.js';
16
- function stripPageContent({ components }) {
17
- for (const page of components.pages ?? []){
18
- for (const key of PAGE_CONTENT_KEYS){
19
- delete page[key];
20
- }
21
- }
22
- }
23
- export default stripPageContent;