@lowdefy/build 0.0.0-experimental-20250903141200 → 0.0.0-experimental-20250911081238

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.
@@ -17,12 +17,10 @@ import makeRefDefinition from './makeRefDefinition.js';
17
17
  import evaluateBuildOperators from './evaluateBuildOperators.js';
18
18
  async function buildRefs({ context }) {
19
19
  const refDef = makeRefDefinition('lowdefy.yaml', null, context.refMap);
20
- const refCache = new Map();
21
20
  let components = await recursiveBuild({
22
21
  context,
23
22
  refDef,
24
- count: 0,
25
- refCache
23
+ count: 0
26
24
  });
27
25
  components = await evaluateBuildOperators({
28
26
  context,
@@ -17,7 +17,13 @@ import parseRefContent from './parseRefContent.js';
17
17
  import runRefResolver from './runRefResolver.js';
18
18
  async function getRefContent({ context, refDef, referencedFrom }) {
19
19
  let content;
20
- if (refDef.resolver || context.refResolver) {
20
+ if (refDef.path === 'lowdefy.yaml' || refDef.path === 'lowdefy.yml') {
21
+ content = await getConfigFile({
22
+ context,
23
+ refDef,
24
+ referencedFrom
25
+ });
26
+ } else if (refDef.resolver || context.refResolver) {
21
27
  content = await runRefResolver({
22
28
  context,
23
29
  refDef,
@@ -14,9 +14,16 @@
14
14
  limitations under the License.
15
15
  */ import { get } from '@lowdefy/helpers';
16
16
  import getRefPath from './getRefPath.js';
17
- import makeRefHash from '../../utils/makeRefHash.js';
17
+ import makeId from '../../utils/makeId.js';
18
18
  function makeRefDefinition(refDefinition, parent, refMap) {
19
+ const id = makeId();
19
20
  const refDef = {
21
+ parent
22
+ };
23
+ refMap[id] = refDef;
24
+ return {
25
+ ...refDef,
26
+ id,
20
27
  key: get(refDefinition, 'key'),
21
28
  original: refDefinition,
22
29
  path: getRefPath(refDefinition),
@@ -26,12 +33,5 @@ function makeRefDefinition(refDefinition, parent, refMap) {
26
33
  default: {}
27
34
  })
28
35
  };
29
- const refHash = makeRefHash(refDef);
30
- refMap[refHash] = {
31
- parent
32
- };
33
- refDef.hash = refHash;
34
- refDef.parent = parent;
35
- return refDef;
36
36
  }
37
37
  export default makeRefDefinition;
@@ -16,7 +16,7 @@
16
16
  function refReviver(key, value) {
17
17
  if (type.isObject(value)) {
18
18
  if (!type.isUndefined(value._ref)) {
19
- return this.refCache.get(value._ref.hash);
19
+ return this.parsedFiles[value._ref.id];
20
20
  }
21
21
  if (value._var) {
22
22
  if (type.isString(value._var)) {
@@ -34,9 +34,9 @@ function refReviver(key, value) {
34
34
  }
35
35
  return value;
36
36
  }
37
- function populateRefs({ refCache, refDef, toPopulate }) {
37
+ function populateRefs({ parsedFiles, refDef, toPopulate }) {
38
38
  return JSON.parse(JSON.stringify(toPopulate), refReviver.bind({
39
- refCache,
39
+ parsedFiles,
40
40
  vars: refDef.vars
41
41
  }));
42
42
  }
@@ -19,20 +19,18 @@ import getRefContent from './getRefContent.js';
19
19
  import getRefsFromFile from './getRefsFromFile.js';
20
20
  import populateRefs from './populateRefs.js';
21
21
  import runTransformer from './runTransformer.js';
22
- async function recursiveBuild({ context, refDef, count, referencedFrom, refCache }) {
22
+ async function recursiveBuild({ context, refDef, count, referencedFrom }) {
23
23
  // TODO: Maybe it would be better to detect a cycle, since this is the real issue here?
24
24
  if (count > 10000) {
25
25
  throw new Error(`Maximum recursion depth of references exceeded.`);
26
26
  }
27
- if (refCache.has(refDef.hash)) {
28
- return refCache.get(refDef.hash);
29
- }
30
27
  let fileContent = await getRefContent({
31
28
  context,
32
29
  refDef,
33
30
  referencedFrom
34
31
  });
35
- const { foundRefs, fileContentBuiltRefs } = getRefsFromFile(fileContent, refDef.hash, context.refMap);
32
+ const { foundRefs, fileContentBuiltRefs } = getRefsFromFile(fileContent, refDef.id, context.refMap);
33
+ const parsedFiles = {};
36
34
  // Since we can have references in the variables of a reference, we need to first parse
37
35
  // the deeper nodes, so we can use those parsed files in references higher in the tree.
38
36
  // To do this, since foundRefs is an array of ref definitions that are in order of the
@@ -41,16 +39,15 @@ async function recursiveBuild({ context, refDef, count, referencedFrom, refCache
41
39
  // Parse vars and path before passing down to parse new file
42
40
  const parsedRefDef = populateRefs({
43
41
  toPopulate: newRefDef,
44
- refCache,
42
+ parsedFiles,
45
43
  refDef
46
44
  });
47
- context.refMap[parsedRefDef.hash].path = parsedRefDef.path;
45
+ context.refMap[parsedRefDef.id].path = parsedRefDef.path;
48
46
  const parsedFile = await recursiveBuild({
49
47
  context,
50
48
  refDef: parsedRefDef,
51
49
  count: count + 1,
52
- referencedFrom: refDef.path,
53
- refCache
50
+ referencedFrom: refDef.path
54
51
  });
55
52
  const transformedFile = await runTransformer({
56
53
  context,
@@ -70,21 +67,19 @@ async function recursiveBuild({ context, refDef, count, referencedFrom, refCache
70
67
  const reviver = (_, value)=>{
71
68
  if (!type.isObject(value)) return value;
72
69
  Object.defineProperty(value, '~r', {
73
- value: refDef.hash,
70
+ value: refDef.id,
74
71
  enumerable: false,
75
72
  writable: true,
76
73
  configurable: true
77
74
  });
78
75
  return value;
79
76
  };
80
- refCache.set(newRefDef.hash, JSON.parse(JSON.stringify(withRefKey), reviver));
77
+ parsedFiles[newRefDef.id] = JSON.parse(JSON.stringify(withRefKey), reviver);
81
78
  }
82
- const result = populateRefs({
79
+ return populateRefs({
83
80
  toPopulate: fileContentBuiltRefs,
84
- refCache,
81
+ parsedFiles,
85
82
  refDef
86
83
  });
87
- refCache.set(refDef.hash, result);
88
- return result;
89
84
  }
90
85
  export default recursiveBuild;
@@ -0,0 +1,32 @@
1
+ /*
2
+ Copyright 2020-2024 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
+ */ async function writeActionSchemas({ context }) {
16
+ try {
17
+ const actions = context.typesMap.actions || {};
18
+ for (const [actionType, actionConfig] of Object.entries(actions)){
19
+ const actionSchema = {
20
+ type: actionType,
21
+ package: actionConfig.package,
22
+ description: `${actionType} action`
23
+ };
24
+ const schemaFileName = `${actionType}.json`;
25
+ const individualSchemaContent = JSON.stringify(actionSchema, null, 2);
26
+ await context.writeBuildArtifact(`schemas/actions/${schemaFileName}`, individualSchemaContent);
27
+ }
28
+ } catch (error) {
29
+ context.logger.warn('Failed to write action schemas:', error.message);
30
+ }
31
+ }
32
+ export default writeActionSchemas;
@@ -0,0 +1,47 @@
1
+ /*
2
+ Copyright 2020-2024 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 fs from 'fs';
16
+ import path from 'path';
17
+ async function writeBlockSchemas({ context }) {
18
+ try {
19
+ const blocks = context.typesMap.blocks || {};
20
+ for (const [blockType, blockConfig] of Object.entries(blocks)){
21
+ const blockSchema = {
22
+ type: blockType,
23
+ package: blockConfig.package,
24
+ description: `${blockType} block`
25
+ };
26
+ // Try to read schema.json from the package
27
+ try {
28
+ const packagePath = path.join(process.cwd(), 'node_modules', blockConfig.package);
29
+ const schemaPath = path.join(packagePath, 'dist', 'blocks', blockConfig.originalTypeName, 'schema.json');
30
+ if (fs.existsSync(schemaPath)) {
31
+ const schemaContent = fs.readFileSync(schemaPath, 'utf8');
32
+ const schema = JSON.parse(schemaContent);
33
+ blockSchema.schema = schema;
34
+ }
35
+ } catch (error) {
36
+ // Continue without schema if it can't be read
37
+ context.logger.warn(`Could not read schema for ${blockType}:`, error.message);
38
+ }
39
+ const schemaFileName = `${blockType}.json`;
40
+ const individualSchemaContent = JSON.stringify(blockSchema, null, 2);
41
+ await context.writeBuildArtifact(`schemas/blocks/${schemaFileName}`, individualSchemaContent);
42
+ }
43
+ } catch (error) {
44
+ context.logger.warn('Failed to write block schemas:', error.message);
45
+ }
46
+ }
47
+ export default writeBlockSchemas;
@@ -0,0 +1,52 @@
1
+ /*
2
+ Copyright 2020-2024 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 fs from 'fs';
16
+ import path from 'path';
17
+ import writeRequestSchemas from './writeRequestSchemas.js';
18
+ async function writeConnectionSchemas({ context }) {
19
+ try {
20
+ const connections = context.typesMap.connections || {};
21
+ for (const [connectionType, connectionConfig] of Object.entries(connections)){
22
+ const connectionSchema = {
23
+ type: connectionType,
24
+ package: connectionConfig.package,
25
+ description: `${connectionType} connection`
26
+ };
27
+ // Try to read schema.js from the package
28
+ try {
29
+ const packagePath = path.join(process.cwd(), 'node_modules', connectionConfig.package);
30
+ const schemaPath = path.join(packagePath, 'dist', 'connections', connectionConfig.originalTypeName, 'schema.js');
31
+ if (fs.existsSync(schemaPath)) {
32
+ const { default: schema } = await import(`file://${schemaPath}`);
33
+ connectionSchema.schema = schema;
34
+ }
35
+ } catch (error) {
36
+ // Continue without schema if it can't be read
37
+ context.logger.warn(`Could not read schema for ${connectionType}:`, error.message);
38
+ }
39
+ const schemaFileName = `${connectionType}.json`;
40
+ const individualSchemaContent = JSON.stringify(connectionSchema, null, 2);
41
+ await context.writeBuildArtifact(`schemas/connections/${schemaFileName}`, individualSchemaContent);
42
+ await writeRequestSchemas({
43
+ connectionType,
44
+ context,
45
+ connectionPackage: connectionConfig.package
46
+ });
47
+ }
48
+ } catch (error) {
49
+ context.logger.warn('Failed to write connection schemas:', error.message);
50
+ }
51
+ }
52
+ export default writeConnectionSchemas;
@@ -0,0 +1,62 @@
1
+ /*
2
+ Copyright 2020-2024 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
+ */ async function writeOperatorSchemas({ context }) {
16
+ try {
17
+ const operators = context.typesMap.operators || {};
18
+ const allOperators = {};
19
+ // Process client operators
20
+ if (operators.client) {
21
+ for (const [operatorType, operatorConfig] of Object.entries(operators.client)){
22
+ allOperators[operatorType] = {
23
+ ...operatorConfig,
24
+ groups: [
25
+ 'client'
26
+ ]
27
+ };
28
+ }
29
+ }
30
+ // Process server operators
31
+ if (operators.server) {
32
+ for (const [operatorType, operatorConfig] of Object.entries(operators.server)){
33
+ if (allOperators[operatorType]) {
34
+ // Operator exists in both client and server
35
+ allOperators[operatorType].groups.push('server');
36
+ } else {
37
+ // Operator only in server
38
+ allOperators[operatorType] = {
39
+ ...operatorConfig,
40
+ groups: [
41
+ 'server'
42
+ ]
43
+ };
44
+ }
45
+ }
46
+ }
47
+ for (const [operatorType, operatorConfig] of Object.entries(allOperators)){
48
+ const operatorSchema = {
49
+ type: operatorType,
50
+ package: operatorConfig.package,
51
+ groups: operatorConfig.groups,
52
+ description: `${operatorType} operator`
53
+ };
54
+ const schemaFileName = `${operatorType}.json`;
55
+ const individualSchemaContent = JSON.stringify(operatorSchema, null, 2);
56
+ await context.writeBuildArtifact(`schemas/operators/${schemaFileName}`, individualSchemaContent);
57
+ }
58
+ } catch (error) {
59
+ context.logger.warn('Failed to write operator schemas:', error.message);
60
+ }
61
+ }
62
+ export default writeOperatorSchemas;
@@ -0,0 +1,38 @@
1
+ /*
2
+ Copyright 2020-2024 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 writeActionSchemas from './writeActionSchemas.js';
16
+ import writeBlockSchemas from './writeBlockSchemas.js';
17
+ import writeConnectionSchemas from './writeConnectionSchemas.js';
18
+ import writeOperatorSchemas from './writeOperatorSchemas.js';
19
+ async function writePluginSchemas({ context }) {
20
+ if (context.stage !== 'dev') {
21
+ return;
22
+ }
23
+ await Promise.all([
24
+ writeActionSchemas({
25
+ context
26
+ }),
27
+ writeBlockSchemas({
28
+ context
29
+ }),
30
+ writeConnectionSchemas({
31
+ context
32
+ }),
33
+ writeOperatorSchemas({
34
+ context
35
+ })
36
+ ]);
37
+ }
38
+ export default writePluginSchemas;
@@ -0,0 +1,49 @@
1
+ /*
2
+ Copyright 2020-2024 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 fs from 'fs';
16
+ import path from 'path';
17
+ async function writeRequestSchemas({ connectionType, context, connectionPackage }) {
18
+ try {
19
+ const allRequests = context.typesMap.requests || {};
20
+ // Filter requests that belong to this connection package
21
+ const requests = Object.fromEntries(Object.entries(allRequests).filter(([, requestConfig])=>requestConfig.package === connectionPackage));
22
+ for (const [requestType, requestConfig] of Object.entries(requests)){
23
+ const requestSchema = {
24
+ connection: connectionType,
25
+ type: requestType,
26
+ package: requestConfig.package,
27
+ description: `${requestType} request`
28
+ };
29
+ // Try to read schema.js from the package
30
+ try {
31
+ const packagePath = path.join(process.cwd(), 'node_modules', requestConfig.package);
32
+ const schemaPath = path.join(packagePath, 'dist', 'connections', connectionType, requestConfig.originalTypeName, 'schema.js');
33
+ if (fs.existsSync(schemaPath)) {
34
+ const { default: schema } = await import(`file://${schemaPath}`);
35
+ requestSchema.schema = schema;
36
+ }
37
+ } catch (error) {
38
+ // Continue without schema if it can't be read
39
+ context.logger.warn(`Could not read schema for ${requestType}:`, error.message);
40
+ }
41
+ const schemaFileName = `${requestType}.json`;
42
+ const individualSchemaContent = JSON.stringify(requestSchema, null, 2);
43
+ await context.writeBuildArtifact(`schemas/requests/${connectionType}/${schemaFileName}`, individualSchemaContent);
44
+ }
45
+ } catch (error) {
46
+ context.logger.warn('Failed to write request schemas:', error.message);
47
+ }
48
+ }
49
+ export default writeRequestSchemas;