@owlmeans/planning 0.1.18-rc.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/README.md +169 -0
- package/agent-meta/manifest.json +16 -0
- package/agent-meta/skills/planning/SKILL.md +248 -0
- package/build/consts.d.ts +126 -0
- package/build/consts.d.ts.map +1 -0
- package/build/consts.js +129 -0
- package/build/consts.js.map +1 -0
- package/build/entrypoints.d.ts +14 -0
- package/build/entrypoints.d.ts.map +1 -0
- package/build/entrypoints.js +69 -0
- package/build/entrypoints.js.map +1 -0
- package/build/errors.d.ts +94 -0
- package/build/errors.d.ts.map +1 -0
- package/build/errors.js +169 -0
- package/build/errors.js.map +1 -0
- package/build/helpers/apply.d.ts +27 -0
- package/build/helpers/apply.d.ts.map +1 -0
- package/build/helpers/apply.js +162 -0
- package/build/helpers/apply.js.map +1 -0
- package/build/helpers/card.d.ts +17 -0
- package/build/helpers/card.d.ts.map +1 -0
- package/build/helpers/card.js +31 -0
- package/build/helpers/card.js.map +1 -0
- package/build/helpers/changes.d.ts +51 -0
- package/build/helpers/changes.d.ts.map +1 -0
- package/build/helpers/changes.js +277 -0
- package/build/helpers/changes.js.map +1 -0
- package/build/helpers/code.d.ts +24 -0
- package/build/helpers/code.d.ts.map +1 -0
- package/build/helpers/code.js +47 -0
- package/build/helpers/code.js.map +1 -0
- package/build/helpers/index.d.ts +9 -0
- package/build/helpers/index.d.ts.map +1 -0
- package/build/helpers/index.js +9 -0
- package/build/helpers/index.js.map +1 -0
- package/build/helpers/query.d.ts +39 -0
- package/build/helpers/query.d.ts.map +1 -0
- package/build/helpers/query.js +293 -0
- package/build/helpers/query.js.map +1 -0
- package/build/helpers/specification.d.ts +21 -0
- package/build/helpers/specification.d.ts.map +1 -0
- package/build/helpers/specification.js +48 -0
- package/build/helpers/specification.js.map +1 -0
- package/build/helpers/status.d.ts +44 -0
- package/build/helpers/status.d.ts.map +1 -0
- package/build/helpers/status.js +78 -0
- package/build/helpers/status.js.map +1 -0
- package/build/helpers/validate.d.ts +30 -0
- package/build/helpers/validate.d.ts.map +1 -0
- package/build/helpers/validate.js +93 -0
- package/build/helpers/validate.js.map +1 -0
- package/build/i18n/be.json +51 -0
- package/build/i18n/de.json +51 -0
- package/build/i18n/en.json +51 -0
- package/build/i18n/es.json +51 -0
- package/build/i18n/pl.json +51 -0
- package/build/i18n/ru.json +51 -0
- package/build/i18n/uk.json +51 -0
- package/build/i18n.d.ts +2 -0
- package/build/i18n.d.ts.map +1 -0
- package/build/i18n.js +19 -0
- package/build/i18n.js.map +1 -0
- package/build/index.d.ts +10 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +9 -0
- package/build/index.js.map +1 -0
- package/build/models/index.d.ts +7 -0
- package/build/models/index.d.ts.map +1 -0
- package/build/models/index.js +19 -0
- package/build/models/index.js.map +1 -0
- package/build/models/project.d.ts +4 -0
- package/build/models/project.d.ts.map +1 -0
- package/build/models/project.js +17 -0
- package/build/models/project.js.map +1 -0
- package/build/models/specification.d.ts +4 -0
- package/build/models/specification.d.ts.map +1 -0
- package/build/models/specification.js +15 -0
- package/build/models/specification.js.map +1 -0
- package/build/models/workcard.d.ts +14 -0
- package/build/models/workcard.d.ts.map +1 -0
- package/build/models/workcard.js +103 -0
- package/build/models/workcard.js.map +1 -0
- package/build/queue/index.d.ts +25 -0
- package/build/queue/index.d.ts.map +1 -0
- package/build/queue/index.js +14 -0
- package/build/queue/index.js.map +1 -0
- package/build/registry.d.ts +10 -0
- package/build/registry.d.ts.map +1 -0
- package/build/registry.js +75 -0
- package/build/registry.js.map +1 -0
- package/build/schemas.d.ts +56 -0
- package/build/schemas.d.ts.map +1 -0
- package/build/schemas.js +578 -0
- package/build/schemas.js.map +1 -0
- package/build/types.d.ts +785 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +2 -0
- package/build/types.js.map +1 -0
- package/package.json +58 -0
- package/src/consts.ts +136 -0
- package/src/entrypoints.ts +127 -0
- package/src/errors.ts +207 -0
- package/src/helpers/apply.ts +183 -0
- package/src/helpers/card.ts +42 -0
- package/src/helpers/changes.ts +333 -0
- package/src/helpers/code.ts +66 -0
- package/src/helpers/index.ts +8 -0
- package/src/helpers/query.ts +345 -0
- package/src/helpers/specification.ts +65 -0
- package/src/helpers/status.ts +117 -0
- package/src/helpers/validate.ts +107 -0
- package/src/i18n/be.json +51 -0
- package/src/i18n/de.json +51 -0
- package/src/i18n/en.json +51 -0
- package/src/i18n/es.json +51 -0
- package/src/i18n/pl.json +51 -0
- package/src/i18n/ru.json +51 -0
- package/src/i18n/uk.json +51 -0
- package/src/i18n.ts +21 -0
- package/src/index.ts +9 -0
- package/src/models/index.ts +21 -0
- package/src/models/project.ts +24 -0
- package/src/models/specification.ts +21 -0
- package/src/models/workcard.ts +138 -0
- package/src/queue/index.ts +31 -0
- package/src/registry.ts +90 -0
- package/src/schemas.ts +654 -0
- package/src/types.ts +837 -0
- package/tests/apply.spec.ts +176 -0
- package/tests/code.spec.ts +40 -0
- package/tests/entrypoints.spec.ts +57 -0
- package/tests/fixtures.ts +124 -0
- package/tests/i18n.spec.ts +30 -0
- package/tests/models.spec.ts +133 -0
- package/tests/query.spec.ts +90 -0
- package/tests/schemas.spec.ts +74 -0
- package/tests/status.spec.ts +75 -0
- package/tests/tsconfig.json +17 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { ANY_STATUS, INTRINSIC_ORDER, IntrinsicPolicy, IntrinsicStatus } from '../consts.js';
|
|
2
|
+
import { PlanningError, UnknownStatusFlow } from '../errors.js';
|
|
3
|
+
/** The primary flow id of a type — `flows[0]`. @throws {UnknownStatusFlow} when it declares none */
|
|
4
|
+
export const primaryFlowOf = (type) => {
|
|
5
|
+
const primary = type.flows[0];
|
|
6
|
+
if (primary == null) {
|
|
7
|
+
throw new UnknownStatusFlow(`${type.type}:primary`);
|
|
8
|
+
}
|
|
9
|
+
return primary;
|
|
10
|
+
};
|
|
11
|
+
export const flowIdsOf = (type) => [...type.flows];
|
|
12
|
+
export const statusDefinitionOf = (flow, status) => flow.statuses.find(definition => definition.key === status);
|
|
13
|
+
/** The intrinsic state a status maps onto, or `undefined` for a status the flow does not declare. */
|
|
14
|
+
export const intrinsicOf = (flow, status) => statusDefinitionOf(flow, status)?.intrinsic;
|
|
15
|
+
/** The status marked `initial`, else the first one. @throws {PlanningError} for a flow with none */
|
|
16
|
+
export const initialStatusOf = (flow) => {
|
|
17
|
+
const status = flow.statuses.find(definition => definition.initial === true) ?? flow.statuses[0];
|
|
18
|
+
if (status == null) {
|
|
19
|
+
throw new PlanningError(`flow-empty:${flow.id}`);
|
|
20
|
+
}
|
|
21
|
+
return status.key;
|
|
22
|
+
};
|
|
23
|
+
export const isTerminal = (flow, status) => statusDefinitionOf(flow, status)?.terminal === true;
|
|
24
|
+
const fromMatches = (rule, status) => rule.from === ANY_STATUS || (Array.isArray(rule.from) && rule.from.includes(status));
|
|
25
|
+
/**
|
|
26
|
+
* The rule a named transition follows from a status.
|
|
27
|
+
*
|
|
28
|
+
* A name may be declared several times with different `from` sets; the rule naming the status
|
|
29
|
+
* explicitly wins, and a `'*'` rule of that name answers only when none does.
|
|
30
|
+
*/
|
|
31
|
+
export const ruleOf = (flow, transition, from) => {
|
|
32
|
+
const named = flow.transitions.filter(rule => rule.name === transition);
|
|
33
|
+
return named.find(rule => rule.from !== ANY_STATUS && fromMatches(rule, from))
|
|
34
|
+
?? named.find(rule => rule.from === ANY_STATUS);
|
|
35
|
+
};
|
|
36
|
+
export const canTransit = (flow, transition, from) => ruleOf(flow, transition, from) != null;
|
|
37
|
+
/**
|
|
38
|
+
* Every transition available from a status, one rule per name (the one `ruleOf` would pick), in
|
|
39
|
+
* declaration order. `explicit: true` keeps only the rules offered to a person.
|
|
40
|
+
*/
|
|
41
|
+
export const transitionsFrom = (flow, status, opts) => {
|
|
42
|
+
const names = [...new Set(flow.transitions.map(rule => rule.name))];
|
|
43
|
+
return names.map(name => ruleOf(flow, name, status))
|
|
44
|
+
.filter((rule) => rule != null)
|
|
45
|
+
.filter(rule => opts?.explicit !== true || rule.explicit === true);
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* A new card's status per flow: every flow's initial status, with the primary one overridden by
|
|
49
|
+
* `status` when the draft names one.
|
|
50
|
+
*
|
|
51
|
+
* @throws {UnknownStatusFlow}
|
|
52
|
+
*/
|
|
53
|
+
export const initialFlowsOf = (type, registry, status) => {
|
|
54
|
+
const primary = primaryFlowOf(type);
|
|
55
|
+
return Object.fromEntries(type.flows.map(id => [
|
|
56
|
+
id, id === primary && status != null ? status : initialStatusOf(registry.flow(id)),
|
|
57
|
+
]));
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* The card's intrinsic state over its flows. {@link IntrinsicPolicy.Primary} reads the primary
|
|
61
|
+
* flow; {@link IntrinsicPolicy.All} takes the least advanced flow. A status the flow does not
|
|
62
|
+
* declare reads as planned.
|
|
63
|
+
*
|
|
64
|
+
* @throws {UnknownStatusFlow}
|
|
65
|
+
*/
|
|
66
|
+
export const resolveIntrinsic = (type, flows, registry) => {
|
|
67
|
+
const read = (id) => {
|
|
68
|
+
const status = flows[id];
|
|
69
|
+
return status == null
|
|
70
|
+
? IntrinsicStatus.Planned
|
|
71
|
+
: intrinsicOf(registry.flow(id), status) ?? IntrinsicStatus.Planned;
|
|
72
|
+
};
|
|
73
|
+
if (type.intrinsic !== IntrinsicPolicy.All) {
|
|
74
|
+
return read(primaryFlowOf(type));
|
|
75
|
+
}
|
|
76
|
+
return type.flows.map(read).reduce((least, intrinsic) => INTRINSIC_ORDER[intrinsic] < INTRINSIC_ORDER[least] ? intrinsic : least, IntrinsicStatus.Closed);
|
|
77
|
+
};
|
|
78
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/helpers/status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Ajv } from 'ajv';
|
|
2
|
+
import type { ErrorObject } from 'ajv';
|
|
3
|
+
import type { PlanningSchemaRegistry, SpecificationSlot, Workcard } from '../types.js';
|
|
4
|
+
/** The ajv every planning validation compiles with: lenient about unknown keywords, all errors, formats. */
|
|
5
|
+
export declare const makeAjv: () => Ajv;
|
|
6
|
+
/** One line per ajv error: `/path message`. */
|
|
7
|
+
export declare const ajvErrorText: (errors?: ErrorObject[] | null) => string;
|
|
8
|
+
/** Keys holding `.` or `$` at any depth — a document store cannot hold them. */
|
|
9
|
+
export declare const invalidFieldKeys: (fields: unknown, path?: string) => string[];
|
|
10
|
+
/**
|
|
11
|
+
* Check `fields` against the type's schema, and its keys against the store rule.
|
|
12
|
+
*
|
|
13
|
+
* @throws {FieldsInvalid}
|
|
14
|
+
*/
|
|
15
|
+
export declare const validateFields: (registry: Pick<PlanningSchemaRegistry, 'validator'>, type: string, fields: Record<string, unknown>) => void;
|
|
16
|
+
/**
|
|
17
|
+
* Check a whole record: its shape by kind, then its `fields` by type.
|
|
18
|
+
*
|
|
19
|
+
* @throws {PlanningError} `malformed:card:…` for a shape fault
|
|
20
|
+
* @throws {FieldsInvalid}
|
|
21
|
+
*/
|
|
22
|
+
export declare const validateCard: (card: Workcard, registry: Pick<PlanningSchemaRegistry, 'validator'>) => void;
|
|
23
|
+
/**
|
|
24
|
+
* Check a document body against its slot: a JSON slot must parse, and match the slot's schema when
|
|
25
|
+
* it declares one.
|
|
26
|
+
*
|
|
27
|
+
* @throws {FieldsInvalid}
|
|
28
|
+
*/
|
|
29
|
+
export declare const validateSpecificationBody: (slot: SpecificationSlot, body?: string | null) => void;
|
|
30
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/helpers/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AACzB,OAAO,KAAK,EAAE,WAAW,EAAoB,MAAM,KAAK,CAAA;AAKxD,OAAO,KAAK,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAEtF,4GAA4G;AAC5G,eAAO,MAAM,OAAO,QAAO,GAK1B,CAAA;AAgBD,+CAA+C;AAC/C,eAAO,MAAM,YAAY,YAAa,WAAW,EAAE,GAAG,IAAI,KAAG,MAE9C,CAAA;AAEf,gFAAgF;AAChF,eAAO,MAAM,gBAAgB,WAAY,OAAO,SAAQ,MAAM,KAAQ,MAAM,EAY3E,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,cAAc,aACf,IAAI,CAAC,sBAAsB,EAAE,WAAW,CAAC,QAAQ,MAAM,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KACjG,IASF,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,YAAY,SAAU,QAAQ,YAAY,IAAI,CAAC,sBAAsB,EAAE,WAAW,CAAC,KAAG,IAQlG,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,SAAU,iBAAiB,SAAS,MAAM,GAAG,IAAI,KAAG,IAgBzF,CAAA"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { Ajv } from 'ajv';
|
|
2
|
+
import formatsPlugin from 'ajv-formats';
|
|
3
|
+
import { SpecificationFormat, WorkcardKind } from '../consts.js';
|
|
4
|
+
import { FieldsInvalid, PlanningError } from '../errors.js';
|
|
5
|
+
import { AnyWorkcardSchema, SpecificationSchema, WorkcardSchema } from '../schemas.js';
|
|
6
|
+
/** The ajv every planning validation compiles with: lenient about unknown keywords, all errors, formats. */
|
|
7
|
+
export const makeAjv = () => {
|
|
8
|
+
const ajv = new Ajv({ strict: false, allErrors: true });
|
|
9
|
+
formatsPlugin(ajv);
|
|
10
|
+
return ajv;
|
|
11
|
+
};
|
|
12
|
+
let shared;
|
|
13
|
+
const ajvOf = () => shared ??= makeAjv();
|
|
14
|
+
const compiled = new Map();
|
|
15
|
+
const compile = (schema) => {
|
|
16
|
+
let validate = compiled.get(schema);
|
|
17
|
+
if (validate == null) {
|
|
18
|
+
validate = ajvOf().compile(schema);
|
|
19
|
+
compiled.set(schema, validate);
|
|
20
|
+
}
|
|
21
|
+
return validate;
|
|
22
|
+
};
|
|
23
|
+
/** One line per ajv error: `/path message`. */
|
|
24
|
+
export const ajvErrorText = (errors) => (errors ?? []).map(error => `${error.instancePath === '' ? '/' : error.instancePath} ${error.message ?? 'invalid'}`)
|
|
25
|
+
.join('; ');
|
|
26
|
+
/** Keys holding `.` or `$` at any depth — a document store cannot hold them. */
|
|
27
|
+
export const invalidFieldKeys = (fields, path = '') => {
|
|
28
|
+
if (fields == null || typeof fields !== 'object') {
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
if (Array.isArray(fields)) {
|
|
32
|
+
return fields.flatMap((entry, index) => invalidFieldKeys(entry, `${path}${index}.`));
|
|
33
|
+
}
|
|
34
|
+
return Object.entries(fields).flatMap(([key, value]) => [
|
|
35
|
+
...(key.includes('.') || key.includes('$') ? [`${path}${key}`] : []),
|
|
36
|
+
...invalidFieldKeys(value, `${path}${key}.`),
|
|
37
|
+
]);
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Check `fields` against the type's schema, and its keys against the store rule.
|
|
41
|
+
*
|
|
42
|
+
* @throws {FieldsInvalid}
|
|
43
|
+
*/
|
|
44
|
+
export const validateFields = (registry, type, fields) => {
|
|
45
|
+
const keys = invalidFieldKeys(fields);
|
|
46
|
+
if (keys.length > 0) {
|
|
47
|
+
throw new FieldsInvalid(`keys:${keys.join(',')}`);
|
|
48
|
+
}
|
|
49
|
+
const validate = registry.validator(type);
|
|
50
|
+
if (!validate(fields)) {
|
|
51
|
+
throw new FieldsInvalid(`${type}:${ajvErrorText(validate.errors)}`);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Check a whole record: its shape by kind, then its `fields` by type.
|
|
56
|
+
*
|
|
57
|
+
* @throws {PlanningError} `malformed:card:…` for a shape fault
|
|
58
|
+
* @throws {FieldsInvalid}
|
|
59
|
+
*/
|
|
60
|
+
export const validateCard = (card, registry) => {
|
|
61
|
+
const validate = compile(card.kind === WorkcardKind.Specification
|
|
62
|
+
? SpecificationSchema
|
|
63
|
+
: card.kind === WorkcardKind.Card || card.kind === WorkcardKind.Project ? WorkcardSchema : AnyWorkcardSchema);
|
|
64
|
+
if (!validate(card)) {
|
|
65
|
+
throw new PlanningError(`malformed:card:${ajvErrorText(validate.errors)}`);
|
|
66
|
+
}
|
|
67
|
+
validateFields(registry, card.type, card.fields);
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Check a document body against its slot: a JSON slot must parse, and match the slot's schema when
|
|
71
|
+
* it declares one.
|
|
72
|
+
*
|
|
73
|
+
* @throws {FieldsInvalid}
|
|
74
|
+
*/
|
|
75
|
+
export const validateSpecificationBody = (slot, body) => {
|
|
76
|
+
if (body == null || slot.format !== SpecificationFormat.Json) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
let parsed;
|
|
80
|
+
try {
|
|
81
|
+
parsed = JSON.parse(body);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
throw new FieldsInvalid(`body:${slot.category}:not-json`);
|
|
85
|
+
}
|
|
86
|
+
if (slot.schema != null && typeof slot.schema === 'object') {
|
|
87
|
+
const validate = compile(slot.schema);
|
|
88
|
+
if (!validate(parsed)) {
|
|
89
|
+
throw new FieldsInvalid(`body:${slot.category}:${ajvErrorText(validate.errors)}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/helpers/validate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"kind": {
|
|
3
|
+
"card": "Картка",
|
|
4
|
+
"project": "Праект",
|
|
5
|
+
"specification": "Спецыфікацыя"
|
|
6
|
+
},
|
|
7
|
+
"intrinsic": {
|
|
8
|
+
"planned": "Запланавана",
|
|
9
|
+
"in-progress": "У працы",
|
|
10
|
+
"closed": "Закрыта"
|
|
11
|
+
},
|
|
12
|
+
"action": {
|
|
13
|
+
"create": "Створана",
|
|
14
|
+
"update": "Абноўлена",
|
|
15
|
+
"transit": "Статус зменены",
|
|
16
|
+
"link": "Звязана",
|
|
17
|
+
"unlink": "Сувязь выдалена",
|
|
18
|
+
"delete": "Выдалена"
|
|
19
|
+
},
|
|
20
|
+
"commit": {
|
|
21
|
+
"pending": "Захаванне…",
|
|
22
|
+
"committed": "Захавана",
|
|
23
|
+
"failed": "Не захавана"
|
|
24
|
+
},
|
|
25
|
+
"format": {
|
|
26
|
+
"markdown": "Markdown",
|
|
27
|
+
"json": "JSON",
|
|
28
|
+
"text": "Звычайны тэкст"
|
|
29
|
+
},
|
|
30
|
+
"errors": {
|
|
31
|
+
"PlanningError": "Не ўдалося выканаць запыт планавання",
|
|
32
|
+
"PlanningErrorWorkcardNotFound": "Гэты элемент не існуе або недаступны вам",
|
|
33
|
+
"PlanningErrorUnknownWorkcardType": "Гэты тып элемента невядомы",
|
|
34
|
+
"PlanningErrorUnknownStatusFlow": "Гэты паток статусаў невядомы",
|
|
35
|
+
"PlanningErrorParentNotFound": "Бацькоўскі элемент не існуе",
|
|
36
|
+
"PlanningErrorCardTypeNotAllowed": "Элемент гэтага тыпу нельга дадаць сюды",
|
|
37
|
+
"PlanningErrorRefused": "Змяненне адхілена",
|
|
38
|
+
"PlanningErrorIllegalTransition": "Такая змена статусу недапушчальная з бягучага статусу",
|
|
39
|
+
"PlanningErrorFieldsInvalid": "Некаторыя палі маюць недапушчальныя значэнні",
|
|
40
|
+
"PlanningErrorLabelNotAllowed": "Гэтая метка тут недапушчальная",
|
|
41
|
+
"PlanningErrorSpecificationSlotUnknown": "Гэты від дакумента тут недапушчальны",
|
|
42
|
+
"PlanningErrorSpecificationRevisionConflict": "Гэты дакумент ужо існуе — адрэдагуйце яго",
|
|
43
|
+
"PlanningErrorRelationshipRefused": "Гэтая сувязь недапушчальная",
|
|
44
|
+
"PlanningErrorCodeTaken": "Гэты код ужо заняты",
|
|
45
|
+
"PlanningErrorWorkcardConflict": "Хтосьці змяніў гэты элемент за гэты час — абнавіце і паспрабуйце зноў",
|
|
46
|
+
"PlanningErrorCommitTimeout": "Змяненне яшчэ захоўваецца — праверце крыху пазней",
|
|
47
|
+
"PlanningErrorCommitFailed": "Не ўдалося захаваць змяненне",
|
|
48
|
+
"PlanningErrorScopeMismatch": "Гэты элемент не існуе або недаступны вам",
|
|
49
|
+
"PlanningErrorUnsupported": "Гэтая аперацыя не падтрымліваецца для гэтага элемента"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"kind": {
|
|
3
|
+
"card": "Karte",
|
|
4
|
+
"project": "Projekt",
|
|
5
|
+
"specification": "Spezifikation"
|
|
6
|
+
},
|
|
7
|
+
"intrinsic": {
|
|
8
|
+
"planned": "Geplant",
|
|
9
|
+
"in-progress": "In Arbeit",
|
|
10
|
+
"closed": "Abgeschlossen"
|
|
11
|
+
},
|
|
12
|
+
"action": {
|
|
13
|
+
"create": "Erstellt",
|
|
14
|
+
"update": "Aktualisiert",
|
|
15
|
+
"transit": "Status geändert",
|
|
16
|
+
"link": "Verknüpft",
|
|
17
|
+
"unlink": "Verknüpfung entfernt",
|
|
18
|
+
"delete": "Gelöscht"
|
|
19
|
+
},
|
|
20
|
+
"commit": {
|
|
21
|
+
"pending": "Wird gespeichert…",
|
|
22
|
+
"committed": "Gespeichert",
|
|
23
|
+
"failed": "Nicht gespeichert"
|
|
24
|
+
},
|
|
25
|
+
"format": {
|
|
26
|
+
"markdown": "Markdown",
|
|
27
|
+
"json": "JSON",
|
|
28
|
+
"text": "Reiner Text"
|
|
29
|
+
},
|
|
30
|
+
"errors": {
|
|
31
|
+
"PlanningError": "Die Planungsanfrage konnte nicht ausgeführt werden",
|
|
32
|
+
"PlanningErrorWorkcardNotFound": "Dieses Element existiert nicht oder ist für dich nicht verfügbar",
|
|
33
|
+
"PlanningErrorUnknownWorkcardType": "Dieser Elementtyp ist unbekannt",
|
|
34
|
+
"PlanningErrorUnknownStatusFlow": "Dieser Statusablauf ist unbekannt",
|
|
35
|
+
"PlanningErrorParentNotFound": "Das übergeordnete Element existiert nicht",
|
|
36
|
+
"PlanningErrorCardTypeNotAllowed": "Ein Element dieses Typs kann hier nicht hinzugefügt werden",
|
|
37
|
+
"PlanningErrorRefused": "Die Änderung wurde abgelehnt",
|
|
38
|
+
"PlanningErrorIllegalTransition": "Dieser Statuswechsel ist vom aktuellen Status aus nicht erlaubt",
|
|
39
|
+
"PlanningErrorFieldsInvalid": "Einige Felder haben ungültige Werte",
|
|
40
|
+
"PlanningErrorLabelNotAllowed": "Dieses Label ist hier nicht erlaubt",
|
|
41
|
+
"PlanningErrorSpecificationSlotUnknown": "Diese Art von Dokument ist hier nicht erlaubt",
|
|
42
|
+
"PlanningErrorSpecificationRevisionConflict": "Dieses Dokument existiert bereits — bearbeite es stattdessen",
|
|
43
|
+
"PlanningErrorRelationshipRefused": "Diese Verknüpfung ist nicht erlaubt",
|
|
44
|
+
"PlanningErrorCodeTaken": "Dieser Code ist bereits vergeben",
|
|
45
|
+
"PlanningErrorWorkcardConflict": "Jemand hat dieses Element inzwischen geändert — neu laden und erneut versuchen",
|
|
46
|
+
"PlanningErrorCommitTimeout": "Die Änderung wird noch gespeichert — prüfe es gleich noch einmal",
|
|
47
|
+
"PlanningErrorCommitFailed": "Die Änderung konnte nicht gespeichert werden",
|
|
48
|
+
"PlanningErrorScopeMismatch": "Dieses Element existiert nicht oder ist für dich nicht verfügbar",
|
|
49
|
+
"PlanningErrorUnsupported": "Dieser Vorgang wird für dieses Element nicht unterstützt"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"kind": {
|
|
3
|
+
"card": "Card",
|
|
4
|
+
"project": "Project",
|
|
5
|
+
"specification": "Specification"
|
|
6
|
+
},
|
|
7
|
+
"intrinsic": {
|
|
8
|
+
"planned": "Planned",
|
|
9
|
+
"in-progress": "In progress",
|
|
10
|
+
"closed": "Closed"
|
|
11
|
+
},
|
|
12
|
+
"action": {
|
|
13
|
+
"create": "Created",
|
|
14
|
+
"update": "Updated",
|
|
15
|
+
"transit": "Status changed",
|
|
16
|
+
"link": "Linked",
|
|
17
|
+
"unlink": "Unlinked",
|
|
18
|
+
"delete": "Deleted"
|
|
19
|
+
},
|
|
20
|
+
"commit": {
|
|
21
|
+
"pending": "Saving…",
|
|
22
|
+
"committed": "Saved",
|
|
23
|
+
"failed": "Not saved"
|
|
24
|
+
},
|
|
25
|
+
"format": {
|
|
26
|
+
"markdown": "Markdown",
|
|
27
|
+
"json": "JSON",
|
|
28
|
+
"text": "Plain text"
|
|
29
|
+
},
|
|
30
|
+
"errors": {
|
|
31
|
+
"PlanningError": "The planning request could not be completed",
|
|
32
|
+
"PlanningErrorWorkcardNotFound": "This item does not exist or is not available to you",
|
|
33
|
+
"PlanningErrorUnknownWorkcardType": "This item type is not known",
|
|
34
|
+
"PlanningErrorUnknownStatusFlow": "This status flow is not known",
|
|
35
|
+
"PlanningErrorParentNotFound": "The parent item does not exist",
|
|
36
|
+
"PlanningErrorCardTypeNotAllowed": "This item type cannot be added here",
|
|
37
|
+
"PlanningErrorRefused": "The change was refused",
|
|
38
|
+
"PlanningErrorIllegalTransition": "This status change is not allowed from the current status",
|
|
39
|
+
"PlanningErrorFieldsInvalid": "Some fields have invalid values",
|
|
40
|
+
"PlanningErrorLabelNotAllowed": "This label is not allowed here",
|
|
41
|
+
"PlanningErrorSpecificationSlotUnknown": "This kind of document is not allowed here",
|
|
42
|
+
"PlanningErrorSpecificationRevisionConflict": "This document already exists — edit it instead",
|
|
43
|
+
"PlanningErrorRelationshipRefused": "This link is not allowed",
|
|
44
|
+
"PlanningErrorCodeTaken": "This code is already taken",
|
|
45
|
+
"PlanningErrorWorkcardConflict": "Someone changed this item in the meantime — reload and try again",
|
|
46
|
+
"PlanningErrorCommitTimeout": "The change is still being saved — check again shortly",
|
|
47
|
+
"PlanningErrorCommitFailed": "The change could not be saved",
|
|
48
|
+
"PlanningErrorScopeMismatch": "This item does not exist or is not available to you",
|
|
49
|
+
"PlanningErrorUnsupported": "This operation is not supported for this item"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"kind": {
|
|
3
|
+
"card": "Tarjeta",
|
|
4
|
+
"project": "Proyecto",
|
|
5
|
+
"specification": "Especificación"
|
|
6
|
+
},
|
|
7
|
+
"intrinsic": {
|
|
8
|
+
"planned": "Planificado",
|
|
9
|
+
"in-progress": "En curso",
|
|
10
|
+
"closed": "Cerrado"
|
|
11
|
+
},
|
|
12
|
+
"action": {
|
|
13
|
+
"create": "Creado",
|
|
14
|
+
"update": "Actualizado",
|
|
15
|
+
"transit": "Estado cambiado",
|
|
16
|
+
"link": "Vinculado",
|
|
17
|
+
"unlink": "Vínculo eliminado",
|
|
18
|
+
"delete": "Eliminado"
|
|
19
|
+
},
|
|
20
|
+
"commit": {
|
|
21
|
+
"pending": "Guardando…",
|
|
22
|
+
"committed": "Guardado",
|
|
23
|
+
"failed": "No guardado"
|
|
24
|
+
},
|
|
25
|
+
"format": {
|
|
26
|
+
"markdown": "Markdown",
|
|
27
|
+
"json": "JSON",
|
|
28
|
+
"text": "Texto sin formato"
|
|
29
|
+
},
|
|
30
|
+
"errors": {
|
|
31
|
+
"PlanningError": "No se pudo completar la solicitud de planificación",
|
|
32
|
+
"PlanningErrorWorkcardNotFound": "Este elemento no existe o no está disponible para ti",
|
|
33
|
+
"PlanningErrorUnknownWorkcardType": "Este tipo de elemento no se conoce",
|
|
34
|
+
"PlanningErrorUnknownStatusFlow": "Este flujo de estados no se conoce",
|
|
35
|
+
"PlanningErrorParentNotFound": "El elemento superior no existe",
|
|
36
|
+
"PlanningErrorCardTypeNotAllowed": "No se puede añadir aquí un elemento de este tipo",
|
|
37
|
+
"PlanningErrorRefused": "El cambio fue rechazado",
|
|
38
|
+
"PlanningErrorIllegalTransition": "Este cambio de estado no está permitido desde el estado actual",
|
|
39
|
+
"PlanningErrorFieldsInvalid": "Algunos campos tienen valores no válidos",
|
|
40
|
+
"PlanningErrorLabelNotAllowed": "Esta etiqueta no está permitida aquí",
|
|
41
|
+
"PlanningErrorSpecificationSlotUnknown": "Este tipo de documento no está permitido aquí",
|
|
42
|
+
"PlanningErrorSpecificationRevisionConflict": "Este documento ya existe — edítalo en su lugar",
|
|
43
|
+
"PlanningErrorRelationshipRefused": "Este vínculo no está permitido",
|
|
44
|
+
"PlanningErrorCodeTaken": "Este código ya está en uso",
|
|
45
|
+
"PlanningErrorWorkcardConflict": "Alguien cambió este elemento mientras tanto — recarga e inténtalo de nuevo",
|
|
46
|
+
"PlanningErrorCommitTimeout": "El cambio aún se está guardando — vuelve a comprobarlo en breve",
|
|
47
|
+
"PlanningErrorCommitFailed": "No se pudo guardar el cambio",
|
|
48
|
+
"PlanningErrorScopeMismatch": "Este elemento no existe o no está disponible para ti",
|
|
49
|
+
"PlanningErrorUnsupported": "Esta operación no es compatible con este elemento"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"kind": {
|
|
3
|
+
"card": "Karta",
|
|
4
|
+
"project": "Projekt",
|
|
5
|
+
"specification": "Specyfikacja"
|
|
6
|
+
},
|
|
7
|
+
"intrinsic": {
|
|
8
|
+
"planned": "Zaplanowane",
|
|
9
|
+
"in-progress": "W toku",
|
|
10
|
+
"closed": "Zamknięte"
|
|
11
|
+
},
|
|
12
|
+
"action": {
|
|
13
|
+
"create": "Utworzono",
|
|
14
|
+
"update": "Zaktualizowano",
|
|
15
|
+
"transit": "Zmieniono status",
|
|
16
|
+
"link": "Powiązano",
|
|
17
|
+
"unlink": "Usunięto powiązanie",
|
|
18
|
+
"delete": "Usunięto"
|
|
19
|
+
},
|
|
20
|
+
"commit": {
|
|
21
|
+
"pending": "Zapisywanie…",
|
|
22
|
+
"committed": "Zapisano",
|
|
23
|
+
"failed": "Nie zapisano"
|
|
24
|
+
},
|
|
25
|
+
"format": {
|
|
26
|
+
"markdown": "Markdown",
|
|
27
|
+
"json": "JSON",
|
|
28
|
+
"text": "Zwykły tekst"
|
|
29
|
+
},
|
|
30
|
+
"errors": {
|
|
31
|
+
"PlanningError": "Nie udało się wykonać żądania planowania",
|
|
32
|
+
"PlanningErrorWorkcardNotFound": "Ten element nie istnieje lub nie jest dla Ciebie dostępny",
|
|
33
|
+
"PlanningErrorUnknownWorkcardType": "Ten typ elementu jest nieznany",
|
|
34
|
+
"PlanningErrorUnknownStatusFlow": "Ten przepływ statusów jest nieznany",
|
|
35
|
+
"PlanningErrorParentNotFound": "Element nadrzędny nie istnieje",
|
|
36
|
+
"PlanningErrorCardTypeNotAllowed": "Nie można tutaj dodać elementu tego typu",
|
|
37
|
+
"PlanningErrorRefused": "Zmiana została odrzucona",
|
|
38
|
+
"PlanningErrorIllegalTransition": "Ta zmiana statusu jest niedozwolona z bieżącego statusu",
|
|
39
|
+
"PlanningErrorFieldsInvalid": "Niektóre pola mają nieprawidłowe wartości",
|
|
40
|
+
"PlanningErrorLabelNotAllowed": "Ta etykieta jest tutaj niedozwolona",
|
|
41
|
+
"PlanningErrorSpecificationSlotUnknown": "Ten rodzaj dokumentu jest tutaj niedozwolony",
|
|
42
|
+
"PlanningErrorSpecificationRevisionConflict": "Ten dokument już istnieje — edytuj go",
|
|
43
|
+
"PlanningErrorRelationshipRefused": "To powiązanie jest niedozwolone",
|
|
44
|
+
"PlanningErrorCodeTaken": "Ten kod jest już zajęty",
|
|
45
|
+
"PlanningErrorWorkcardConflict": "Ktoś w międzyczasie zmienił ten element — odśwież i spróbuj ponownie",
|
|
46
|
+
"PlanningErrorCommitTimeout": "Zmiana jest nadal zapisywana — sprawdź ponownie za chwilę",
|
|
47
|
+
"PlanningErrorCommitFailed": "Nie udało się zapisać zmiany",
|
|
48
|
+
"PlanningErrorScopeMismatch": "Ten element nie istnieje lub nie jest dla Ciebie dostępny",
|
|
49
|
+
"PlanningErrorUnsupported": "Ta operacja nie jest obsługiwana dla tego elementu"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"kind": {
|
|
3
|
+
"card": "Карточка",
|
|
4
|
+
"project": "Проект",
|
|
5
|
+
"specification": "Спецификация"
|
|
6
|
+
},
|
|
7
|
+
"intrinsic": {
|
|
8
|
+
"planned": "Запланировано",
|
|
9
|
+
"in-progress": "В работе",
|
|
10
|
+
"closed": "Закрыто"
|
|
11
|
+
},
|
|
12
|
+
"action": {
|
|
13
|
+
"create": "Создано",
|
|
14
|
+
"update": "Обновлено",
|
|
15
|
+
"transit": "Статус изменён",
|
|
16
|
+
"link": "Связано",
|
|
17
|
+
"unlink": "Связь удалена",
|
|
18
|
+
"delete": "Удалено"
|
|
19
|
+
},
|
|
20
|
+
"commit": {
|
|
21
|
+
"pending": "Сохранение…",
|
|
22
|
+
"committed": "Сохранено",
|
|
23
|
+
"failed": "Не сохранено"
|
|
24
|
+
},
|
|
25
|
+
"format": {
|
|
26
|
+
"markdown": "Markdown",
|
|
27
|
+
"json": "JSON",
|
|
28
|
+
"text": "Обычный текст"
|
|
29
|
+
},
|
|
30
|
+
"errors": {
|
|
31
|
+
"PlanningError": "Не удалось выполнить запрос планирования",
|
|
32
|
+
"PlanningErrorWorkcardNotFound": "Этот элемент не существует или недоступен вам",
|
|
33
|
+
"PlanningErrorUnknownWorkcardType": "Этот тип элемента неизвестен",
|
|
34
|
+
"PlanningErrorUnknownStatusFlow": "Этот поток статусов неизвестен",
|
|
35
|
+
"PlanningErrorParentNotFound": "Родительский элемент не существует",
|
|
36
|
+
"PlanningErrorCardTypeNotAllowed": "Элемент этого типа нельзя добавить сюда",
|
|
37
|
+
"PlanningErrorRefused": "Изменение отклонено",
|
|
38
|
+
"PlanningErrorIllegalTransition": "Такая смена статуса недопустима из текущего статуса",
|
|
39
|
+
"PlanningErrorFieldsInvalid": "Некоторые поля содержат недопустимые значения",
|
|
40
|
+
"PlanningErrorLabelNotAllowed": "Эта метка здесь недопустима",
|
|
41
|
+
"PlanningErrorSpecificationSlotUnknown": "Этот вид документа здесь недопустим",
|
|
42
|
+
"PlanningErrorSpecificationRevisionConflict": "Этот документ уже существует — отредактируйте его",
|
|
43
|
+
"PlanningErrorRelationshipRefused": "Эта связь недопустима",
|
|
44
|
+
"PlanningErrorCodeTaken": "Этот код уже занят",
|
|
45
|
+
"PlanningErrorWorkcardConflict": "Кто-то изменил этот элемент за это время — обновите и попробуйте снова",
|
|
46
|
+
"PlanningErrorCommitTimeout": "Изменение ещё сохраняется — проверьте чуть позже",
|
|
47
|
+
"PlanningErrorCommitFailed": "Не удалось сохранить изменение",
|
|
48
|
+
"PlanningErrorScopeMismatch": "Этот элемент не существует или недоступен вам",
|
|
49
|
+
"PlanningErrorUnsupported": "Эта операция не поддерживается для этого элемента"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"kind": {
|
|
3
|
+
"card": "Картка",
|
|
4
|
+
"project": "Проєкт",
|
|
5
|
+
"specification": "Специфікація"
|
|
6
|
+
},
|
|
7
|
+
"intrinsic": {
|
|
8
|
+
"planned": "Заплановано",
|
|
9
|
+
"in-progress": "У роботі",
|
|
10
|
+
"closed": "Закрито"
|
|
11
|
+
},
|
|
12
|
+
"action": {
|
|
13
|
+
"create": "Створено",
|
|
14
|
+
"update": "Оновлено",
|
|
15
|
+
"transit": "Статус змінено",
|
|
16
|
+
"link": "Пов’язано",
|
|
17
|
+
"unlink": "Зв’язок видалено",
|
|
18
|
+
"delete": "Видалено"
|
|
19
|
+
},
|
|
20
|
+
"commit": {
|
|
21
|
+
"pending": "Збереження…",
|
|
22
|
+
"committed": "Збережено",
|
|
23
|
+
"failed": "Не збережено"
|
|
24
|
+
},
|
|
25
|
+
"format": {
|
|
26
|
+
"markdown": "Markdown",
|
|
27
|
+
"json": "JSON",
|
|
28
|
+
"text": "Звичайний текст"
|
|
29
|
+
},
|
|
30
|
+
"errors": {
|
|
31
|
+
"PlanningError": "Не вдалося виконати запит планування",
|
|
32
|
+
"PlanningErrorWorkcardNotFound": "Цей елемент не існує або недоступний вам",
|
|
33
|
+
"PlanningErrorUnknownWorkcardType": "Цей тип елемента невідомий",
|
|
34
|
+
"PlanningErrorUnknownStatusFlow": "Цей потік статусів невідомий",
|
|
35
|
+
"PlanningErrorParentNotFound": "Батьківський елемент не існує",
|
|
36
|
+
"PlanningErrorCardTypeNotAllowed": "Елемент цього типу не можна додати сюди",
|
|
37
|
+
"PlanningErrorRefused": "Зміну відхилено",
|
|
38
|
+
"PlanningErrorIllegalTransition": "Така зміна статусу неприпустима з поточного статусу",
|
|
39
|
+
"PlanningErrorFieldsInvalid": "Деякі поля мають неприпустимі значення",
|
|
40
|
+
"PlanningErrorLabelNotAllowed": "Ця мітка тут неприпустима",
|
|
41
|
+
"PlanningErrorSpecificationSlotUnknown": "Цей вид документа тут неприпустимий",
|
|
42
|
+
"PlanningErrorSpecificationRevisionConflict": "Цей документ уже існує — відредагуйте його",
|
|
43
|
+
"PlanningErrorRelationshipRefused": "Цей зв’язок неприпустимий",
|
|
44
|
+
"PlanningErrorCodeTaken": "Цей код уже зайнятий",
|
|
45
|
+
"PlanningErrorWorkcardConflict": "Хтось змінив цей елемент тим часом — оновіть і спробуйте знову",
|
|
46
|
+
"PlanningErrorCommitTimeout": "Зміна ще зберігається — перевірте трохи пізніше",
|
|
47
|
+
"PlanningErrorCommitFailed": "Не вдалося зберегти зміну",
|
|
48
|
+
"PlanningErrorScopeMismatch": "Цей елемент не існує або недоступний вам",
|
|
49
|
+
"PlanningErrorUnsupported": "Ця операція не підтримується для цього елемента"
|
|
50
|
+
}
|
|
51
|
+
}
|
package/build/i18n.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":""}
|
package/build/i18n.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { addI18nLib } from '@owlmeans/i18n';
|
|
2
|
+
import { PLANNING_I18N } from './consts.js';
|
|
3
|
+
import en from './i18n/en.json' with { type: 'json' };
|
|
4
|
+
import pl from './i18n/pl.json' with { type: 'json' };
|
|
5
|
+
import ru from './i18n/ru.json' with { type: 'json' };
|
|
6
|
+
import be from './i18n/be.json' with { type: 'json' };
|
|
7
|
+
import uk from './i18n/uk.json' with { type: 'json' };
|
|
8
|
+
import es from './i18n/es.json' with { type: 'json' };
|
|
9
|
+
import de from './i18n/de.json' with { type: 'json' };
|
|
10
|
+
/**
|
|
11
|
+
* Labels under `lib:planning.*`, and every refusal under the shared `errors` resource keyed by its
|
|
12
|
+
* type name — which is where a panel's error lookup (`errors.<type>`) finds them.
|
|
13
|
+
*/
|
|
14
|
+
const LANGUAGES = { en, pl, ru, be, uk, es, de };
|
|
15
|
+
Object.entries(LANGUAGES).forEach(([lng, data]) => {
|
|
16
|
+
addI18nLib(lng, PLANNING_I18N, data);
|
|
17
|
+
addI18nLib(lng, 'errors', data.errors);
|
|
18
|
+
});
|
|
19
|
+
//# sourceMappingURL=i18n.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18n.js","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AACrD,OAAO,EAAE,MAAM,gBAAgB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AAErD;;;GAGG;AACH,MAAM,SAAS,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAA;AAEhD,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE;IAChD,UAAU,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,CAAC,CAAA;IACpC,UAAU,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;AACxC,CAAC,CAAC,CAAA"}
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type * from './types.js';
|
|
2
|
+
export * from './consts.js';
|
|
3
|
+
export * from './schemas.js';
|
|
4
|
+
export * from './errors.js';
|
|
5
|
+
export * from './entrypoints.js';
|
|
6
|
+
export * from './registry.js';
|
|
7
|
+
export * from './helpers/index.js';
|
|
8
|
+
export * from './models/index.js';
|
|
9
|
+
export * from './i18n.js';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,YAAY,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,eAAe,CAAA;AAC7B,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,WAAW,CAAA"}
|