diff --git a/packages/xod-project/src/internal/patchPathUtils.js b/packages/xod-project/src/internal/patchPathUtils.js index c0f9b26e..fb907cfb 100644 --- a/packages/xod-project/src/internal/patchPathUtils.js +++ b/packages/xod-project/src/internal/patchPathUtils.js @@ -22,14 +22,18 @@ const alphanumericWithHypens = `${alphanumeric}(-${alphanumeric})*`; const alphanumericWithHypensAndCommans = `${alphanumeric}(-${alphanumeric}|,${alphanumeric})*`; // -$5 -const variadicLevel = '-\\$\\d'; +const variadicLevel = '(-\\$\\d+){0,1}'; // (foo-2-bar,foo-5-bar) const types = `(\\(${alphanumericWithHypensAndCommans}\\)){0,1}`; // foo2(foo-2-bar,foo-5-bar)-$5 const patchBaseNameRegExp = new RegExp( - `^${alphanumericWithHypens}(${types}|${variadicLevel})$` + `^${alphanumericWithHypens}${types}${variadicLevel}$` +); + +const specializationPatchBasenameRegExp = new RegExp( + `^${alphanumericWithHypens}\\(${alphanumericWithHypensAndCommans}\\)${variadicLevel}$` ); // foo-2-bar @@ -116,3 +120,8 @@ export const isWatchPatchPath = R.test(/^xod\/core\/watch$/); // :: LibName -> Boolean export const isBuiltInLibName = R.equals(TERMINALS_LIB_NAME); + +// :: PatchPath -> Boolean +export const isSpecializationPatchBasename = R.test( + specializationPatchBasenameRegExp +); diff --git a/packages/xod-project/src/node.js b/packages/xod-project/src/node.js index 66e58565..4b967fcf 100644 --- a/packages/xod-project/src/node.js +++ b/packages/xod-project/src/node.js @@ -9,6 +9,8 @@ import { isOutputTerminalPath, getTerminalDataType, isPathLocal, + getBaseName, + isSpecializationPatchBasename, } from './patchPathUtils'; /** @@ -222,6 +224,15 @@ export const isLocalNode = def( R.compose(isPathLocal, getNodeType) ); +/** + * Checks that Node have a NodeType referenced to the specialization Patch. + * E.G. `@/if-else(number)` + */ +export const isSpecializationNode = def( + 'isSpecializationNode :: Node -> Boolean', + R.compose(isSpecializationPatchBasename, getBaseName, getNodeType) +); + // ============================================================================= // // Pins diff --git a/packages/xod-project/src/patchPathUtils.js b/packages/xod-project/src/patchPathUtils.js index 4054c3ec..5e7cc641 100644 --- a/packages/xod-project/src/patchPathUtils.js +++ b/packages/xod-project/src/patchPathUtils.js @@ -14,6 +14,7 @@ export { isLocalMarker, isValidIdentifier, isValidPatchBasename, + isSpecializationPatchBasename, isPathLocal, isPathLibrary, isLibName, @@ -59,6 +60,13 @@ export const validatePath = Tools.errOnFalse( */ export const getBaseName = R.compose(R.last, R.split('/')); +// :: PatchPath -> Identifier +export const getBaseNameWithoutTypes = R.compose( + R.head, + R.split('('), + getBaseName +); + /** * @function getLibraryName * @param {string} path diff --git a/packages/xod-project/test/patchPathUtils.spec.js b/packages/xod-project/test/patchPathUtils.spec.js index e9119e3f..c08736d5 100644 --- a/packages/xod-project/test/patchPathUtils.spec.js +++ b/packages/xod-project/test/patchPathUtils.spec.js @@ -67,6 +67,12 @@ describe('PatchPathUtils', () => { PatchPathUtils.isValidPatchBasename('foo(super-string,number)') ); + // Valid basenames with variadic level + assert.isTrue(PatchPathUtils.isValidPatchBasename('lower-kebab-123-$3')); + assert.isTrue( + PatchPathUtils.isValidPatchBasename('foo(super-string,number)-$2') + ); + // Invalid common patch basenames assert.isFalse(PatchPathUtils.isValidPatchBasename('-')); assert.isFalse(PatchPathUtils.isValidPatchBasename('a-')); @@ -84,6 +90,16 @@ describe('PatchPathUtils', () => { assert.isFalse(PatchPathUtils.isValidPatchBasename('foo--bar(string)')); assert.isFalse(PatchPathUtils.isValidPatchBasename('(string)')); assert.isFalse(PatchPathUtils.isValidPatchBasename('(string,number)')); + + // Invalid basenames with variadic level + assert.isFalse(PatchPathUtils.isValidPatchBasename('foo-$')); + assert.isFalse(PatchPathUtils.isValidPatchBasename('foo-$a')); + assert.isFalse( + PatchPathUtils.isValidPatchBasename('foo(super-string,number)-$') + ); + assert.isFalse( + PatchPathUtils.isValidPatchBasename('foo(super-string,number)-$a') + ); }); }); describe('isValidPatchPath', () => {