extwee 2.2.5 → 2.3.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.
Files changed (63) hide show
  1. package/.github/workflows/dependabot-automerge.yml +23 -0
  2. package/.github/workflows/nodejs.yml +4 -1
  3. package/README.md +29 -14
  4. package/SECURITY.md +1 -1
  5. package/build/extwee.web.min.js +2 -0
  6. package/build/extwee.web.min.js.LICENSE.txt +1 -0
  7. package/extwee.config.json +6 -0
  8. package/extwee.config.md +67 -0
  9. package/index.js +2 -0
  10. package/package.json +24 -23
  11. package/src/CLI/CommandLineProcessing.js +196 -0
  12. package/src/CLI/ProcessConfig/loadStoryFormat.js +102 -0
  13. package/src/CLI/ProcessConfig/readDirectories.js +46 -0
  14. package/src/CLI/ProcessConfig.js +175 -0
  15. package/src/CLI/isDirectory.js +27 -0
  16. package/src/CLI/isFile.js +28 -0
  17. package/src/Config/parser.js +30 -8
  18. package/src/Passage.js +17 -2
  19. package/src/Story.js +101 -1
  20. package/src/StoryFormat/compile.js +19 -0
  21. package/src/StoryFormat.js +51 -0
  22. package/src/extwee.js +20 -195
  23. package/test/Config/Config.test.js +40 -10
  24. package/test/Config/files/full.json +8 -0
  25. package/test/Config/files/valid.json +4 -3
  26. package/test/Config/isDirectory.test.js +44 -0
  27. package/test/Config/isFile.test.js +50 -0
  28. package/test/Config/loadStoryFormat.test.js +101 -0
  29. package/test/Config/readDirectories.test.js +68 -0
  30. package/test/Objects/Passage.test.js +5 -0
  31. package/test/Objects/Story.test.js +174 -0
  32. package/test/Objects/StoryFormat.test.js +60 -0
  33. package/test/TWS/Parse.test.js +0 -22
  34. package/test/Web/window.Extwee.test.js +85 -0
  35. package/types/Story.d.ts +26 -1
  36. package/types/StoryFormat/compile.d.ts +8 -0
  37. package/types/StoryFormat.d.ts +7 -0
  38. package/types/index.d.ts +4 -2
  39. package/types/src/CLI/CommandLineProcessing.d.ts +8 -0
  40. package/types/src/CLI/ProcessConfig/loadStoryFormat.d.ts +20 -0
  41. package/types/src/CLI/ProcessConfig/readDirectories.d.ts +9 -0
  42. package/types/src/CLI/ProcessConfig.d.ts +12 -0
  43. package/types/src/CLI/isDirectory.d.ts +1 -0
  44. package/types/src/CLI/isFile.d.ts +1 -0
  45. package/types/src/Config/parser.d.ts +6 -0
  46. package/types/src/Config/reader.d.ts +11 -0
  47. package/types/src/IFID/generate.d.ts +14 -0
  48. package/types/src/JSON/parse.d.ts +44 -1
  49. package/types/src/Passage.d.ts +49 -4
  50. package/types/src/Story.d.ts +110 -16
  51. package/types/src/StoryFormat/compile.d.ts +8 -0
  52. package/types/src/StoryFormat/parse.d.ts +46 -3
  53. package/types/src/StoryFormat.d.ts +69 -38
  54. package/types/src/TWS/parse.d.ts +3 -3
  55. package/types/src/Twee/parse.d.ts +3 -4
  56. package/types/src/Twine1HTML/compile.d.ts +3 -1
  57. package/types/src/Twine1HTML/parse.d.ts +3 -4
  58. package/types/src/Twine2ArchiveHTML/compile.d.ts +8 -0
  59. package/types/src/Twine2ArchiveHTML/parse.d.ts +31 -1
  60. package/types/src/Twine2HTML/compile.d.ts +7 -2
  61. package/types/src/Twine2HTML/parse.d.ts +12 -9
  62. package/index.html +0 -22
  63. package/test/TWS/TWSParser/Example1.tws +0 -150
@@ -229,6 +229,45 @@ describe('Story', () => {
229
229
  });
230
230
  });
231
231
 
232
+ describe('storyStylesheet', () => {
233
+ let s = null;
234
+
235
+ beforeEach(() => {
236
+ s = new Story();
237
+ });
238
+
239
+ it('Set storyStylesheet', () => {
240
+ s.storyStylesheet = 'Test';
241
+ expect(s.storyStylesheet).not.toBe('');
242
+ });
243
+
244
+ it('Should throw error if not String', () => {
245
+ expect(() => {
246
+ s.storyStylesheet = 1;
247
+ }).toThrow();
248
+ }
249
+ );
250
+ });
251
+
252
+ describe('storyJavaScript', () => {
253
+ let s = null;
254
+
255
+ beforeEach(() => {
256
+ s = new Story();
257
+ });
258
+
259
+ it('Set storyJavaScript', () => {
260
+ s.storyJavaScript = 'Test';
261
+ expect(s.storyJavaScript).not.toBe('');
262
+ });
263
+
264
+ it('Should throw error if not String', () => {
265
+ expect(() => {
266
+ s.storyJavaScript = 1;
267
+ }).toThrow();
268
+ });
269
+ });
270
+
232
271
  describe('passages', () => {
233
272
  let s = null;
234
273
 
@@ -442,6 +481,30 @@ describe('Story', () => {
442
481
  // Should have a single passage.
443
482
  expect(result.passages.length).toBe(1);
444
483
  });
484
+
485
+ it('Should have style data', function () {
486
+ // Create default Story.
487
+ const s = new Story();
488
+ // Add a stylesheet.
489
+ s.storyStylesheet = 'Test';
490
+ // Convert to JSON and then back to object.
491
+ const result = JSON.parse(s.toJSON());
492
+ // Should have a stylesheet.
493
+ expect(result.style).toBe('Test');
494
+ }
495
+ );
496
+
497
+ it('Should have script data', function () {
498
+ // Create default Story.
499
+ const s = new Story();
500
+ // Add a script.
501
+ s.storyJavaScript = 'Test';
502
+ // Convert to JSON and then back to object.
503
+ const result = JSON.parse(s.toJSON());
504
+ // Should have a script.
505
+ expect(result.script).toBe('Test');
506
+ }
507
+ );
445
508
  });
446
509
 
447
510
  describe('toTwee()', function () {
@@ -647,6 +710,48 @@ describe('Story', () => {
647
710
  // Test for passage text.
648
711
  expect(p[0].text).toBe('Test');
649
712
  });
713
+
714
+ it('Should encode story stylesheet as passage with "stylesheet" tag', () => {
715
+ // Add passages.
716
+ s.storyStylesheet = 'Test';
717
+
718
+ // Set IFID.
719
+ s.IFID = 'DE7DF8AD-E4CD-499E-A4E7-C5B98B73449A';
720
+
721
+ // Convert into Twee.
722
+ const t = s.toTwee();
723
+
724
+ // Convert back into Story.
725
+ const story = parseTwee(t);
726
+
727
+ // Search for 'stylesheet'.
728
+ const p = story.getPassagesByTag('stylesheet');
729
+
730
+ // Test for passage text.
731
+ expect(p[0].text).toBe('Test');
732
+ }
733
+ );
734
+
735
+ it('Should encode story JavaScript as passage with "script" tag', () => {
736
+ // Add passages.
737
+ s.storyJavaScript = 'Test';
738
+
739
+ // Set IFID.
740
+ s.IFID = 'DE7DF8AD-E4CD-499E-A4E7-C5B98B73449A';
741
+
742
+ // Convert into Twee.
743
+ const t = s.toTwee();
744
+
745
+ // Convert back into Story.
746
+ const story = parseTwee(t);
747
+
748
+ // Search for 'stylesheet'.
749
+ const p = story.getPassagesByTag('script');
750
+
751
+ // Test for passage text.
752
+ expect(p[0].text).toBe('Test');
753
+ }
754
+ );
650
755
  });
651
756
 
652
757
  describe('toTwine2HTML()', () => {
@@ -695,6 +800,19 @@ describe('Story', () => {
695
800
  expect(result.includes('<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css">Word')).toBe(true);
696
801
  });
697
802
 
803
+ it('Should encode stylesheet property', () => {
804
+ // Add passage.
805
+ s.addPassage(new Passage('Start', 'Word'));
806
+ // Set start.
807
+ s.start = 'Start';
808
+ // Set stylesheet.
809
+ s.storyStylesheet = 'Test';
810
+ // Create HTML.
811
+ const result = s.toTwine2HTML();
812
+ // Expect the stylesheet passage text to be encoded.
813
+ expect(result.includes('<style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css">Test')).toBe(true);
814
+ });
815
+
698
816
  it('Should encode script passages', () => {
699
817
  // Add passage.
700
818
  s.addPassage(new Passage('Start', 'Word'));
@@ -708,6 +826,19 @@ describe('Story', () => {
708
826
  expect(result.includes('<script role="script" id="twine-user-script" type="text/twine-javascript">Word')).toBe(true);
709
827
  });
710
828
 
829
+ it('Should encode script property', () => {
830
+ // Add passage.
831
+ s.addPassage(new Passage('Start', 'Word'));
832
+ // Set start.
833
+ s.start = 'Start';
834
+ // Set script.
835
+ s.storyJavaScript = 'Test';
836
+ // Create HTML.
837
+ const result = s.toTwine2HTML();
838
+ // Expect the script passage text to be encoded.
839
+ expect(result.includes('<script role="script" id="twine-user-script" type="text/twine-javascript">Test')).toBe(true);
840
+ });
841
+
711
842
  it('Should encode format', () => {
712
843
  // Add passage.
713
844
  s.addPassage(new Passage('Start', 'Word'));
@@ -819,6 +950,49 @@ describe('Story', () => {
819
950
  // Expect the creator to be encoded.
820
951
  expect(result.includes(`creator="${creatorName}"`)).not.toBe(true);
821
952
  });
953
+
954
+ it('Should not encode story tag colors if none are present', () => {
955
+ // Add passage.
956
+ s.addPassage(new Passage('Start', 'Word'));
957
+ // Set start.
958
+ s.start = 'Start';
959
+ // Create HTML.
960
+ const result = s.toTwine2HTML();
961
+ // Expect the tag colors to not be encoded if none are present.
962
+ expect(result.includes('<tw-tag')).toBe(false);
963
+ });
964
+
965
+ it('Should encode single story tag color', () => {
966
+ // Add passage.
967
+ s.addPassage(new Passage('Start', 'Word'));
968
+ // Set start.
969
+ s.start = 'Start';
970
+ // Add tag colors.
971
+ s.tagColors = {
972
+ bar: 'green'
973
+ };
974
+ // Create HTML.
975
+ const result = s.toTwine2HTML();
976
+ // Expect the tag colors to be encoded.
977
+ expect(result.includes('<tw-tag name="bar" color="green"></tw-tag>')).toBe(true);
978
+ });
979
+
980
+ it('Should encode multiple story tag colors', () => {
981
+ // Add passage.
982
+ s.addPassage(new Passage('Start', 'Word'));
983
+ // Set start.
984
+ s.start = 'Start';
985
+ // Add tag colors.
986
+ s.tagColors = {
987
+ bar: 'green',
988
+ foo: 'red'
989
+ };
990
+ // Create HTML.
991
+ const result = s.toTwine2HTML();
992
+ // Expect the tag colors to be encoded.
993
+ expect(result.includes('<tw-tag name="bar" color="green"></tw-tag>')).toBe(true);
994
+ expect(result.includes('<tw-tag name="foo" color="red"></tw-tag>')).toBe(true);
995
+ });
822
996
  });
823
997
 
824
998
  describe('toTwine1HTML()', function () {
@@ -15,6 +15,29 @@ describe('StoryFormat', () => {
15
15
  });
16
16
  });
17
17
 
18
+ describe('Constructor with default values', () => {
19
+ it('Should create an instance of StoryFormat', () => {
20
+ const sf = new StoryFormat();
21
+ expect(sf).toBeInstanceOf(StoryFormat);
22
+ });
23
+ });
24
+
25
+ describe('Constructor with parameters', () => {
26
+ it('Should create an instance of StoryFormat with parameters', () => {
27
+ const sf = new StoryFormat('name', 'version', 'description', 'author', 'image', 'url', 'license', true, 'source');
28
+ expect(sf).toBeInstanceOf(StoryFormat);
29
+ expect(sf.name).toBe('name');
30
+ expect(sf.version).toBe('version');
31
+ expect(sf.description).toBe('description');
32
+ expect(sf.author).toBe('author');
33
+ expect(sf.image).toBe('image');
34
+ expect(sf.url).toBe('url');
35
+ expect(sf.license).toBe('license');
36
+ expect(sf.proofing).toBe(true);
37
+ expect(sf.source).toBe('source');
38
+ });
39
+ });
40
+
18
41
  describe('name', () => {
19
42
  it('Set new String', () => {
20
43
  const sf = new StoryFormat();
@@ -153,7 +176,44 @@ describe('StoryFormat', () => {
153
176
  describe('toString', () => {
154
177
  it('Should return string representation', () => {
155
178
  const sf = new StoryFormat();
179
+ sf.version = '1.0.0';
156
180
  expect(sf.toString()).toBe(JSON.stringify(sf, null, '\t'));
157
181
  });
182
+
183
+ it('Should throw error if version is not valid', () => {
184
+ const sf = new StoryFormat();
185
+ expect(() => {
186
+ sf.toString();
187
+ }).toThrow();
188
+ });
189
+ });
190
+
191
+ describe('toJSON', () => {
192
+ it('Should return JSON representation with default name', () => {
193
+ const sf = new StoryFormat();
194
+ sf.version = '1.0.0';
195
+ expect(sf.toJSON().includes("Untitled Story Format")).toEqual(true);
196
+ });
197
+
198
+ it('Should return JSON representation with custom name', () => {
199
+ const sf = new StoryFormat();
200
+ sf.name = 'Custom Name';
201
+ sf.version = '1.0.0';
202
+ expect(sf.toJSON().includes("Custom Name")).toEqual(true);
203
+ });
204
+
205
+ it('Should overwrite with default name if name is empty string', () => {
206
+ const sf = new StoryFormat();
207
+ sf.name = '';
208
+ sf.version = '1.0.0';
209
+ expect(sf.toJSON().includes("Untitled Story Format")).toEqual(true);
210
+ });
211
+
212
+ it('Should throw error if version is not valid', () => {
213
+ const sf = new StoryFormat();
214
+ expect(() => {
215
+ sf.toJSON();
216
+ }).toThrow();
217
+ });
158
218
  });
159
219
  });
@@ -7,28 +7,6 @@ describe('TWSParser', () => {
7
7
  expect(() => { parseTWS(0); }).toThrow();
8
8
  });
9
9
 
10
- describe('Story parsing', function () {
11
- let r = null;
12
-
13
- beforeAll(() => {
14
- const contents = fs.readFileSync('test/TWS/TWSParser/Example1.tws');
15
- //const b = Buffer.from(contents, 'binary');
16
- r = parseTWS(contents);
17
- });
18
-
19
- it('Should parse StoryTitle', function () {
20
- expect(r.name).toBe('Untitled Story');
21
- });
22
-
23
- it('Should parse zoom', function () {
24
- expect(r.zoom).toBe(1);
25
- });
26
-
27
- it('Should parse start passage', function () {
28
- expect(r.start).toBe('Start');
29
- });
30
- });
31
-
32
10
  describe('Passage parsing', function () {
33
11
  let r = null;
34
12
 
@@ -0,0 +1,85 @@
1
+ /**
2
+ * @jest-environment jsdom
3
+ */
4
+
5
+ import '../../web-index.js';
6
+
7
+ describe('Extwee', () => {
8
+ it('should have all the expected properties', () => {
9
+ expect(window.Extwee).toHaveProperty('parseTwee');
10
+ expect(window.Extwee).toHaveProperty('parseJSON');
11
+ expect(window.Extwee).toHaveProperty('parseTWS');
12
+ expect(window.Extwee).toHaveProperty('parseStoryFormat');
13
+ expect(window.Extwee).toHaveProperty('parseTwine1HTML');
14
+ expect(window.Extwee).toHaveProperty('parseTwine2HTML');
15
+ expect(window.Extwee).toHaveProperty('parseTwine2ArchiveHTML');
16
+ expect(window.Extwee).toHaveProperty('compileTwine1HTML');
17
+ expect(window.Extwee).toHaveProperty('compileTwine2HTML');
18
+ expect(window.Extwee).toHaveProperty('compileTwine2ArchiveHTML');
19
+ expect(window.Extwee).toHaveProperty('generateIFID');
20
+ expect(window.Extwee).toHaveProperty('Story');
21
+ expect(window.Extwee).toHaveProperty('Passage');
22
+ expect(window.Extwee).toHaveProperty('StoryFormat');
23
+ });
24
+
25
+ it('should have the expected types', () => {
26
+ expect(typeof window.Extwee.parseTwee).toBe('function');
27
+ expect(typeof window.Extwee.parseJSON).toBe('function');
28
+ expect(typeof window.Extwee.parseTWS).toBe('function');
29
+ expect(typeof window.Extwee.parseStoryFormat).toBe('function');
30
+ expect(typeof window.Extwee.parseTwine1HTML).toBe('function');
31
+ expect(typeof window.Extwee.parseTwine2HTML).toBe('function');
32
+ expect(typeof window.Extwee.parseTwine2ArchiveHTML).toBe('function');
33
+ expect(typeof window.Extwee.compileTwine1HTML).toBe('function');
34
+ expect(typeof window.Extwee.compileTwine2HTML).toBe('function');
35
+ expect(typeof window.Extwee.compileTwine2ArchiveHTML).toBe('function');
36
+ expect(typeof window.Extwee.generateIFID).toBe('function');
37
+ expect(typeof window.Extwee.Story).toBe('function');
38
+ expect(typeof window.Extwee.Passage).toBe('function');
39
+ expect(typeof window.Extwee.StoryFormat).toBe('function');
40
+ });
41
+
42
+ it('should have the expected properties in StoryFormat', () => {
43
+ const storyFormat = new window.Extwee.StoryFormat();
44
+ expect(storyFormat).toHaveProperty('name');
45
+ expect(storyFormat).toHaveProperty('version');
46
+ expect(storyFormat).toHaveProperty('description');
47
+ expect(storyFormat).toHaveProperty('author');
48
+ expect(storyFormat).toHaveProperty('image');
49
+ expect(storyFormat).toHaveProperty('url');
50
+ expect(storyFormat).toHaveProperty('license');
51
+ expect(storyFormat).toHaveProperty('proofing');
52
+ expect(storyFormat).toHaveProperty('source');
53
+ });
54
+
55
+ it('should have the expected properties in Story', () => {
56
+ const story = new window.Extwee.Story();
57
+ expect(story).toHaveProperty('name');
58
+ expect(story).toHaveProperty('IFID');
59
+ expect(story).toHaveProperty('start');
60
+ expect(story).toHaveProperty('format');
61
+ expect(story).toHaveProperty('formatVersion');
62
+ expect(story).toHaveProperty('zoom');
63
+ expect(story).toHaveProperty('passages');
64
+ expect(story).toHaveProperty('creator');
65
+ expect(story).toHaveProperty('creatorVersion');
66
+ expect(story).toHaveProperty('metadata');
67
+ expect(story).toHaveProperty('tagColors');
68
+ expect(story).toHaveProperty('storyJavaScript');
69
+ expect(story).toHaveProperty('storyStylesheet');
70
+ });
71
+
72
+ it('should have the expected types in Passage', () => {
73
+ const passage = new window.Extwee.Passage();
74
+ expect(passage).toHaveProperty('name');
75
+ expect(passage).toHaveProperty('text');
76
+ expect(passage).toHaveProperty('tags');
77
+ expect(passage).toHaveProperty('metadata');
78
+ });
79
+
80
+ it('should generate a valid IFID', () => {
81
+ const ifid = window.Extwee.generateIFID();
82
+ expect(ifid).toMatch(/^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/);
83
+ });
84
+
85
+ });
package/types/Story.d.ts CHANGED
@@ -13,6 +13,8 @@
13
13
  * @property {string} creatorVersion - Version used to create Story.
14
14
  * @property {object} metadata - Metadata of Story.
15
15
  * @property {object} tagColors - Tag Colors
16
+ * @property {string} storyJavaScript - Story JavaScript
17
+ * @property {string} storyStylesheet - Story Stylesheet
16
18
  * @method {number} addPassage - Add a passage to the story and returns the new length of the passages array.
17
19
  * @method {number} removePassageByName - Remove a passage from the story by name and returns the new length of the passages array.
18
20
  * @method {Array} getPassagesByTag - Find passages by tag.
@@ -142,6 +144,25 @@ export class Story {
142
144
  * @property {Array} passages - Passages
143
145
  */
144
146
  get passages(): any[];
147
+ /**
148
+ * @param {string} s - Replacement story stylesheet
149
+ */
150
+ set storyStylesheet(s: string);
151
+ /**
152
+ * Story stylesheet data can be set as a passage, property value, or both.
153
+ * @returns {string} storyStylesheet
154
+ */
155
+ get storyStylesheet(): string;
156
+ /**
157
+ * Set story JavaScript.
158
+ * @param {string} s - Replacement story JavaScript
159
+ */
160
+ set storyJavaScript(s: string);
161
+ /**
162
+ * Get story JavaScript.
163
+ * @returns {string} storyJavaScript
164
+ */
165
+ get storyJavaScript(): string;
145
166
  /**
146
167
  * Add a passage to the story.
147
168
  * Passing `StoryData` will override story metadata and `StoryTitle` will override story name.
@@ -209,6 +230,10 @@ export class Story {
209
230
  * - `format`: (string) Optional. The format of the story.
210
231
  * - `format-version`: (string) Optional. The version of the format of the story.
211
232
  *
233
+ * Because story stylesheet data can be represented as a passage, property value, or both, all approaches are encoded.
234
+ *
235
+ * Because story JavaScript can be represented as a passage, property value, or both, all approaches are encoded.
236
+ *
212
237
  * @method toTwine2HTML
213
238
  * @returns {string} Twine 2 HTML string
214
239
  */
@@ -226,5 +251,5 @@ export class Story {
226
251
  #private;
227
252
  }
228
253
  export const creatorName: "extwee";
229
- export const creatorVersion: "2.2.5";
254
+ export const creatorVersion: "2.2.6";
230
255
  import Passage from './Passage.js';
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Compiles a {@link StoryFormat} object into a JSONP string for writing to a `format.js` file.
3
+ * @see {@link https://github.com/iftechfoundation/twine-specs/blob/master/twine-2-storyformats-spec.md Twine 2 Story Formats Specification}
4
+ * @param {StoryFormat} storyFormat Story format object to compile.
5
+ * @returns {string} JSONP string.
6
+ */
7
+ export function compile(storyFormat: StoryFormat): string;
8
+ import StoryFormat from '../StoryFormat.js';
@@ -30,6 +30,7 @@
30
30
  * sf.source = 'New';
31
31
  */
32
32
  export default class StoryFormat {
33
+ constructor(name?: string, version?: string, description?: string, author?: string, image?: string, url?: string, license?: string, proofing?: boolean, source?: string);
33
34
  /**
34
35
  * @param {string} n - Replacement name.
35
36
  */
@@ -117,5 +118,11 @@ export default class StoryFormat {
117
118
  * @returns {string} - A string representation of the story format.
118
119
  */
119
120
  toString(): string;
121
+ /**
122
+ * Produces a JSON representation of the story format object.
123
+ * @method toJSON
124
+ * @returns {object} - A JSON representation of the story format.
125
+ */
126
+ toJSON(): object;
120
127
  #private;
121
128
  }
package/types/index.d.ts CHANGED
@@ -8,7 +8,9 @@ import { parse as parseTwine2ArchiveHTML } from './src/Twine2ArchiveHTML/parse.j
8
8
  import { compile as compileTwine1HTML } from './src/Twine1HTML/compile.js';
9
9
  import { compile as compileTwine2HTML } from './src/Twine2HTML/compile.js';
10
10
  import { compile as compileTwine2ArchiveHTML } from './src/Twine2ArchiveHTML/compile.js';
11
- import Story from './src/Story.js';
11
+ import { compile as compileStoryFormat } from './src/StoryFormat/compile.js';
12
+ import { generate as generateIFID } from './src/IFID/generate.js';
13
+ import { Story } from './src/Story.js';
12
14
  import Passage from './src/Passage.js';
13
15
  import StoryFormat from './src/StoryFormat.js';
14
- export { parseTwee, parseJSON, parseTWS, parseStoryFormat, parseTwine1HTML, parseTwine2HTML, parseTwine2ArchiveHTML, compileTwine1HTML, compileTwine2HTML, compileTwine2ArchiveHTML, Story, Passage, StoryFormat };
16
+ export { parseTwee, parseJSON, parseTWS, parseStoryFormat, parseTwine1HTML, parseTwine2HTML, parseTwine2ArchiveHTML, compileTwine1HTML, compileTwine2HTML, compileTwine2ArchiveHTML, compileStoryFormat, generateIFID, Story, Passage, StoryFormat };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Process command line arguments.
3
+ * @function CommandLineProcessing
4
+ * @description This function processes the command line arguments passed to the Extwee CLI.
5
+ * @module CLI/commandLineProcessing
6
+ * @param {Array} argv - The command line arguments passed to the CLI.
7
+ */
8
+ export function CommandLineProcessing(argv: any[]): void;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Load the story format from the story-formats directory.
3
+ * @function loadStoryFormat
4
+ * @description This function loads the story format from the story-formats directory.
5
+ * It checks if the story-formats directory exists, if the named story format exists,
6
+ * if the version directory exists, and if the format.js file exists.
7
+ * If any of these checks fail, the function will exit the process with an error message.
8
+ * If all checks pass, the function will return the contents of the format.js file.
9
+ * @param {string} storyFormatName - The name of the story format.
10
+ * @param {string} storyFormatVersion - The version of the story format.
11
+ * @returns {string} - The contents of the format.js file.
12
+ * @throws {Error} - If the story-formats directory does not exist, if the named story format does not exist,
13
+ * if the version directory does not exist, or if the format.js file does not exist.
14
+ * @example
15
+ * // Load the story format from the story-formats directory.
16
+ * const storyFormat = loadStoryFormat('Harlowe', '3.2.0');
17
+ * console.log(storyFormat);
18
+ * // Output: The contents of the format.js file.
19
+ */
20
+ export function loadStoryFormat(storyFormatName: string, storyFormatVersion: string): string;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Read the contents of a directory and returns all directories.
3
+ * @function readDirectories
4
+ * @description This function reads the contents of a directory and returns a list of directories.
5
+ * @param {string} directory - The path to the directory to read.
6
+ * @returns {Array<string>} - An array of directories in the directory.
7
+ * @throws {Error} - If the directory does not exist or if there is an error reading the directory.
8
+ */
9
+ export function readDirectories(directory: string): Array<string>;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Processes the config file, if present.
3
+ * @function ConfigFileProcessing
4
+ * @description This function processes the config file.
5
+ * It checks if the config file exists and if it does, it reads the config file.
6
+ * If the config file does not exist, the function will exit the process with an error message.
7
+ * The config file is used to store configuration options for the Extwee CLI.
8
+ * @returns {void}
9
+ * @throws {Error} - If the config file does not exist or if there is an error parsing the config file.
10
+ */
11
+ export function ConfigFileProcessing(): void;
12
+ export function ConfigFilePresent(): boolean;
@@ -0,0 +1 @@
1
+ export function isDirectory(path: any): boolean;
@@ -0,0 +1 @@
1
+ export function isFile(path: any): boolean;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Parses a JSON object and extracts the StoryFormat, StoryTitle and StoryVersion.
3
+ * @param {object} obj Incoming JSON object.
4
+ * @returns {object} An object containing the extracted results.
5
+ */
6
+ export function parser(obj: object): object;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Read a JSON file and return its contents.
3
+ * @param {string} path Path to the JSON file.
4
+ * @returns {object} Parsed JSON object.
5
+ * @throws {Error} If the file does not exist.
6
+ * @throws {Error} If the file is not a valid JSON file.
7
+ * @example
8
+ * const contents = reader('test/Config/files/valid.json');
9
+ * console.log(contents); // {"story-format": 'Harlowe', "story-title": "My Story"}
10
+ */
11
+ export function reader(path: string): object;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Generates an Interactive Fiction Identification (IFID) based the Treaty of Babel.
3
+ *
4
+ * For Twine works, the IFID is a UUID (v4) in uppercase.
5
+ * @see Treaty of Babel ({@link https://babel.ifarchive.org/babel_rev11.html#the-ifid-for-an-html-story-file})
6
+ * @function generate
7
+ * @description Generates a new IFID.
8
+ * @returns {string} IFID
9
+ * @example
10
+ * const ifid = generate();
11
+ * console.log(ifid);
12
+ * // => 'A1B2C3D4-E5F6-G7H8-I9J0-K1L2M3N4O5P6'
13
+ */
14
+ export function generate(): string;
@@ -1,8 +1,51 @@
1
1
  /**
2
2
  * Parse JSON representation into Story.
3
+ * @see {@link https://github.com/iftechfoundation/twine-specs/blob/master/twine-2-jsonoutput-doc.md Twine 2 JSON Specification}
3
4
  * @function parse
4
5
  * @param {string} jsonString - JSON string to convert to Story.
6
+ * @throws {Error} - Invalid JSON!
5
7
  * @returns {Story} Story object.
8
+ * @example
9
+ * const jsonString = `{
10
+ * "name": "My Story",
11
+ * "start": "First Passage",
12
+ * "ifid": "A1B2C3D4-E5F6-G7H8-I9J0-K1L2M3N4O5P6",
13
+ * "format": "SugarCube",
14
+ * "formatVersion": "2.31.0",
15
+ * "creator": "Twine",
16
+ * "creatorVersion": "2.3.9",
17
+ * "zoom": 1,
18
+ * "passages": [
19
+ * {
20
+ * "name": "First Passage",
21
+ * "tags": "",
22
+ * "metadata": "",
23
+ * "text": "This is the first passage."
24
+ * },
25
+ * ]
26
+ * }`;
27
+ * const story = parse(jsonString);
28
+ * console.log(story);
29
+ * // => Story {
30
+ * // name: 'My Story',
31
+ * // start: 'First Passage',
32
+ * // IFID: 'A1B2C3D4-E5F6-G7H8-I9J0-K1L2M3N4O5P6',
33
+ * // format: 'SugarCube',
34
+ * // formatVersion: '2.31.0',
35
+ * // creator: 'Twine',
36
+ * // creatorVersion: '2.3.9',
37
+ * // zoom: 1,
38
+ * // tagColors: {},
39
+ * // metadata: {},
40
+ * // passages: [
41
+ * // Passage {
42
+ * // name: 'First Passage',
43
+ * // tags: '',
44
+ * // metadata: '',
45
+ * // text: 'This is the first passage.'
46
+ * // }
47
+ * // ]
48
+ * // }
6
49
  */
7
50
  export function parse(jsonString: string): Story;
8
- import Story from '../Story.js';
51
+ import { Story } from '../Story.js';