@patterkit/model 0.3.0 → 0.4.1
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/dist/index.cjs +5 -20
- package/dist/index.d.cts +11 -17
- package/dist/index.d.ts +11 -17
- package/dist/index.js +6 -16
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -29,19 +29,20 @@ __export(index_exports, {
|
|
|
29
29
|
PROJECT_LOCALE_SCENE: () => PROJECT_LOCALE_SCENE,
|
|
30
30
|
RERECORD_STATUS: () => RERECORD_STATUS,
|
|
31
31
|
RERECORD_STATUS_DECL: () => RERECORD_STATUS_DECL,
|
|
32
|
-
RESERVED_PROPERTY_NAMES: () => RESERVED_PROPERTY_NAMES,
|
|
32
|
+
RESERVED_PROPERTY_NAMES: () => import_expr.RESERVED_PROPERTY_NAMES,
|
|
33
33
|
castStringKey: () => castStringKey,
|
|
34
34
|
deriveRecordingFolders: () => deriveRecordingFolders,
|
|
35
35
|
effectiveGameId: () => effectiveGameId,
|
|
36
36
|
gameIdify: () => gameIdify,
|
|
37
|
-
isCaseOnlyPropertyName: () => isCaseOnlyPropertyName,
|
|
37
|
+
isCaseOnlyPropertyName: () => import_expr.isCaseOnlyPropertyName,
|
|
38
38
|
isContentlessBeat: () => isContentlessBeat,
|
|
39
39
|
isValidGameId: () => isValidGameId,
|
|
40
|
-
isValidPropertyName: () => isValidPropertyName,
|
|
41
|
-
propertyNameify: () => propertyNameify,
|
|
40
|
+
isValidPropertyName: () => import_expr.isValidPropertyName,
|
|
41
|
+
propertyNameify: () => import_expr.propertyNameify,
|
|
42
42
|
walkNodes: () => walkNodes
|
|
43
43
|
});
|
|
44
44
|
module.exports = __toCommonJS(index_exports);
|
|
45
|
+
var import_expr = require("@wildwinter/expr");
|
|
45
46
|
function walkNodes(nodes, visit) {
|
|
46
47
|
for (const node of nodes) {
|
|
47
48
|
visit(node);
|
|
@@ -62,22 +63,6 @@ function gameIdify(text) {
|
|
|
62
63
|
function isValidGameId(gameId) {
|
|
63
64
|
return /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(gameId);
|
|
64
65
|
}
|
|
65
|
-
var RESERVED_PROPERTY_NAMES = ["true", "false", "and", "or", "not"];
|
|
66
|
-
function propertyNameify(text) {
|
|
67
|
-
const trimmed = text.trim();
|
|
68
|
-
const deliberateLeading = trimmed.startsWith("_");
|
|
69
|
-
let out = trimmed.toLowerCase().replace(/['\u2019]/g, "").replace(/[^a-z0-9_]+/g, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "");
|
|
70
|
-
if (out === "") return "";
|
|
71
|
-
if (deliberateLeading || /^[0-9]/.test(out)) out = `_${out}`;
|
|
72
|
-
if (RESERVED_PROPERTY_NAMES.includes(out)) out = `${out}_`;
|
|
73
|
-
return out;
|
|
74
|
-
}
|
|
75
|
-
function isValidPropertyName(name) {
|
|
76
|
-
return /^[a-z_][a-z0-9_]*$/.test(name) && !RESERVED_PROPERTY_NAMES.includes(name);
|
|
77
|
-
}
|
|
78
|
-
function isCaseOnlyPropertyName(name) {
|
|
79
|
-
return !isValidPropertyName(name) && isValidPropertyName(name.toLowerCase());
|
|
80
|
-
}
|
|
81
66
|
function effectiveGameId(entity) {
|
|
82
67
|
const g = entity.gameId?.trim();
|
|
83
68
|
return g ? g : gameIdify(entity.name);
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AstNode } from '@wildwinter/expr';
|
|
2
|
+
export { RESERVED_PROPERTY_NAMES, isCaseOnlyPropertyName, isValidPropertyName, propertyNameify } from '@wildwinter/expr';
|
|
2
3
|
|
|
3
4
|
type ScalarValue = boolean | number | string | string[];
|
|
4
5
|
/** Developer-defined host metadata (spec §17). Opaque to Patter. */
|
|
@@ -207,27 +208,13 @@ declare function isContentlessBeat(beat: Beat, hasText: boolean): boolean;
|
|
|
207
208
|
declare function gameIdify(text: string): string;
|
|
208
209
|
/** A valid authored game id: lowercase alphanumerics + hyphens, no leading / trailing hyphen. */
|
|
209
210
|
declare function isValidGameId(gameId: string): boolean;
|
|
210
|
-
|
|
211
|
-
* `packages/model/test/property-name-grammar.test.ts` probes the real parser rather
|
|
212
|
-
* than trusting this copy. */
|
|
213
|
-
declare const RESERVED_PROPERTY_NAMES: readonly string[];
|
|
214
|
-
/** Coerce a label into a legal property name: lower case, apostrophes dropped, runs of
|
|
215
|
-
* anything else to a single underscore, no trailing underscore, an underscore in front
|
|
216
|
-
* of a leading digit, one behind a keyword. "" when nothing usable was left. */
|
|
217
|
-
declare function propertyNameify(text: string): string;
|
|
218
|
-
/** Is this a name an expression can actually reach? Lower case letters, digits and
|
|
219
|
-
* underscores, not starting with a digit, not a keyword. "" is not a name. */
|
|
220
|
-
declare function isValidPropertyName(name: string): boolean;
|
|
221
|
-
/** True when folding case ALONE would make it legal (`isNight`). The only violation a
|
|
222
|
-
* loader may repair without guessing at intent: every reference is folded already, so
|
|
223
|
-
* folding the declaration to match changes nothing observable. */
|
|
224
|
-
declare function isCaseOnlyPropertyName(name: string): boolean;
|
|
211
|
+
|
|
225
212
|
/** The effective address: the explicit `gameId` if pinned, else derived from `name`. */
|
|
226
213
|
declare function effectiveGameId(entity: {
|
|
227
214
|
gameId?: string;
|
|
228
215
|
name: string;
|
|
229
216
|
}): string;
|
|
230
|
-
type PropertyType = "boolean" | "number" | "string" | "flags" | "enum";
|
|
217
|
+
type PropertyType = "boolean" | "number" | "string" | "flags" | "enum" | "quality";
|
|
231
218
|
interface PropertyDecl {
|
|
232
219
|
name: string;
|
|
233
220
|
type: PropertyType;
|
|
@@ -251,6 +238,11 @@ interface PropertyDecl {
|
|
|
251
238
|
temporary?: boolean;
|
|
252
239
|
/** For enum / flags. */
|
|
253
240
|
values?: string[];
|
|
241
|
+
/** For quality: the ORDERED ladder of stage names (the shared engine's quality type, expr 0.4.0).
|
|
242
|
+
* Ordering operators compare by position in this list and `advance()` steps along it, so the order
|
|
243
|
+
* is the meaning - unlike `values`, whose order is presentation only. Default seeds to the first
|
|
244
|
+
* stage when no `default` is declared. */
|
|
245
|
+
stages?: string[];
|
|
254
246
|
/** Free-text author note documenting what this property is for (authoring only; shown as a hint). */
|
|
255
247
|
purpose?: string;
|
|
256
248
|
}
|
|
@@ -265,6 +257,8 @@ interface HostScopeDecl {
|
|
|
265
257
|
name: string;
|
|
266
258
|
type: PropertyType;
|
|
267
259
|
values?: string[];
|
|
260
|
+
/** For quality: the ordered stage ladder (see `PropertyDecl.stages`). */
|
|
261
|
+
stages?: string[];
|
|
268
262
|
default?: ScalarValue;
|
|
269
263
|
writable?: boolean;
|
|
270
264
|
/** Free-text author note documenting the property (authoring only; shown as a hint). */
|
|
@@ -852,4 +846,4 @@ declare const DEFAULT_CAPTION_DELIMITERS: CaptionDelimiters;
|
|
|
852
846
|
* captions are off). Applies even to a project that pins no `closedCaptions`. */
|
|
853
847
|
declare const DEFAULT_CAPTION_CHARACTER = "SFX";
|
|
854
848
|
|
|
855
|
-
export { type AuthoringFile, type Beat, type Block, type Bundle, type BundleCastMember, COMMON_GENDERS, type CaptionDelimiters, type CastMember, type Comment, type CommentMessage, type CommentRange, type CompiledBlock, type CompiledEffect, type CompiledGroup, type CompiledScene, type CompiledSnippet, type CoverageDriver, DEFAULT_CAPTION_CHARACTER, DEFAULT_CAPTION_DELIMITERS, DEFAULT_DOCUMENTATION_CLASSES, DEFAULT_RECORDING_STATUSES, DEFAULT_WRITING_STATUSES, type DocLine, type DocumentationClass, type EditRecord, type Effect, type EstimatingConfig, type Expression, type FlowFile, type FlowNode, type GameData, type GameDataField, type GameDataFieldType, type GameDataFields, type GameDataNodeKind, type GameEventBeat, type GrammaticalGender, type Group, type HostScopeDecl, type HostScopeRegistry, type HostScopeSpec, type Jump, type JumpTarget, type LineBeat, type LocaleFile, PROJECT_LOCALE_SCENE, type ProjectDictionary, type ProjectFile, type PromptBeat, type PropertyDecl, type PropertyType, RERECORD_STATUS, RERECORD_STATUS_DECL,
|
|
849
|
+
export { type AuthoringFile, type Beat, type Block, type Bundle, type BundleCastMember, COMMON_GENDERS, type CaptionDelimiters, type CastMember, type Comment, type CommentMessage, type CommentRange, type CompiledBlock, type CompiledEffect, type CompiledGroup, type CompiledScene, type CompiledSnippet, type CoverageDriver, DEFAULT_CAPTION_CHARACTER, DEFAULT_CAPTION_DELIMITERS, DEFAULT_DOCUMENTATION_CLASSES, DEFAULT_RECORDING_STATUSES, DEFAULT_WRITING_STATUSES, type DocLine, type DocumentationClass, type EditRecord, type Effect, type EstimatingConfig, type Expression, type FlowFile, type FlowNode, type GameData, type GameDataField, type GameDataFieldType, type GameDataFields, type GameDataNodeKind, type GameEventBeat, type GrammaticalGender, type Group, type HostScopeDecl, type HostScopeRegistry, type HostScopeSpec, type Jump, type JumpTarget, type LineBeat, type LocaleFile, PROJECT_LOCALE_SCENE, type ProjectDictionary, type ProjectFile, type PromptBeat, type PropertyDecl, type PropertyType, RERECORD_STATUS, RERECORD_STATUS_DECL, type RecordingFolder, type RecordingStatusDecl, type ScalarValue, type Scene, type Selector, type SelectorExhaust, type SelectorOrder, type SequenceOptions, type Snippet, type Suggestion, type TextBeat, type VcsKind, type WritingStatusDecl, castStringKey, deriveRecordingFolders, effectiveGameId, gameIdify, isContentlessBeat, isValidGameId, walkNodes };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AstNode } from '@wildwinter/expr';
|
|
2
|
+
export { RESERVED_PROPERTY_NAMES, isCaseOnlyPropertyName, isValidPropertyName, propertyNameify } from '@wildwinter/expr';
|
|
2
3
|
|
|
3
4
|
type ScalarValue = boolean | number | string | string[];
|
|
4
5
|
/** Developer-defined host metadata (spec §17). Opaque to Patter. */
|
|
@@ -207,27 +208,13 @@ declare function isContentlessBeat(beat: Beat, hasText: boolean): boolean;
|
|
|
207
208
|
declare function gameIdify(text: string): string;
|
|
208
209
|
/** A valid authored game id: lowercase alphanumerics + hyphens, no leading / trailing hyphen. */
|
|
209
210
|
declare function isValidGameId(gameId: string): boolean;
|
|
210
|
-
|
|
211
|
-
* `packages/model/test/property-name-grammar.test.ts` probes the real parser rather
|
|
212
|
-
* than trusting this copy. */
|
|
213
|
-
declare const RESERVED_PROPERTY_NAMES: readonly string[];
|
|
214
|
-
/** Coerce a label into a legal property name: lower case, apostrophes dropped, runs of
|
|
215
|
-
* anything else to a single underscore, no trailing underscore, an underscore in front
|
|
216
|
-
* of a leading digit, one behind a keyword. "" when nothing usable was left. */
|
|
217
|
-
declare function propertyNameify(text: string): string;
|
|
218
|
-
/** Is this a name an expression can actually reach? Lower case letters, digits and
|
|
219
|
-
* underscores, not starting with a digit, not a keyword. "" is not a name. */
|
|
220
|
-
declare function isValidPropertyName(name: string): boolean;
|
|
221
|
-
/** True when folding case ALONE would make it legal (`isNight`). The only violation a
|
|
222
|
-
* loader may repair without guessing at intent: every reference is folded already, so
|
|
223
|
-
* folding the declaration to match changes nothing observable. */
|
|
224
|
-
declare function isCaseOnlyPropertyName(name: string): boolean;
|
|
211
|
+
|
|
225
212
|
/** The effective address: the explicit `gameId` if pinned, else derived from `name`. */
|
|
226
213
|
declare function effectiveGameId(entity: {
|
|
227
214
|
gameId?: string;
|
|
228
215
|
name: string;
|
|
229
216
|
}): string;
|
|
230
|
-
type PropertyType = "boolean" | "number" | "string" | "flags" | "enum";
|
|
217
|
+
type PropertyType = "boolean" | "number" | "string" | "flags" | "enum" | "quality";
|
|
231
218
|
interface PropertyDecl {
|
|
232
219
|
name: string;
|
|
233
220
|
type: PropertyType;
|
|
@@ -251,6 +238,11 @@ interface PropertyDecl {
|
|
|
251
238
|
temporary?: boolean;
|
|
252
239
|
/** For enum / flags. */
|
|
253
240
|
values?: string[];
|
|
241
|
+
/** For quality: the ORDERED ladder of stage names (the shared engine's quality type, expr 0.4.0).
|
|
242
|
+
* Ordering operators compare by position in this list and `advance()` steps along it, so the order
|
|
243
|
+
* is the meaning - unlike `values`, whose order is presentation only. Default seeds to the first
|
|
244
|
+
* stage when no `default` is declared. */
|
|
245
|
+
stages?: string[];
|
|
254
246
|
/** Free-text author note documenting what this property is for (authoring only; shown as a hint). */
|
|
255
247
|
purpose?: string;
|
|
256
248
|
}
|
|
@@ -265,6 +257,8 @@ interface HostScopeDecl {
|
|
|
265
257
|
name: string;
|
|
266
258
|
type: PropertyType;
|
|
267
259
|
values?: string[];
|
|
260
|
+
/** For quality: the ordered stage ladder (see `PropertyDecl.stages`). */
|
|
261
|
+
stages?: string[];
|
|
268
262
|
default?: ScalarValue;
|
|
269
263
|
writable?: boolean;
|
|
270
264
|
/** Free-text author note documenting the property (authoring only; shown as a hint). */
|
|
@@ -852,4 +846,4 @@ declare const DEFAULT_CAPTION_DELIMITERS: CaptionDelimiters;
|
|
|
852
846
|
* captions are off). Applies even to a project that pins no `closedCaptions`. */
|
|
853
847
|
declare const DEFAULT_CAPTION_CHARACTER = "SFX";
|
|
854
848
|
|
|
855
|
-
export { type AuthoringFile, type Beat, type Block, type Bundle, type BundleCastMember, COMMON_GENDERS, type CaptionDelimiters, type CastMember, type Comment, type CommentMessage, type CommentRange, type CompiledBlock, type CompiledEffect, type CompiledGroup, type CompiledScene, type CompiledSnippet, type CoverageDriver, DEFAULT_CAPTION_CHARACTER, DEFAULT_CAPTION_DELIMITERS, DEFAULT_DOCUMENTATION_CLASSES, DEFAULT_RECORDING_STATUSES, DEFAULT_WRITING_STATUSES, type DocLine, type DocumentationClass, type EditRecord, type Effect, type EstimatingConfig, type Expression, type FlowFile, type FlowNode, type GameData, type GameDataField, type GameDataFieldType, type GameDataFields, type GameDataNodeKind, type GameEventBeat, type GrammaticalGender, type Group, type HostScopeDecl, type HostScopeRegistry, type HostScopeSpec, type Jump, type JumpTarget, type LineBeat, type LocaleFile, PROJECT_LOCALE_SCENE, type ProjectDictionary, type ProjectFile, type PromptBeat, type PropertyDecl, type PropertyType, RERECORD_STATUS, RERECORD_STATUS_DECL,
|
|
849
|
+
export { type AuthoringFile, type Beat, type Block, type Bundle, type BundleCastMember, COMMON_GENDERS, type CaptionDelimiters, type CastMember, type Comment, type CommentMessage, type CommentRange, type CompiledBlock, type CompiledEffect, type CompiledGroup, type CompiledScene, type CompiledSnippet, type CoverageDriver, DEFAULT_CAPTION_CHARACTER, DEFAULT_CAPTION_DELIMITERS, DEFAULT_DOCUMENTATION_CLASSES, DEFAULT_RECORDING_STATUSES, DEFAULT_WRITING_STATUSES, type DocLine, type DocumentationClass, type EditRecord, type Effect, type EstimatingConfig, type Expression, type FlowFile, type FlowNode, type GameData, type GameDataField, type GameDataFieldType, type GameDataFields, type GameDataNodeKind, type GameEventBeat, type GrammaticalGender, type Group, type HostScopeDecl, type HostScopeRegistry, type HostScopeSpec, type Jump, type JumpTarget, type LineBeat, type LocaleFile, PROJECT_LOCALE_SCENE, type ProjectDictionary, type ProjectFile, type PromptBeat, type PropertyDecl, type PropertyType, RERECORD_STATUS, RERECORD_STATUS_DECL, type RecordingFolder, type RecordingStatusDecl, type ScalarValue, type Scene, type Selector, type SelectorExhaust, type SelectorOrder, type SequenceOptions, type Snippet, type Suggestion, type TextBeat, type VcsKind, type WritingStatusDecl, castStringKey, deriveRecordingFolders, effectiveGameId, gameIdify, isContentlessBeat, isValidGameId, walkNodes };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
+
import {
|
|
3
|
+
propertyNameify,
|
|
4
|
+
isValidPropertyName,
|
|
5
|
+
isCaseOnlyPropertyName,
|
|
6
|
+
RESERVED_PROPERTY_NAMES
|
|
7
|
+
} from "@wildwinter/expr";
|
|
2
8
|
function walkNodes(nodes, visit) {
|
|
3
9
|
for (const node of nodes) {
|
|
4
10
|
visit(node);
|
|
@@ -19,22 +25,6 @@ function gameIdify(text) {
|
|
|
19
25
|
function isValidGameId(gameId) {
|
|
20
26
|
return /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(gameId);
|
|
21
27
|
}
|
|
22
|
-
var RESERVED_PROPERTY_NAMES = ["true", "false", "and", "or", "not"];
|
|
23
|
-
function propertyNameify(text) {
|
|
24
|
-
const trimmed = text.trim();
|
|
25
|
-
const deliberateLeading = trimmed.startsWith("_");
|
|
26
|
-
let out = trimmed.toLowerCase().replace(/['\u2019]/g, "").replace(/[^a-z0-9_]+/g, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "");
|
|
27
|
-
if (out === "") return "";
|
|
28
|
-
if (deliberateLeading || /^[0-9]/.test(out)) out = `_${out}`;
|
|
29
|
-
if (RESERVED_PROPERTY_NAMES.includes(out)) out = `${out}_`;
|
|
30
|
-
return out;
|
|
31
|
-
}
|
|
32
|
-
function isValidPropertyName(name) {
|
|
33
|
-
return /^[a-z_][a-z0-9_]*$/.test(name) && !RESERVED_PROPERTY_NAMES.includes(name);
|
|
34
|
-
}
|
|
35
|
-
function isCaseOnlyPropertyName(name) {
|
|
36
|
-
return !isValidPropertyName(name) && isValidPropertyName(name.toLowerCase());
|
|
37
|
-
}
|
|
38
28
|
function effectiveGameId(entity) {
|
|
39
29
|
const g = entity.gameId?.trim();
|
|
40
30
|
return g ? g : gameIdify(entity.name);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patterkit/model",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Patter data-model types: source (scene/block/group/snippet/beat/jump), project, locale, authoring. The shape source-of-truth.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -34,6 +34,6 @@
|
|
|
34
34
|
"build": "tsup src/index.ts --format esm,cjs --dts --clean"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@wildwinter/expr": "^0.
|
|
37
|
+
"@wildwinter/expr": "^0.5.0"
|
|
38
38
|
}
|
|
39
39
|
}
|