Git Product home page Git Product logo

stekoe / ocl.js Goto Github PK

View Code? Open in Web Editor NEW
51.0 5.0 7.0 3.68 MB

The Object Constraint Language (OCL) is a language for describing rules that apply to MOF conform modelling languages like UML. The OCL is a text based language that provides constraint and object query expressions that cannot be expressed by a meta modelling language.

Home Page: http://ocl.stekoe.de

License: Other

JavaScript 46.21% Yacc 3.78% TypeScript 50.00%
ocl ocl-expression language constraints constraint-language javascript

ocl.js's Introduction

Hello, World!

Website Twitter

SteKoes's GitHub Stats SteKoes' Tech-Stack on GitHub

ocl.js's People

Contributors

dependabot-preview[bot] avatar dependabot[bot] avatar stekoe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

ocl.js's Issues

Add API documentation for OclEngine

There is need to have a documentation of the API provided by OclEngine. It has to be added as jsDoc and to the SteKoe/ocl.js-docs repository!

require and import should work the same

require('@stekoe/ocl.js') and import OclEngine from '@stekoe/ocl.js'should both return a reference to the class OclEngine.

Right now require needs to be called with .default to get the OclEngine.

Create new instance of OclEngine throw error

since version v1.1.0 creating a new instance of OclEngine throw an error in typescript project.

Given

import { OclEngine } from '@stekoe/ocl.js';

const oclEngine = OclEngine.create();

Then
it throw an error.

Cannot read property 'create' of undefined.
Sure using new OclEngine() does not work anymore because the class has no constructor.

Unable to create an instance of OclEngine: OclEngine is undefined

Hi,
This maybe related to #28 and #29 .
I still unable to import OclEngine properly and create an instance of it. Using Typescript, I always get OclEngine undefined :

import { OclEngine } from '@stekoe/ocl.js'

Error:
TypeError: Cannot read property 'create' of undefined

I also tried all the following with no luck:

import OclEngine from '@stekoe/ocl.js'
import * as OclEngine from '@stekoe/ocl.js'

I only got this to work using require which I don't prefer.

My tsconfig.json :

{
  "compilerOptions": {
    "moduleResolution": "node",
    "target": "es5",
    "module": "commonjs",
    "lib": [
      "es2017",
      "es7",
      "es6",
      "dom"
    ],
    "strict": true,
    "sourceMap": true,
    "declaration": true,
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "strictNullChecks": false,
    "declarationDir": "dist/types",
    "outDir": "dist/library",
    "typeRoots": [
      "node_modules/@types"
    ],
    "baseUrl": "./"
  },
  "include": [
    "src"
  ]
}

Use ES5 constructs for non-transpiled code

I am using Jint to call ocl.js from .NET. However, Jint only supports ES5 (mostly), and it is running into issues with the following code:

function functionCallExpression(yy, fn, source, params = undefined) {
let expressionTypeName = `${yy.Utils.ucfirst(fn)}Expression`;

The issue is the use of the default values in the argument list, and the string interpolation on the second line.

No examples in JavaScript

Hello,

The examples given on the site, as far as I understood are in TypeScript. Are there similar detailed examples in JavaScript? I notice that there are plenty of snippets for TypeScript, but none for JS.

Add support escape syntax support

We have enumerations defined like this:

image

Note the dashes in state-id, state-voter-registration-id, etc.

The UML tool I use (MagicDraw) wouldn't accept rules like this:

context VoterRecordsRequest 
inv VoterRegistrationRequired: self.Type->exists(c | c = VoterRequestType::ballot-request) implies self.OtherType->size() = 1

but it would work if the OCL escape sequence was used:

context VoterRecordsRequest
inv VoterRegistrationRequired: self.Type->exists(c | c = VoterRequestType::_'ballot-request') implies self.OtherType->size() = 1

I'm not sure if this is standard behavior, but Eclipse says it is

Escape syntax for illegal names: type, operation, attribute, etc. names that correspond to OCL reserved
words can be escaped in the standard fashion using a leading underscore (‘_’). In addition, names that
contain spaces or tabs can be escaped by enclosing them in double-quotes (‘"’; this is non-standard).
e.g., self.ownedRule->forAll(c : Constraint | c._context = self)

How to build up the models?

It's not clear to me how to use the API of this project. Specifically I'm having problems of building up the "instance" models to be checked.
I'm very interested in integrating OCL into a metamodeling framework, but after playing around with the ocl.js I can't get it to work. I've included a snippet, any pointers are welcome.
(I'm using the structure below since I'm intending to generate the models to be evaluated on the fly based on the models in our framework.)

global.window = undefined; // Needed to avoid exception at import..
const OCLEngine = require("@stekoe/ocl.js");

function OCLObject(type, attributes, pointers, sets) {
    this.type = type;
    this.attributes = attributes;
    this.pointers = pointers;
    this.sets = sets;
}

// Super-classes
const Person = new OCLObject('Person', {name: 'Person', isMale: true}, {dad: null, mom: null}, {});
const Family = new OCLObject('Family', {name: 'Family', address: ''}, {}, {familyMembers: []});

// "Instances"
const aFamily = Object.assign(Object.create(Family), {
    attributes: {name: 'Smiths', address: 'Main Street'},
});

const dad = Object.assign(Object.create(Person), {
    attributes: {name: 'Joe', isMale: true},
});

const mom = Object.assign(Object.create(Person), {
    attributes: {name: 'Jen', isMale: false},
});

const son = Object.assign(Object.create(Person), {
    attributes: {name: 'JoeJr', isMale: true},
    pointers: {dad: dad, mom: mom}
});

const daughter = Object.assign(Object.create(Person), {
    attributes: {name: 'JenJr', isMale: false},
    pointers: {dad: dad, mom: mom}
});

const derp = Object.assign(Object.create(Person), {
    attributes: {name: 'derp', isMale: false},
    pointers: {mom: dad, dad: mom}
});

Object.assign(aFamily, {sets: {familyMembers: [dad, mom, son, daughter, derp]}});


// Check the instance model
const oclEngine = new OCLEngine();

const dadIsMale = `
    -- Check that dad is indeed a male
    context Person
        inv: self.pointers.dad->notEmpty() implies self.pointers.dad.isMale = true
`;

oclEngine.addOclExpression(dadIsMale);

var res = oclEngine.evaluate(aFamily);
console.log(res); // t { namesOfFailedInvs: [], evaluatedContexts: [], result: true }
res = oclEngine.evaluate(son);
console.log(res); // t { namesOfFailedInvs: [], evaluatedContexts: [], result: true }
res = oclEngine.evaluate(derp);
console.log(res); // t { namesOfFailedInvs: [], evaluatedContexts: [], result: true }

OclEngine is default export, but not marked as such

In using the ocl.js in another TypeScript project, I'm running into an issue with the npm package. It appears that the OclEngine is the default export of the module, but it is not defined as such.

This causes code like this to fail

import OclEngine from "@stekoe/ocl.js";
export class OclEngineFactory {
    public static getOclEngine() {
        const oclEngine =  OclEngine.create();

With an error like

{
	"resource": "{}"
	"owner": "typescript",
	"code": "2339",
	"severity": 8,
	"message": "Property 'create' does not exist on type 'typeof import(\"{my_path}/node_modules/@stekoe/ocl.js/index\")'.",
	"source": "ts",
	"startLineNumber": 4,
	"startColumn": 38,
	"endLineNumber": 4,
	"endColumn": 44
}

It will work if I cast OclEngine to any, but that defeats the purpose of TypeScript.

oclIsUndefined and null

The spec of the OCL 2.4, defines oclIsUndefined as such:

Evaluates to true if the self is equal to invalid or equal to null.

Right now ocl.js checks against the JavaScript undefined type. This is a bit of a judgement call, but I'm thinking at oclIsUndefined should also return true if the object invoking the function is null. As an aside, I'm thinking undefined is closer to OclInvalid, which is a type, like JS undefined.

Allow to add labels to expressions

It should be possible to add labels to expressions. The labels can then be used to call evaluate(..., [label, label, ...]) which just evaluates expressions having at least one of the given labels.

Support for removing existing ocl expressions from the list (evaluatedContexts)

Curent behavior

using addOclExpression always store new expression in a list until the oclEngine Restart. This is a Problem as soon as a User try to use it in a single page application i.e dont restart the engine after give a expression.

Desired behavior
next to OclEngine.addOclExpression() it will be good to have a methods like OclEngine.removeOclExpression() and/or OclEngine.clearAllOclExpressions(), in order to achieve the expected behavior in e.g in a SPA.

Support for isUnique

I have several status attributes in a class, each one being an array of an enumeration type. This is to handle when an attribute can be composed of multiple statuses. However, the attribute shouldn't contain multiple values of the same enumeration literal, i.e. its values should be unique. It seems OCL has a function for this, called isUnique

example constraint:

self.RejectionStatusType->isUnique(self)

I imagine for this to work, all OclExpressions must have a comparable value.

Update NPM package

I'd like to use this project from a node / npm context. There are a couple things that probably need to be squared away first:

  • generate .d.ts for TypeScript support
  • configure webpack to generate node friendly code

Build fails on Windows

npm run build fails on windows, with the following error

> rm -rf ./lib/components/parser/parser.ts && ts-node -O {\"module\":\"commonjs\"} generator/oclParserGenerator.ts

'rm' is not recognized as an internal or external command,
operable program or batch file.

This is causes by the use of the rm command in generate:parser. Recommend changing this to rimraf

Support for enumerations

I have some rules that look like this in my UML tool:

self.Type = VoterIdType::other implies not self.OtherType.oclIsUndefined()

or in English: OtherType must be defined when Type = other

other is a literal from the enumeration VoterIdType. ocl.js doesn't currently support enumerations, so I've ended up translating the rules to look something like this:

context VoterId 
inv ViOtherTypeMustBeDefined: self.Type <> "other" implies self.OtherType->oclIsUndefined()

I'm thinking that an API call could be added called something like registerEnumeration(name: string, literals: string[]). I'm unsure what the impact would be on the parser side.

TypeScript compiler not seeing declarations

When I compile my TypeScript project using the npm module @stekoe/ocl.js, it cannot find the index.d.ts file.

error TS7016: Could not find a declaration file for module '@stekoe/ocl.js'. '/mycodepath/node_modules/@stekoe/ocl.js/dist/ocl.min.js' implicitly has an 'any' type.
  Try `npm install @types/stekoe__ocl.js` if it exists or add a new declaration (.d.ts) file containing `declare module '@stekoe/ocl.js';`

However if I move the index.d.ts up a level (to ocl.js/) and change its body to

export * from './dist/components/OclEngine';

it works.

the 1.0.0-beta.8 version not working as expected using typescript

for a simple use case like described in the doc i get a error window is not define from ocl.min.js

given

import OclEngine from '@stekoe/ocl.js';

class Person {
    name: string;
    age: number;
    children: Person[];
    isMarried: boolean;
    husband: Person;
    wife: Person;
}

// const oclEngine = new OclEngine();

or 
const oclEngine = OclEngine.create();

expected
new instance of ocl engine

got
ReferenceError: window is not defined from node_modules\@stekoe\ocl.js\dist\ocl.min.js:1:286

Determine properties accessed by OCL Expression

I have a need to figure out which JSON properties were used (appeared) in an OcIInvariant that failed. This is to provide the end user contextual information about the JSON instance that was passed in (e.g. to highlight the properties whose values caused the failure). I believe this could be done thru the parser's AST (perhaps finding all VariableExpression). This method could lead to some positives (e.g. identify variables that were not touched due to short circuiting).

I'm open to other approaches as well.

Promises and Resolver binding

Hi!
I found your library very interesting to use in very specific way.
In early 2k there was a tool sounds like Bolder for Delphi, and later that company moved it to C# with name of ECO Enterprise Core Object. So from that time I’ve implemented many project learn js and many more things, but once I’be learn Ocl I can’t stop thinking of open source alternative for Eco.

So I’ve examined the code and I see that it has no promise support for async data handling. I think this is not big issue to stop using that.

Currently I’m using graphql for data backend, and I’ve found that ocl.js can be used with it.
So I thinking of using ocl in one of my open source project for handling complex data validation, derivation, and maybe for backend derived fields calculation.

Have you ever plan to support promises and async resolvers for custom operations?

Current state of the project?

Dear @SteKoe,

I am really interested in your project and it works pretty well!
I was wondering about the current state of it. The latest version available from npm is 1.2.0 while it seems you were working on the 1.3.0 version which adds (among other things) support for let expressions. I was wondering if you have any plan to release the last version. On the other hand, I found this Github repository which seems to be a fork of yours (releasing v1.3.0) but I am not sure how the two projects are related.

Thanks for your inputs.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.