as- core 3.1- 类型标记
以元模型3.1版本为基础,管理、核实和取消/串行资产管理壳.
这是一个软件开发工具包,用于:
- 操纵,
- 核实,和
- 与JSON之间除/序列化
...基于元模型3.1版本的资产管理贝壳.
简介见 开始。 。 。 .
API的详细文献资料见: API 文档。 。 。 .
我们在本节中记录了执行和接口选择的大部分理由 设计决定。 。 。 .
如果你想捐款,见我们 贡献指南。 。 。 .
请看 更改日志 用于各版本之间变化的列表.
开始
这里有一个快速的介绍 让你开始与SDK. 看你怎样才能:
- 安装 SDK, (中文(简体) ),
- 程序创建、获取和设定 AAS 模型的属性, (中文(简体) ),
- 切换运行时实例类型, (中文(简体) ),
- 重排、复制和转换一个模型, (中文(简体) ),
- 验证一个模型,以及
- 将一个模型从JSON去除/序列化。 。 。 .
安装 SDK
SDK 作为 npm 包可用 @aas-core-works/a-core3.1-typescript。 。 。 .
使用它安装 npm数字 :
npm install @aas-core-works/aas-core3.1-typescript
创建、获取和设定
模块 types 定义元模型的所有数据类型.
这包括类,界面和点数.
模块 types 也包含抽象的访客和变压器, 但我们会写更多关于他们的 斜体和变形 节.
创建
我们用建筑师来创建AAS模型.
通常从下而上,一直到 types.Environment。 。 。 .
获取和设置属性
类的所有属性被建模为TypeScript属性.
类初始化后,可以直接获得并修改其属性.
未设置的属性应当指定 null。 。 。 .
为了避免混乱和不必要的复杂,SDK并不期望 undefined 属性值.
带有默认值的获取器
对于带有默认值的可选属性,我们提供特殊的获取器, {property name}OrDefault。 。 。 .
如果财产是 null,该获取器会给出默认值.
否则,如果设定财产,则归还财产的实际价值.
例如,见 types.IHasKind.kindOrDefault。 。 。 .
示例: 创建带有子模型的环境
下面是一个非常简单的例子,我们展示如何创造一个包含子模型的环境.
子模型将包含两个元素,一个属性和一个blob.
import * as aas from "@aas-core-works/aas-core3.1-typescript";
// Create the first element
const someElement = new aas.types.Property(
aas.types.DataTypeDefXsd.Int
);
someElement.idShort = "someProperty";
someElement.value = "1984";
// Create the second element
const anotherElement = new aas.types.Blob(
"application/octet-stream"
);
anotherElement.idShort = "someBlob";
anotherElement.value = new Uint8Array([0xDE, 0xAD, 0xBE, 0xEF]);
// You can directly access the element properties.
anotherElement.value = new Uint8Array([0xDE, 0xAD, 0xC0, 0xDE]);
// Nest the elements in a submodel
const submodel = new aas.types.Submodel(
"some-unique-global-identifier"
);
submodel.submodelElements = [
someElement,
anotherElement
];
// Now create the environment to wrap it all up
const environment = new aas.types.Environment();
environment.submodels = [submodel];
// You can access the propreties from the children as well.
(<aas.types.Blob>environment.submodels![0].submodelElements![1]).value =
new Uint8Array([0xC0, 0x01, 0xCA, 0xFE]);
// Now you can do something with the `environment`...
切换运行时类型
JavaScript,并因此TypeScript,不支持多重继承.
因此,我们只引入一个单一的,最一般的抽象阶级 types.Class。 。 。 .
在元模型中被定义为"抽象类",我们执行为 接口 在类型脚本中.
所有混凝土阶级都继承了 types.Class 并指定它们执行的接口(“抽象类”).
虽然TypeScript允许我们定义接口,但它们只是用于在编译时保证类型安全,但不能用于运行时的类型开关.
这有影响,例如,当您想要选择属于类型的子模型元素时 types.Property。 。 。 .
TypeScript没有提供一个有效的方法来检查仅基于接口的运行时间类型.
为了能够有效进行类型投放和检查,我们执行各项职能 as{class name} 财务报告和审定财务报表 is{class name} 用于元模型的所有课程.
采用变压器模式(见该科) 斜体和变形 并且只执行几个调度功能呼叫.
职能 as{class name} 允许您 尝试 给特定类型的铸币局.
如果可以投影,则输入只需返回.
否则,函数返回 null。 。 。 .
这里有一个简短的例子: types.asProperty 财务报告和审定财务报表 types.asBlob数字 :
import * as aas from "@aas-core-works/aas-core3.1-typescript";
// Create the first element
const someElement = new aas.types.Property(
aas.types.DataTypeDefXsd.Int
);
someElement.idShort = "someProperty";
someElement.value = "1984";
console.log(aas.types.asProperty(someElement) === someElement)
// Prints: true
console.log(aas.types.asBlob(someElement) === null);
// Prints: true
职能 is{class name} 提供运行时间类型检查.
感谢 类型脚本类型断言 在签名时,TypeScript编译器可以自动推断出对成功检查的适当类型.
这里有一个简短的例子: types.isProperty 财务报告和审定财务报表 types.isBlob数字 :
import * as aas from "@aas-core-works/aas-core3.1-typescript";
// Create the first element
const someElement = new aas.types.Property(
aas.types.DataTypeDefXsd.Int
);
someElement.idShort = "someProperty";
someElement.value = "1984";
console.log(aas.types.isProperty(someElement))
// Prints: true
console.log(aas.types.isBlob(someElement));
// Prints: false
if (aas.types.isProperty(someElement)) {
// TypeScript compiler will automatically infer that `someElement`
// is a `types.Property` thanks to type assertions from
// `types.isProperty`.
console.log(someElement.value);
// Prints: 1984
}
这个 is* 财务报告和审定财务报表 as* 函数假设您提前知道检查中的预期类型.
如果您使用一个原型来定义一个类型, 或想要检查两个实例是否共享同一个类型, 则此操作无效, 因为您无法从一个实例中提取该类型信息 .
对于这些情况,我们规定:typesMatch]函数 :
import * as aas from "@aas-core-works/aas-core3.1-typescript";
// Create a property
const aProperty = new aas.types.Property(
aas.types.DataTypeDefXsd.Int
);
// Create a blob
const aBlob = new aas.types.Blob(
"text/plain"
);
// Create another property
const anotherProperty = new aas.types.Property(
aas.types.DataTypeDefXsd.Decimal
);
// Check the type matches
console.log(aas.types.typesMatch(aProperty, aProperty))
// Prints: true
console.log(aas.types.typesMatch(aProperty, aBlob))
// Prints: false
console.log(aas.types.typesMatch(aProperty, anotherProperty))
// Prints: true
斜体和变形
SDK提供了多种途径,可以使模型的元素循环,以及这些元素如何被转化. 以下各节将探讨其中一种办法.
over*OrEmpty
所有可选列表都有相应的 over{property name}OrEmpty 盖特.
它给你一个 IterableIterator。 。 。 .
如果财产没有设定(即说. 设置为 null),这个得到器会空出.
否则,它将产生实际财产价值.
例如,见 types.Environment.overSubmodelsOrEmpty。 。 。 .
descend 财务报告和审定财务报表 descendOnce
如果你正在写一个简单的脚本,而不关心表演,SDK在最抽象的类中提供了两种方法 types.Class, (中文(简体) ), descendOnce 财务报告和审定财务报表 descend,用于循环实例.
两者 descendOnce 财务报告和审定财务报表 descend 过量提及的儿童 types.Class。 。 。 .
方法 descendOnce正如名字所暗示的, 在所有紧要的孩子 被累累过之后,停止.
方法 descend 孙子孙女孙子孙女孙子孙女孙子孙女孙子孙女孙子孙女孙子孙女孙女孙子孙女孙子孙女孙子孙子孙子孙子孙子孙子孙子孙子孙子孙子孙子孙子孙子孙子孙子孙子孙子孙子孙子孙子孙子孙子孙子孙子孙子孙子孙子孙子孙子孙相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相继相续相续相续相续相续相续相续相续相续相续相续相续相续相续相续相续相续相续相续相续相续相续相续相续相续 包括:.
以下是一个简短的例子: 您可以从一个环境获得所有属性, 其ID短从另一个环境开始 :
import * as aas from "@aas-core-works/aas-core3.1-typescript";
// Prepare the environment
const someElement = new aas.types.Property(
aas.types.DataTypeDefXsd.Int
);
someElement.idShort = "someProperty";
someElement.value = "1984";
const anotherElement = new aas.types.Property(
aas.types.DataTypeDefXsd.Int
);
anotherElement.idShort = "anotherProperty";
anotherElement.value = "1985";
const yetAnotherElement = new aas.types.Property(
aas.types.DataTypeDefXsd.Int
);
yetAnotherElement.idShort = "yetAnotherProperty";
yetAnotherElement.value = "1986";
const submodel = new aas.types.Submodel(
"some-unique-global-identifier"
);
submodel.submodelElements = [
someElement,
anotherElement,
yetAnotherElement
];
const environment = new aas.types.Environment();
environment.submodels = [submodel];
// Iterate using `descend`
for (const something of environment.descend()) {
if (
aas.types.isProperty(something)
&& something.idShort?.toLowerCase().includes("another")
) {
console.log(something.idShort);
}
}
// Prints:
// anotherProperty
// yetAnotherProperty
重排为 descendOnce 财务报告和审定财务报表 descend 如果表现无关紧要,效果会很好.
然而,如果业绩很重要,这不是一个好办法.
首先,所有的孩子都会被探视(尽管你只需要一个小子集).
第二,你执行循环中每个实例的循环正文.
在以上示例中,您检查运行时间类型 types.isProperty 引用的每个实例 types.Environment。 。 。 .
让我们在下一节中看看,我们如何使用更有效的方法,尽管也使用更复杂的方法.
访客
访客模式 是软件工程中常见的设计模式. 我们不会在这里解释图案的细节,因为你们可以在书籍或互联网上的丰富文献中看到.
游客模式的基石是: 双发:在迭代过程中不向理想类型投影,而是投影方法 accept 联 合 国 types.Class 直接发送到适当的访问方法.
这使得我们能够节省运行时间类型开关并直接发送执行.
SDK 已经执行 accept 方法,所以你只需要执行访问者.
访问者班对元模的每个班都有访问方法. 在SDK中,我们提供不同的风味 游客抽象课程,你可以随时执行:
AbstractVisitor需要落实所有访问方法,PassThroughVisitor访问所有元素却无所作为AbstractVisitorWithContext它沿迭代传播上下文对象.
让我们重写上述例子 descend 使用访问者模式的方法 :
import * as aas from "@aas-core-works/aas-core3.1-typescript";
// Prepare the environment
const someElement = new aas.types.Property(
aas.types.DataTypeDefXsd.Int
);
someElement.idShort = "someProperty";
someElement.value = "1984";
const anotherElement = new aas.types.Property(
aas.types.DataTypeDefXsd.Int
);
anotherElement.idShort = "anotherProperty";
anotherElement.value = "1985";
const yetAnotherElement = new aas.types.Property(
aas.types.DataTypeDefXsd.Int
);
yetAnotherElement.idShort = "yetAnotherProperty";
yetAnotherElement.value = "1986";
const submodel = new aas.types.Submodel(
"some-unique-global-identifier"
);
submodel.submodelElements = [
someElement,
anotherElement,
yetAnotherElement
];
const environment = new aas.types.Environment();
environment.submodels = [submodel];
// Implement the visitor
class Visitor extends aas.types.PassThroughVisitor {
visitProperty(that: aas.types.Property): void {
if (that.idShort?.toLowerCase().includes("another")) {
console.log(that.idShort);
}
}
}
// Iterate
const visitor = new Visitor();
visitor.visit(environment);
// Prints:
// anotherProperty
// yetAnotherProperty
重复与 descend数字 :
- 由于双发,我们节省了一个铸件. 这通常更有效率.
- 重排逻辑
descend住在离处决地点很近的地方. 相比之下,访问者需要被定义为一个单独的班级. 虽然有时写得更快,但写给来访者会使代码的可读性更差.
登机还是访客?
一般来说,熟悉 访客模式 显然,面向对象的编程更喜欢访问类.
喜欢功能编程、生成表达式和ilks的人会更喜欢 descend。 。 。 .
很难讨论不同的口味,所以你也许应该想出 明确的代码指南 并坚持它们.
在牺牲可读性之前,要始终做到剖面,出于性能原因,盲目应用一种或另一种方法.
变形器
变压器模式类似于 访客模式,其中,我们“转换”访问的元素为某种其他形式(无论是字符串还是不同的对象). 在编译器设计中非常常见,抽象的语法树被转换为不同的代表.
SDK提供了不同的变压器口味:
AbstractTransformer,其中模型元素被直接转化为某种东西,以及AbstractTransformerWithContext,它沿变换传播上下文对象.
通常你执行每个混凝土类 如何改造它.
如果您想要只指定一个子集的变换, 并提供其余的默认值, SDK 提供 TransformerWithDefault 财务报告和审定财务报表 TransformerWithDefaultAndContext。 。 。 .
由于代码的长度,我们故意省略了一个例子. 请让我们知道,如果你想在此举个例子的话.
数字字面上的斜体
类型脚本特性 计数 作为语言的核心部分. 然而,在JavaScript中不支持这些点数,它们如何在JavaScript中被代表要由转接器决定.
我们用数字字形来捕捉元模型中的计数(见节) 设计决定) (中文(简体) ).
虽然有 过度统计的方法,当使用数字计数词时,代码并不特别安全.
例如: 字形常被作为字符串来标注,尽管取出字形最初是作为整数来标注.
此外,所有的代码片段 似乎相当混乱我们.
因此,我们提供 over{enumeration name} 函数在 types 模块,您可以使用该模块在引用字元时进行排列.
例如,见[types.overAasSubmodelElements[ [ ] [ ] ]. ].
如果你想得到字面上的字符串代表,我们提供[stringification模块.
职能 stringification.{enumeration name}ToString 给回字面上的字符串表示,或者 null 如果文字无效.
为了方便客户,我们SDK也执行功能 stringification.must{enumeration name}ToString 以返回字符串表达式,或扔出出错误.
如果你确信你的代码只处理正确的字面, stringification.must{enumeration name}ToString 将节省一个无效检查.
例如,见 stringification.modelingKindToString 财务报告和审定财务报表 stringification.mustModelingKindToString。 。 。 .
以下是一个简单的例子,说明如何绕过点数的字词 types.ModelingKind 使用函数 types.overModelingKind数字 :
import * as aas from "@aas-core-works/aas-core3.1-typescript";
for (const literal of aas.types.overModelingKind()) {
const asString = aas.stringification.mustModelingKindToString(literal);
console.log(
`${literal} ${typeof (literal)} ${asString}`
);
}
// Prints:
// 0 number Template
// 1 number Instance
校验
我们的SDK允许你验证一个模型满足了元模型的局限性.
校验逻辑集中在模块中 verification需要的只是呼吁 verification.verify 函数.
职能 verification.verify 将检查特定模式要素的制约因素是否得到满足,包括再次出现儿童要素.
函数返回一个 IterableIterator 联 合 国 verification.VerificationError',可以用于进一步处理的 (譬如说.,向用户报告).
以下是一个简短的例子:
import * as aas from "@aas-core-works/aas-core3.1-typescript";
// Prepare the environment
const someElement = new aas.types.Property(
aas.types.DataTypeDefXsd.Int
);
// The ID-shorts must be proper variable names,
// but there is a dash (`-`) in this ID-short.
someElement.idShort = "some-property";
someElement.value = "1984";
const submodel = new aas.types.Submodel(
"some-unique-global-identifier"
);
submodel.submodelElements = [someElement];
const environment = new aas.types.Environment();
environment.submodels = [submodel];
for (const error of aas.verification.verify(environment)) {
console.log(`${error.path}: ${error.message}`);
}
// Prints:
// .submodels[0].submodelElements[0].idShort: ID-short of Referables
// shall only feature letters, digits, underscore (``_``);
// starting mandatory with a letter. *I.e.* ``[a-zA-Z][a-zA-Z0-9_]+``.
如果您仅想要检查当前实例, 且您不希望校验重现到孩子中, 请提供第二个参数 recurse 设置为 false 致秘书长的信 verification.verify数字 :
for (const error of verification.verify(environment, false)) {
console.log(`${error.path}: ${error.message}`);
}
// Does not print anything as environment instance for itself
// is valid. However, the submodel elements beneath the environment
// are invalid, but this verification is not recursive.
限制已报告错误的数量
由于职能 verification.verify 给你一个 IterableIterator,你可以简单地打破循环.
例如,只报告前10个错误(假设代码来自以上例子):
let reportedErrors = 0;
for (const error of verification.verify(environment)) {
console.log(`${error.path}: ${error.message}`);
reportedErrors++;
if (reportedErrors === 10) {
break;
}
}
受到的限制
元模型中指定的限制并非全部可以验证. 一些制约因素需要外部依赖性,例如AAS登记册. 核查外部依赖性的限制,超出了我们的SDK的范围,因为我们仍然缺乏与这些依赖性有关的标准化接口.
然而,所有需要限制的因素 没有 外部依赖性得到核实.
完整的例外清单请见模块说明 types。 。 。 .
JSON 取消/序列化
我们的SDK通过模块处理AAS模型从JSON格式到JSON格式的去/串行化 jsonization。 。 。 .
序列化
要序列化,请调用函数 jsonization.toJsonable 例如 types.Class 它将转换为 JSON 可读 JavaScript 对象.
以下是一个片段,它首先将环境转换为JSON可读对象,然后将JSON可读对象转换为文本:
import * as aas from "@aas-core-works/aas-core3.1-typescript";
// Prepare the environment
const someElement = new aas.types.Property(
aas.types.DataTypeDefXsd.Int
);
someElement.idShort = "someProperty";
someElement.value = "1984";
const submodel = new aas.types.Submodel(
"some-unique-global-identifier"
);
submodel.submodelElements = [someElement];
const environment = new aas.types.Environment();
environment.submodels = [submodel];
// Serialize to a JSON-able object
const jsonable = aas.jsonization.toJsonable(environment);
// Convert the JSON-able object to a string
const text = JSON.stringify(jsonable, null, 2);
console.log(text);
// Prints:
// {
// "submodels": [
// {
// "id": "some-unique-global-identifier",
// "submodelElements": [
// {
// "idShort": "some_property",
// "valueType": "xs:int",
// "value": "1984",
// "modelType": "Property"
// }
// ],
// "modelType": "Submodel"
// }
// ]
// }
取消序列
我们的SDK可以将 JSON 可读对象转换为 types.Class。 。 。 .
为此,你称适当功能 jsonization.{class name}FromJsonable。 。 。 .
例如,如果你想将一个实例去序列化 types.Environment电话 jsonization.environmentFromJsonable。 。 。 .
注意 SDK 不能自动将类作为歧视者的财产去序列化 modelType 不包括在序列式中 全部 上课.
因此,如果没有提供歧视性财产,我们就不能仅仅从序列中了解案件的实际类型.
见 本节论述AAS样本中的歧视者 更多细节.
职能 jsonization.{class name}FromJsonable 返回一个 "两个"结构:或者成功去序列化实例,或者存在去序列化错误,如果有的话.
如果有错误,它的财产 error 将被设定.
否则,财产 value 将包含去序列化实例.
如果您喜欢在去序列化错误时丢弃例外, 并且不想检查 error 明确,然后调用方法 mustValue。 。 。 .
我们使用 "两个"结构 (有时也叫"脱节结合")而不是例外来避免代价高昂的堆起倒塌. 堆叠倒取有道理,如果你想的话,因为代码行与去序列化错误无关.
这里有一个例子片段 来告诉你如何去序列化一个实例 types.Environment数字 :
import * as aas from "@aas-core-works/aas-core3.1-typescript";
const text = `
{
"submodels": [
{
"id": "some-unique-global-identifier",
"submodelElements": [
{
"idShort": "someProperty",
"valueType": "xs:boolean",
"modelType": "Property"
}
],
"modelType": "Submodel"
}
]
}
`;
const jsonable = JSON.parse(text);
const instanceOrError = aas.jsonization.environmentFromJsonable(
jsonable
);
if (instanceOrError.error !== null) {
console.log(
"De-serialization failed: " +
`${instanceOrError.error.path}: ` +
`${instanceOrError.error.message}`
);
}
// Doesn't print anything as `text` is
// a valid representation.
const environment = instanceOrError.mustValue();
for (const something of environment.descend()) {
console.log(something.constructor.name);
}
// Prints:
// Submodel
// Property
API 密码
API的详细文献资料见: API 文档。 。 。 .
设计决定
我们在这里介绍了我们在设计和实施SDK过程中所作的一些选择. 虽然没有必要理解我们的想法 使用情况 sDK,我们解释为什么我们按我们的方式 来组织和编程SDK. 希望这能澄清一些困惑,或缓解挫折感,如果你想以不同方式实施某些特征的话.
编号为数字
我们优化了检查和比较的点数,而不是字符串代表. 因此,我们将文字作为数字(而不是字符串)执行. 例如,由于散列值直接在通常只涉及几个算术的数值上计算,这就使得查找速度更快.
与此相反,如果将点数字作为字符串列出,则需要通过延时计算字的散列值 所有字符 字符串.
构造器中没有参数属性
参数属性 建筑人签名是界定某一类的公共和私人财产的简洁方式.
当我们使用TSDoc编写文档,记录属性时 在构造器中 伤害可读性. 因此,我们产生属性(有文件)与类体的构造器分开.
与元模型不同的继承等级
AAS元模型采用多相继承.
然而,TypeScript只支持单一继承.
此外,如果继承链很长,则与 instanceof 时间的复杂性可能是线性的.
请参看,例如: 重叠流问题: instanceof
而不是多重继承 我们使用接口并提供 is* 财务报告和审定财务报表 as* 函数可以在运行时动态决定实例类型.
所有班级都继承最普通的班级 types.Class。 。 。 .
请参见第1节 切换运行时类型。 。 。 .
使用 Either 构造
我们用 "两个"结构 在去串行化中,因为JavaScript引擎无法保证对尝试捕获块进行优化. 例如,见:, 关于尝试/捕获块效率的重叠流问题。 。 。 .
通过使用 Either我们可以去除尝试/捕捉到的块 并刮去很多循环.
见节 取消序列 更多信息.
无 XML
我们没有执行 XML , 因为截至本次写作( 2022-12- 21) 时, 我们无法找到一个坚实的库, 它既适用于 NodeJS , 也适用于浏览器 . 我们最接近的是 萨克斯.js,但似乎不再保留(见 sax.js仓库中有关维护的这个问题) (中文(简体) ). 有多个叉子,例如 萨克斯但他们的能见度和关注度似乎要低得多.
我们愿意听取建议,我们当然愿意重新评估我们目前关于跳过AAS模式XML去/串行化的决定.
字节为 Uint8Array
在TypeScript(和JavaScript)中执行一个字节数组的方法多种多样.
例如,我们可以使用纯字符串(但有限制,代码点仅限于范围) [0, 255]) (中文(简体) ).
另一种表述方式是使用数字阵列(Array<number>),并将数字限制在幅度内 [0, 255]。 。 。 .
还有其他许多.
我们终于安定下来了 Uint8Array 这对我们来说是最自然的.
反对字符串和数组数字, Uint8Array 通常以内存高效的方式执行(每个字节点一个字节,而不是字符串2个字节,或者数字数组8个字节).
不过, Uint8Array''是不可改变的,所以任何更改都涉及一并写.
我们认为这种案例在申请中是罕见的,但这可以进行辩论.
请 创建问题 如果您的应用程序需要可变字节数组, 以便我们可以讨论其他选项 .
内部基地64 解码/编码
这个 base64 编码 用于浏览器和节点的应用不同. 浏览器平台提供 atob (英语) 财务报告和审定财务报表 btoa 数据 函数,虽然常用 节点缓冲。 。 。 .
我们执行我们自己的 base64 编码 并进行编解码,因为我们希望在不同的平台上有一个单独的实施(譬如说.,浏览器和节点.
此外,我们表示的字节值是: Uint8Array,因此我们也确保我们的基础64执行直接促进 Uint8Array对.
例如,如果我们使用 atob (英语) 我们必须把弦转换成 Uint8Array,至少需要额外的内存副本.
请注意,我们的执行工作也因缺乏贴补检查而受到影响(见此) 贴纸检查当我们在野外遵循广泛使用的算法. 根据同样的 贴纸检查,这种脆弱性存在于Python,PHP,JavaScript,Node.js等标准库中.
贡献指南
问题
请报告错误或特性请求 创建 GitHub 问题。 。 。 .
在代码中
如果你想在代码中贡献,欢迎拉请求!
请吧 创建一个新问题 在你潜入编码之前. 很可能我们已经开始研究这个特点,或者说,有些上下游的复杂性你可能不知道.
SDK 代码生成
代码的最大部分已经自动生成 as- core- 代码源。 。 。 . 改变生成器,而不是增加新的功能,可能最有意义. 然而,这需要逐案决定.
要重生成代码 :
-
创建虚拟环境 :
python3 -m venv venv -
激活虚拟环境( 在 Windows 上):
venv/Scripts/activate... 或在 Linux/ Mac 上:
source venv/bin/activate -
安装开发依赖 :
pip3 install --editable dev_scripts --group dev_scripts/pyproject.toml:dev -
运行将下载最新Aas-core-meta模型的主要更新脚本,以及重新生成代码并重新记录测试数据:
python dev_scripts/update_all.py
构建文档
我们用 类型文件 用于构建文档:
npx typedoc --out doc-local src/
在此命令之后,文档可在 doc-local 目录.
承诺前检查
请运行 :
npm run lint && npm run build && npm run test
...在每个人承诺之前.
要自动重格式化代码 :
npm run format
调取请求
地缘分枝. 我们开发的特色分支,看 吉特书的这一部分。 。 。 .
如果您是开发团队的成员,则直接在寄存器内创建一个特征分支.
否则,如果您是非会员贡献者,请将寄存器叉出并创建功能分支于您所创建的寄存器. 见 此 GitHub 教程 以更多的引导.
分行前缀. 请用您的 Github 用户名在分支前加注(譬如说., (中文(简体) ), mristin/Add-some-feature) (中文(简体) ).
不断融合. GitHub将通过GitHub动作自动运行连续集成(CI). CI包括运行测试,检查代码,重建文档 包括:.
提交信件
承诺信息遵循了https://chris.beams.io/posts/git-committe:
- 用空白行将主体与身体分开,
- 将主题行限制为50个字符,
- 资本化主题行,
- 不以周期结束主题行,
- 用主题线上必须的心情,
- 以72个字符包起尸体
- 用尸体来解释 什麽 财务报告和审定财务报表 为什么 (代替 怎么样) (中文(简体) ).
更改日志
1.0.0-rc.1 (2025-12-09) (中文(简体) )
- 初步版本,可供第一次审议