@docx4j/core-ts 0.1.0 → 0.1.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.
Files changed (168) hide show
  1. package/README.md +410 -10
  2. package/dist/model/content/Body.d.mts +109 -4
  3. package/dist/model/content/Body.mjs +300 -29
  4. package/dist/model/content/Comment.d.mts +78 -0
  5. package/dist/model/content/Comment.mjs +429 -0
  6. package/dist/model/content/ContentControl.d.mts +173 -0
  7. package/dist/model/content/ContentControl.mjs +638 -0
  8. package/dist/model/content/Font.d.mts +48 -8
  9. package/dist/model/content/Font.mjs +55 -13
  10. package/dist/model/content/InlinePicture.d.mts +103 -0
  11. package/dist/model/content/InlinePicture.mjs +361 -0
  12. package/dist/model/content/List.d.mts +253 -0
  13. package/dist/model/content/List.mjs +778 -0
  14. package/dist/model/content/Paragraph.d.mts +213 -16
  15. package/dist/model/content/Paragraph.mjs +611 -57
  16. package/dist/model/content/Range.d.mts +48 -4
  17. package/dist/model/content/Range.mjs +161 -4
  18. package/dist/model/content/Table.d.mts +130 -0
  19. package/dist/model/content/Table.mjs +429 -0
  20. package/dist/model/content/TrackedChange.d.mts +96 -0
  21. package/dist/model/content/TrackedChange.mjs +352 -0
  22. package/dist/model/content/comments.d.mts +122 -0
  23. package/dist/model/content/comments.mjs +248 -0
  24. package/dist/model/content/index.d.mts +13 -3
  25. package/dist/model/content/index.mjs +15 -3
  26. package/dist/model/content/ooxml.d.mts +17 -0
  27. package/dist/model/content/ooxml.mjs +214 -0
  28. package/dist/model/content/styles.d.mts +21 -0
  29. package/dist/model/content/styles.mjs +86 -0
  30. package/dist/model/content/tracking.d.mts +104 -0
  31. package/dist/model/content/tracking.mjs +313 -0
  32. package/dist/model/content/tree.d.mts +56 -9
  33. package/dist/model/content/tree.mjs +104 -31
  34. package/dist/model/customxml/CustomXmlPart.d.mts +158 -0
  35. package/dist/model/customxml/CustomXmlPart.mjs +415 -0
  36. package/dist/model/customxml/CustomXmlPartCollection.d.mts +68 -0
  37. package/dist/model/customxml/CustomXmlPartCollection.mjs +183 -0
  38. package/dist/model/customxml/XmlMapping.d.mts +46 -0
  39. package/dist/model/customxml/XmlMapping.mjs +98 -0
  40. package/dist/model/customxml/bindings.d.mts +41 -0
  41. package/dist/model/customxml/bindings.mjs +230 -0
  42. package/dist/model/customxml/index.d.mts +7 -0
  43. package/dist/model/customxml/index.mjs +9 -0
  44. package/dist/model/customxml/insert.d.mts +20 -0
  45. package/dist/model/customxml/insert.mjs +22 -0
  46. package/dist/model/customxml/kinds.d.mts +103 -0
  47. package/dist/model/customxml/kinds.mjs +267 -0
  48. package/dist/model/customxml/xpath.d.mts +52 -0
  49. package/dist/model/customxml/xpath.mjs +205 -0
  50. package/dist/model/fonts/CJKToEnglish.d.mts +2 -0
  51. package/dist/model/fonts/CJKToEnglish.mjs +16 -0
  52. package/dist/model/fonts/FontFallback.d.mts +58 -0
  53. package/dist/model/fonts/FontFallback.mjs +219 -0
  54. package/dist/model/fonts/IdentityPlusMapper.d.mts +7 -0
  55. package/dist/model/fonts/IdentityPlusMapper.mjs +19 -0
  56. package/dist/model/fonts/LanguageTagToScriptMapping.d.mts +7 -0
  57. package/dist/model/fonts/LanguageTagToScriptMapping.mjs +67 -0
  58. package/dist/model/fonts/Mapper.d.mts +190 -0
  59. package/dist/model/fonts/Mapper.mjs +481 -0
  60. package/dist/model/fonts/PhysicalFont.d.mts +34 -0
  61. package/dist/model/fonts/PhysicalFont.mjs +62 -0
  62. package/dist/model/fonts/RunFontSelector.d.mts +194 -0
  63. package/dist/model/fonts/RunFontSelector.mjs +441 -0
  64. package/dist/model/fonts/ThemeFonts.d.mts +17 -0
  65. package/dist/model/fonts/ThemeFonts.mjs +76 -0
  66. package/dist/model/fonts/defaultTheme.d.mts +37 -0
  67. package/dist/model/fonts/defaultTheme.mjs +57 -0
  68. package/dist/model/fonts/families.generated.d.mts +11 -0
  69. package/dist/model/fonts/families.generated.mjs +17 -0
  70. package/dist/model/fonts/fontsInUse.d.mts +39 -0
  71. package/dist/model/fonts/fontsInUse.mjs +183 -0
  72. package/dist/model/fonts/index.d.mts +14 -0
  73. package/dist/model/fonts/index.mjs +29 -0
  74. package/dist/model/fonts/lookup.d.mts +5 -0
  75. package/dist/model/fonts/lookup.mjs +12 -0
  76. package/dist/model/fonts/registry.d.mts +31 -0
  77. package/dist/model/fonts/registry.mjs +103 -0
  78. package/dist/model/fonts/scripts.d.mts +2 -0
  79. package/dist/model/fonts/scripts.mjs +78 -0
  80. package/dist/model/fonts/substitutions.generated.d.mts +30 -0
  81. package/dist/model/fonts/substitutions.generated.mjs +12 -0
  82. package/dist/model/fonts/themes.generated.d.mts +6 -0
  83. package/dist/model/fonts/themes.generated.mjs +11 -0
  84. package/dist/model/index.d.mts +5 -0
  85. package/dist/model/index.mjs +13 -1
  86. package/dist/model/listnumbering/Emulator.d.mts +187 -0
  87. package/dist/model/listnumbering/Emulator.mjs +332 -0
  88. package/dist/model/listnumbering/definitions.d.mts +251 -0
  89. package/dist/model/listnumbering/definitions.mjs +571 -0
  90. package/dist/model/listnumbering/formats.d.mts +25 -0
  91. package/dist/model/listnumbering/formats.mjs +320 -0
  92. package/dist/model/listnumbering/index.d.mts +4 -0
  93. package/dist/model/listnumbering/index.mjs +15 -0
  94. package/dist/model/listnumbering/state.d.mts +97 -0
  95. package/dist/model/listnumbering/state.mjs +179 -0
  96. package/dist/model/properties/PropertyResolver.d.mts +216 -0
  97. package/dist/model/properties/PropertyResolver.mjs +524 -0
  98. package/dist/model/properties/catalogue.d.mts +179 -0
  99. package/dist/model/properties/catalogue.mjs +860 -0
  100. package/dist/model/properties/index.d.mts +4 -0
  101. package/dist/model/properties/index.mjs +9 -0
  102. package/dist/model/properties/log.d.mts +7 -0
  103. package/dist/model/properties/log.mjs +25 -0
  104. package/dist/model/properties/styleUtil.d.mts +112 -0
  105. package/dist/model/properties/styleUtil.mjs +359 -0
  106. package/dist/node/index.d.mts +1 -0
  107. package/dist/node/index.mjs +12 -0
  108. package/dist/office-js/document.d.mts +111 -0
  109. package/dist/office-js/document.mjs +267 -0
  110. package/dist/office-js/enums.d.mts +187 -0
  111. package/dist/office-js/enums.mjs +176 -0
  112. package/dist/office-js/errors.d.mts +29 -0
  113. package/dist/office-js/errors.mjs +39 -0
  114. package/dist/office-js/extras.d.mts +5 -0
  115. package/dist/office-js/extras.mjs +29 -0
  116. package/dist/office-js/fragment.d.mts +10 -0
  117. package/dist/office-js/fragment.mjs +23 -0
  118. package/dist/office-js/index.d.mts +183 -0
  119. package/dist/office-js/index.mjs +54 -0
  120. package/dist/office-js/proxy.d.mts +72 -0
  121. package/dist/office-js/proxy.mjs +279 -0
  122. package/dist/office-js/run.d.mts +32 -0
  123. package/dist/office-js/run.mjs +66 -0
  124. package/dist/office-js/supported.d.mts +7 -0
  125. package/dist/office-js/supported.generated.d.mts +1 -0
  126. package/dist/office-js/supported.generated.mjs +235 -0
  127. package/dist/office-js/supported.mjs +53 -0
  128. package/dist/office-js/toApiScript.d.mts +25 -0
  129. package/dist/office-js/toApiScript.mjs +394 -0
  130. package/dist/opc/ContentTypes.d.mts +1 -0
  131. package/dist/opc/ContentTypes.mjs +1 -0
  132. package/dist/opc/DirectoryPartStore.d.mts +47 -0
  133. package/dist/opc/DirectoryPartStore.mjs +123 -0
  134. package/dist/opc/exceptions.d.mts +30 -0
  135. package/dist/opc/exceptions.mjs +38 -0
  136. package/dist/opc/index.d.mts +1 -1
  137. package/dist/opc/index.mjs +1 -1
  138. package/dist/packages/OpcPackage.d.mts +19 -1
  139. package/dist/packages/OpcPackage.mjs +29 -0
  140. package/dist/packages/PresentationMLPackage.d.mts +71 -1
  141. package/dist/packages/PresentationMLPackage.mjs +179 -0
  142. package/dist/packages/SpreadsheetMLPackage.d.mts +30 -1
  143. package/dist/packages/SpreadsheetMLPackage.mjs +78 -0
  144. package/dist/packages/WordprocessingMLPackage.d.mts +124 -2
  145. package/dist/packages/WordprocessingMLPackage.mjs +309 -2
  146. package/dist/packages/index.d.mts +1 -1
  147. package/dist/packages/index.mjs +1 -1
  148. package/dist/parts/DefaultXmlPart.d.mts +18 -0
  149. package/dist/parts/DefaultXmlPart.mjs +34 -5
  150. package/dist/parts/PartRegistry.mjs +1 -0
  151. package/dist/parts/XmlPart.d.mts +33 -0
  152. package/dist/parts/XmlPart.mjs +105 -2
  153. package/dist/parts/pml/defaults.d.mts +6 -0
  154. package/dist/parts/pml/defaults.mjs +53 -0
  155. package/dist/parts/pml/index.d.mts +66 -3
  156. package/dist/parts/pml/index.mjs +206 -7
  157. package/dist/parts/pml/placeholders.d.mts +71 -0
  158. package/dist/parts/pml/placeholders.mjs +141 -0
  159. package/dist/parts/sml/index.d.mts +19 -1
  160. package/dist/parts/sml/index.mjs +60 -1
  161. package/dist/parts/wml/comments.d.mts +1 -0
  162. package/dist/parts/wml/comments.mjs +179 -0
  163. package/dist/parts/wml/defaultNumbering.d.mts +1 -0
  164. package/dist/parts/wml/defaultNumbering.mjs +216 -0
  165. package/dist/parts/wml/index.d.mts +121 -0
  166. package/dist/parts/wml/index.mjs +291 -0
  167. package/dist/xml/dom.mjs +1 -2
  168. package/package.json +25 -4
@@ -0,0 +1,279 @@
1
+ // The proxies, collections and results of the Word shim (CR-002 section 3.10).
2
+ //
3
+ // The views of `src/model/content/` stay plain objects for direct users (section 3.12); the shim
4
+ // is the only thing that wraps them. A proxy does four things: `load` / `track` / `untrack` are
5
+ // no-ops returning the object, a member the views implement passes through (its result wrapped in
6
+ // turn), an asynchronous member returns a `ClientResult` whose `value` the next `context.sync()`
7
+ // fills, and anything else throws `NotSupportedError` naming the class and the member.
8
+ import { NotSupportedError, ItemNotFoundError, ValueNotLoadedError } from './errors.mjs';
9
+ /** The wrapped object's target, for `unwrap`. */
10
+ const RAW = Symbol('docx4j.officeJs.raw');
11
+ /** Marks an array that is already a collection, so that it is not wrapped a second time. */
12
+ const COLLECTION = Symbol('docx4j.officeJs.collection');
13
+ /**
14
+ * The result of an asynchronous call, as Office JS hands one out: `value` after `context.sync()`.
15
+ * It is also awaitable (an extension), so that `await body.insertXml(...)`, which is how the
16
+ * content API and `toApiScript`'s output read, keeps its order through the shim.
17
+ */
18
+ export class ClientResult {
19
+ constructor(
20
+ /** The call this is the result of ('getOoxml'), for the error message. */
21
+ member = 'value') {
22
+ this.member = member;
23
+ this.loaded = false;
24
+ }
25
+ /** @internal the underlying call, which `context.sync()` awaits and `then` delegates to. */
26
+ attach(promise) {
27
+ this.promise = promise;
28
+ }
29
+ /** Awaiting the result resolves to the value, without waiting for the next sync. */
30
+ then(onFulfilled, onRejected) {
31
+ var _a;
32
+ const promise = (_a = this.promise) !== null && _a !== void 0 ? _a : Promise.resolve(this.value);
33
+ return promise.then(onFulfilled, onRejected);
34
+ }
35
+ /** The value; throws until `context.sync()` has resolved it, as Office JS does. */
36
+ get value() {
37
+ if (!this.loaded)
38
+ throw new ValueNotLoadedError(`The result of ${this.member}() is not loaded yet; await context.sync() first`);
39
+ return this.result;
40
+ }
41
+ /** @internal filled by the context when the underlying promise settles. */
42
+ resolveWith(value) {
43
+ this.result = value;
44
+ this.loaded = true;
45
+ }
46
+ /** True once `context.sync()` has filled it. */
47
+ get isLoaded() {
48
+ return this.loaded;
49
+ }
50
+ toJSON() {
51
+ return { value: this.loaded ? this.result : undefined };
52
+ }
53
+ }
54
+ /** The item class name behind a member that returns a collection, for empty ones and for messages. */
55
+ const COLLECTION_ITEM_CLASS = {
56
+ paragraphs: 'Paragraph',
57
+ tables: 'Table',
58
+ rows: 'TableRow',
59
+ cells: 'TableCell',
60
+ contentControls: 'ContentControl',
61
+ inlinePictures: 'InlinePicture',
62
+ lists: 'List',
63
+ getLevelParagraphs: 'Paragraph',
64
+ getDescendants: 'Paragraph',
65
+ fields: 'Field',
66
+ search: 'Range',
67
+ getComments: 'Comment',
68
+ comments: 'Comment',
69
+ replies: 'Comment',
70
+ getTrackedChanges: 'TrackedChange',
71
+ customXmlParts: 'CustomXmlPart',
72
+ };
73
+ /** Members whose promise is the caller's to await, not a ClientResult: `context.sync()`. */
74
+ const RAW_PROMISE_MEMBERS = new Set(['sync']);
75
+ /** The engine behind the views: handed out as it is, never proxied, so that docx4j code works on it. */
76
+ const RAW_VALUE_MEMBERS = new Set(['package_', 'part']);
77
+ /** Objects that are data, not views: never proxied, handed out as they are. */
78
+ const PLAIN_CONSTRUCTORS = new Set([
79
+ Object, Array, Date, RegExp, Map, Set, WeakMap, WeakSet, Promise, Error, Uint8Array, ArrayBuffer, Function,
80
+ ]);
81
+ /** True for an instance of a class of ours (a view, or one of the shim's own objects). */
82
+ function isView(value) {
83
+ const proto = Object.getPrototypeOf(value);
84
+ if (proto === null || proto === Object.prototype)
85
+ return false;
86
+ const ctor = value.constructor;
87
+ return typeof ctor === 'function' && !PLAIN_CONSTRUCTORS.has(ctor);
88
+ }
89
+ function isThenable(value) {
90
+ return typeof value === 'object' && value !== null && typeof value.then === 'function';
91
+ }
92
+ /** The target behind a proxy the shim handed out; anything else is returned as it is. */
93
+ export function unwrap(value) {
94
+ if (typeof value === 'object' && value !== null) {
95
+ const raw = value[RAW];
96
+ if (raw !== undefined)
97
+ return raw;
98
+ }
99
+ return value;
100
+ }
101
+ /**
102
+ * A null object: `isNullObject` is true and every other member throws, as Office JS's
103
+ * `*OrNullObject` results do.
104
+ */
105
+ export function nullObject(className) {
106
+ const fail = (member) => {
107
+ throw new ItemNotFoundError(`Word.${className} is a null object (nothing matched); check isNullObject before using ${member}`);
108
+ };
109
+ const proxy = new Proxy({ isNullObject: true }, {
110
+ get(target, prop) {
111
+ if (typeof prop === 'symbol')
112
+ return Reflect.get(target, prop);
113
+ if (prop === 'isNullObject')
114
+ return true;
115
+ if (prop === 'toJSON')
116
+ return () => ({ isNullObject: true });
117
+ if (prop === 'then')
118
+ return undefined;
119
+ if (prop === 'load' || prop === 'track' || prop === 'untrack')
120
+ return () => proxy;
121
+ return fail(prop);
122
+ },
123
+ set(_target, prop) {
124
+ return fail(String(prop));
125
+ },
126
+ });
127
+ return proxy;
128
+ }
129
+ /**
130
+ * Wraps the views of one `Word.run` in proxies. One wrapper per context, so that the same view
131
+ * gives the same proxy and object identity holds within a batch, as it does in Office JS.
132
+ */
133
+ export class Wrapper {
134
+ constructor(context,
135
+ /** Members the shim adds over a view (`getOoxml`), consulted only when the view has none. */
136
+ extras = {}) {
137
+ this.context = context;
138
+ this.extras = extras;
139
+ this.cache = new WeakMap();
140
+ }
141
+ /** Wraps whatever a member returned: a view, an array of views, a promise, or a plain value. */
142
+ value(value, member = '') {
143
+ if (value === null || typeof value !== 'object')
144
+ return value;
145
+ if (value instanceof ClientResult)
146
+ return value;
147
+ if (Array.isArray(value))
148
+ return value[COLLECTION] === true ? value : this.collection(value, member);
149
+ if (!isView(value))
150
+ return value;
151
+ return this.object(value);
152
+ }
153
+ /** The proxy over one view. */
154
+ object(view, className = view.constructor.name) {
155
+ const target = unwrap(view);
156
+ const cached = this.cache.get(target);
157
+ if (cached !== undefined)
158
+ return cached;
159
+ const wrapper = this;
160
+ const proxy = new Proxy(target, {
161
+ get(obj, prop, receiver) {
162
+ var _a;
163
+ if (typeof prop === 'symbol')
164
+ return prop === RAW ? obj : Reflect.get(obj, prop, obj);
165
+ switch (prop) {
166
+ case 'load':
167
+ case 'retrieve':
168
+ case 'track':
169
+ case 'untrack':
170
+ if (!(prop in obj))
171
+ return () => proxy;
172
+ break;
173
+ case 'isNullObject':
174
+ if (!(prop in obj))
175
+ return false;
176
+ break;
177
+ case 'then':
178
+ if (!(prop in obj))
179
+ return undefined;
180
+ break;
181
+ default:
182
+ break;
183
+ }
184
+ if (!(prop in obj)) {
185
+ const extra = (_a = wrapper.extras[className]) === null || _a === void 0 ? void 0 : _a[prop];
186
+ if (extra === undefined)
187
+ throw new NotSupportedError(className, prop);
188
+ const call = extra;
189
+ return (...args) => wrapper.result(call(obj, ...args.map(unwrap)), prop);
190
+ }
191
+ const member = Reflect.get(obj, prop, obj);
192
+ if (typeof member === 'function') {
193
+ if (RAW_PROMISE_MEMBERS.has(prop))
194
+ return (...args) => member.apply(obj, args.map(unwrap));
195
+ return (...args) => wrapper.result(member.apply(obj, args.map(unwrap)), prop);
196
+ }
197
+ void receiver;
198
+ return RAW_VALUE_MEMBERS.has(prop) ? member : wrapper.value(member, prop);
199
+ },
200
+ set(obj, prop, value) {
201
+ if (typeof prop === 'symbol')
202
+ return Reflect.set(obj, prop, value, obj);
203
+ if (!(prop in obj))
204
+ throw new NotSupportedError(className, prop);
205
+ return Reflect.set(obj, prop, unwrap(value), obj);
206
+ },
207
+ });
208
+ this.cache.set(target, proxy);
209
+ return proxy;
210
+ }
211
+ /** The result of a call: a promise becomes a ClientResult the next sync() fills. */
212
+ result(value, member) {
213
+ if (value instanceof ClientResult || !isThenable(value))
214
+ return this.value(value, member);
215
+ const result = new ClientResult(member);
216
+ const settled = value.then((resolved) => {
217
+ const wrapped = this.value(resolved, member);
218
+ result.resolveWith(wrapped);
219
+ return wrapped;
220
+ });
221
+ result.attach(settled);
222
+ this.context.enqueue(settled);
223
+ return result;
224
+ }
225
+ /** An array of views as an Office JS collection: the array, plus `items` and the getters. */
226
+ collection(items, member = '') {
227
+ var _a;
228
+ if (items.length > 0 && !items.every((i) => typeof i === 'object' && i !== null && isView(i)))
229
+ return items;
230
+ const itemClass = items.length > 0 ? items[0].constructor.name : ((_a = COLLECTION_ITEM_CLASS[member]) !== null && _a !== void 0 ? _a : 'Object');
231
+ const wrapped = items.map((i) => this.value(i, member));
232
+ const className = `${itemClass}Collection`;
233
+ const collection = wrapped;
234
+ const define = (name, value) => {
235
+ Object.defineProperty(collection, name, { value, enumerable: false, configurable: true, writable: true });
236
+ };
237
+ define(COLLECTION, true);
238
+ define('items', wrapped);
239
+ define('getFirst', () => {
240
+ if (wrapped.length === 0)
241
+ throw new ItemNotFoundError(`Word.${className} is empty; getFirst() found nothing (getFirstOrNullObject() does not throw)`);
242
+ return wrapped[0];
243
+ });
244
+ define('getFirstOrNullObject', () => (wrapped.length === 0 ? nullObject(itemClass) : wrapped[0]));
245
+ define('getLast', () => {
246
+ if (wrapped.length === 0)
247
+ throw new ItemNotFoundError(`Word.${className} is empty; getLast() found nothing (getLastOrNullObject() does not throw)`);
248
+ return wrapped[wrapped.length - 1];
249
+ });
250
+ define('getLastOrNullObject', () => (wrapped.length === 0 ? nullObject(itemClass) : wrapped[wrapped.length - 1]));
251
+ define('getCount', () => {
252
+ const result = new ClientResult('getCount');
253
+ result.resolveWith(wrapped.length);
254
+ return result;
255
+ });
256
+ define('load', () => collectionProxy);
257
+ define('track', () => collectionProxy);
258
+ define('untrack', () => collectionProxy);
259
+ const wrapperSelf = this;
260
+ const collectionProxy = new Proxy(collection, {
261
+ get(obj, prop) {
262
+ if (typeof prop === 'symbol')
263
+ return prop === RAW ? obj : Reflect.get(obj, prop, obj);
264
+ if (prop === 'then' && !(prop in obj))
265
+ return undefined;
266
+ if (prop === 'isNullObject')
267
+ return false;
268
+ if (!(prop in obj))
269
+ throw new NotSupportedError(className, prop);
270
+ const member2 = Reflect.get(obj, prop, obj);
271
+ if (typeof member2 === 'function' && !/^\d+$/.test(prop)) {
272
+ return (...args) => wrapperSelf.result(member2.apply(obj, args.map(unwrap)), prop);
273
+ }
274
+ return member2;
275
+ },
276
+ });
277
+ return collectionProxy;
278
+ }
279
+ }
@@ -0,0 +1,32 @@
1
+ import type { WordprocessingMLPackage } from '../packages/WordprocessingMLPackage.mjs';
2
+ import { Document, type RunOptions } from './document.mjs';
3
+ import { type PendingSink } from './proxy.mjs';
4
+ export type { RunOptions };
5
+ /** Office JS's `context.trackedObjects`: object lifetime is the garbage collector's business here. */
6
+ export interface TrackedObjects {
7
+ add<T>(object: T): T;
8
+ remove<T>(object: T): T;
9
+ }
10
+ /** A subset of Office JS `Word.RequestContext` over a package. */
11
+ export declare class RequestContext implements PendingSink {
12
+ /** The package this context is over (extension: Office JS has a host document). */
13
+ readonly package_: WordprocessingMLPackage;
14
+ readonly document: Document;
15
+ /** Tracking is a no-op: nothing here is a remote proxy. */
16
+ readonly trackedObjects: TrackedObjects;
17
+ private pending;
18
+ constructor(
19
+ /** The package this context is over (extension: Office JS has a host document). */
20
+ package_: WordprocessingMLPackage, options?: RunOptions);
21
+ /** @internal a promise whose result the next `sync()` must resolve. */
22
+ enqueue(promise: Promise<unknown>): void;
23
+ /** Resolves the pending results, filling every `ClientResult.value` handed out since the last sync. */
24
+ sync<T>(value?: T): Promise<T | RequestContext>;
25
+ }
26
+ /**
27
+ * Runs an add-in style callback against a package: `Word.run(pkg, async (context) => { ... })`.
28
+ * Office JS's `Word.run(batch)` takes the host document; there is none here, so the package comes
29
+ * first. The callback gets a proxied `RequestContext`; a final `sync()` resolves anything it left
30
+ * pending, and the callback's value is the result.
31
+ */
32
+ export declare function run<T>(pkg: WordprocessingMLPackage, batch: (context: RequestContext) => Promise<T> | T, options?: RunOptions): Promise<T>;
@@ -0,0 +1,66 @@
1
+ // `Word.run(pkg, fn)` and its RequestContext (CR-002 section 3.10).
2
+ //
3
+ // Office JS batches proxy calls and resolves them on `context.sync()`. Here the tree is in memory,
4
+ // so a call acts at once (CR-002 section 3.1) and `sync()` only resolves what was asynchronous:
5
+ // the marshalling and unmarshalling calls, whose `ClientResult.value` it fills. An add-in script
6
+ // written for Word therefore runs unchanged, `load` / `sync` lines and all.
7
+ import { Document } from './document.mjs';
8
+ import { EXTRA_MEMBERS } from './extras.mjs';
9
+ import { Wrapper, unwrap } from './proxy.mjs';
10
+ /** A subset of Office JS `Word.RequestContext` over a package. */
11
+ export class RequestContext {
12
+ constructor(
13
+ /** The package this context is over (extension: Office JS has a host document). */
14
+ package_, options = {}) {
15
+ this.package_ = package_;
16
+ /** Tracking is a no-op: nothing here is a remote proxy. */
17
+ this.trackedObjects = { add: (o) => o, remove: (o) => o };
18
+ this.pending = [];
19
+ this.document = new Document(package_, options);
20
+ }
21
+ /** @internal a promise whose result the next `sync()` must resolve. */
22
+ enqueue(promise) {
23
+ this.pending.push(promise);
24
+ }
25
+ /** Resolves the pending results, filling every `ClientResult.value` handed out since the last sync. */
26
+ async sync(value) {
27
+ while (this.pending.length > 0) {
28
+ const batch = this.pending;
29
+ this.pending = [];
30
+ await Promise.all(batch);
31
+ }
32
+ return value === undefined ? this : value;
33
+ }
34
+ }
35
+ /** Unmarshals what the document-level members read synchronously, as Office JS's host has already. */
36
+ async function prepare(pkg, options) {
37
+ const main = pkg.getMainDocumentPart();
38
+ await main.getContents();
39
+ if (options.unmarshalSideParts === false)
40
+ return;
41
+ const sideParts = [pkg.docPropsCorePart, pkg.docPropsExtendedPart, main.documentSettingsPart];
42
+ for (const part of sideParts) {
43
+ if (part && !part.isUnmarshalled) {
44
+ try {
45
+ await part.getContents();
46
+ }
47
+ catch {
48
+ // A side part that will not unmarshal is not worth failing the batch for; reads report nothing.
49
+ }
50
+ }
51
+ }
52
+ }
53
+ /**
54
+ * Runs an add-in style callback against a package: `Word.run(pkg, async (context) => { ... })`.
55
+ * Office JS's `Word.run(batch)` takes the host document; there is none here, so the package comes
56
+ * first. The callback gets a proxied `RequestContext`; a final `sync()` resolves anything it left
57
+ * pending, and the callback's value is the result.
58
+ */
59
+ export async function run(pkg, batch, options = {}) {
60
+ await prepare(pkg, options);
61
+ const context = new RequestContext(pkg, options);
62
+ const wrapper = new Wrapper(context, EXTRA_MEMBERS);
63
+ const result = await batch(wrapper.object(context, 'RequestContext'));
64
+ await context.sync();
65
+ return unwrap(result);
66
+ }
@@ -0,0 +1,7 @@
1
+ import { SUBSET_MEMBERS } from './supported.generated.mjs';
2
+ /**
3
+ * Every member this package implements, as `Class.member` (`'Body.insertParagraph'`). A member
4
+ * that is not here throws `NotSupportedError` when an add-in calls it through the shim.
5
+ */
6
+ export declare const supported: ReadonlySet<string>;
7
+ export { SUBSET_MEMBERS };
@@ -0,0 +1 @@
1
+ export declare const SUBSET_MEMBERS: readonly string[];
@@ -0,0 +1,235 @@
1
+ // Generated by scripts/generate-supported.mjs from test/office-js-subset.ts. Do not edit.
2
+ // Every member the Office JS subset declares, as `Class.member`: what this package implements
3
+ // of the Word API (CR-002 sections 3.4 and 3.10). Regenerate with `npm run generate`.
4
+ export const SUBSET_MEMBERS = [
5
+ 'Body.clear',
6
+ 'Body.contentControls',
7
+ 'Body.getComments',
8
+ 'Body.getTrackedChanges',
9
+ 'Body.inlinePictures',
10
+ 'Body.insertBreak',
11
+ 'Body.insertInlinePictureFromBase64',
12
+ 'Body.insertParagraph',
13
+ 'Body.insertTable',
14
+ 'Body.insertText',
15
+ 'Body.lists',
16
+ 'Body.paragraphs',
17
+ 'Body.search',
18
+ 'Body.tables',
19
+ 'Body.text',
20
+ 'CheckboxContentControl.isChecked',
21
+ 'Comment.authorEmail',
22
+ 'Comment.authorName',
23
+ 'Comment.content',
24
+ 'Comment.creationDate',
25
+ 'Comment.delete',
26
+ 'Comment.replies',
27
+ 'Comment.reply',
28
+ 'Comment.resolved',
29
+ 'ContentControl.appearance',
30
+ 'ContentControl.cannotDelete',
31
+ 'ContentControl.cannotEdit',
32
+ 'ContentControl.checkboxContentControl',
33
+ 'ContentControl.color',
34
+ 'ContentControl.comboBoxContentControl',
35
+ 'ContentControl.contentControls',
36
+ 'ContentControl.datePickerContentControl',
37
+ 'ContentControl.delete',
38
+ 'ContentControl.dropDownListContentControl',
39
+ 'ContentControl.getRange',
40
+ 'ContentControl.groupContentControl',
41
+ 'ContentControl.id',
42
+ 'ContentControl.insertParagraph',
43
+ 'ContentControl.insertText',
44
+ 'ContentControl.paragraphs',
45
+ 'ContentControl.pictureContentControl',
46
+ 'ContentControl.placeholderText',
47
+ 'ContentControl.removeWhenEdited',
48
+ 'ContentControl.repeatingSectionContentControl',
49
+ 'ContentControl.search',
50
+ 'ContentControl.tables',
51
+ 'ContentControl.tag',
52
+ 'ContentControl.text',
53
+ 'ContentControl.title',
54
+ 'ContentControl.type',
55
+ 'ContentControl.xmlMapping',
56
+ 'ContentControlListItem.delete',
57
+ 'ContentControlListItem.displayText',
58
+ 'ContentControlListItem.index',
59
+ 'ContentControlListItem.value',
60
+ 'CustomXmlNode.attributes',
61
+ 'CustomXmlNode.baseName',
62
+ 'CustomXmlNode.childNodes',
63
+ 'CustomXmlNode.delete',
64
+ 'CustomXmlNode.firstChild',
65
+ 'CustomXmlNode.hasChildNodes',
66
+ 'CustomXmlNode.insertNodeBefore',
67
+ 'CustomXmlNode.lastChild',
68
+ 'CustomXmlNode.namespaceUri',
69
+ 'CustomXmlNode.nextSibling',
70
+ 'CustomXmlNode.nodeType',
71
+ 'CustomXmlNode.nodeValue',
72
+ 'CustomXmlNode.ownerPart',
73
+ 'CustomXmlNode.parentNode',
74
+ 'CustomXmlNode.previousSibling',
75
+ 'CustomXmlNode.removeChild',
76
+ 'CustomXmlNode.replaceChildNode',
77
+ 'CustomXmlNode.selectNodes',
78
+ 'CustomXmlNode.selectSingleNode',
79
+ 'CustomXmlNode.text',
80
+ 'CustomXmlNode.xml',
81
+ 'CustomXmlNode.xpath',
82
+ 'CustomXmlPart.builtIn',
83
+ 'CustomXmlPart.delete',
84
+ 'CustomXmlPart.documentElement',
85
+ 'CustomXmlPart.getXml',
86
+ 'CustomXmlPart.id',
87
+ 'CustomXmlPart.namespaceManager',
88
+ 'CustomXmlPart.namespaceUri',
89
+ 'CustomXmlPart.schemaCollection',
90
+ 'CustomXmlPart.selectNodes',
91
+ 'CustomXmlPart.selectSingleNode',
92
+ 'CustomXmlPart.setXml',
93
+ 'CustomXmlPartCollection.add',
94
+ 'CustomXmlPartCollection.getByNamespace',
95
+ 'CustomXmlPartCollection.getItem',
96
+ 'CustomXmlPartCollection.items',
97
+ 'CustomXmlPrefixMappingCollection.addNamespace',
98
+ 'CustomXmlPrefixMappingCollection.items',
99
+ 'CustomXmlPrefixMappingCollection.lookupNamespace',
100
+ 'CustomXmlPrefixMappingCollection.lookupPrefix',
101
+ 'DatePickerContentControl.dateCalendarType',
102
+ 'DatePickerContentControl.dateDisplayFormat',
103
+ 'DatePickerContentControl.dateDisplayLocale',
104
+ 'DatePickerContentControl.dateStorageFormat',
105
+ 'Document.body',
106
+ 'Document.changeTrackingMode',
107
+ 'Document.getTrackedChanges',
108
+ 'Font.bold',
109
+ 'Font.color',
110
+ 'Font.highlightColor',
111
+ 'Font.italic',
112
+ 'Font.name',
113
+ 'Font.size',
114
+ 'Font.strikeThrough',
115
+ 'Font.subscript',
116
+ 'Font.superscript',
117
+ 'Font.underline',
118
+ 'InlinePicture.altTextDescription',
119
+ 'InlinePicture.altTextTitle',
120
+ 'InlinePicture.delete',
121
+ 'InlinePicture.getBase64ImageSrc',
122
+ 'InlinePicture.height',
123
+ 'InlinePicture.imageFormat',
124
+ 'InlinePicture.paragraph',
125
+ 'InlinePicture.width',
126
+ 'List.getLevelFont',
127
+ 'List.getLevelParagraphs',
128
+ 'List.getLevelString',
129
+ 'List.id',
130
+ 'List.insertParagraph',
131
+ 'List.levelExistences',
132
+ 'List.levelTypes',
133
+ 'List.paragraphs',
134
+ 'List.setLevelAlignment',
135
+ 'List.setLevelBullet',
136
+ 'List.setLevelIndents',
137
+ 'List.setLevelNumbering',
138
+ 'List.setLevelStartingNumber',
139
+ 'ListContentControl.addListItem',
140
+ 'ListContentControl.deleteAllListItems',
141
+ 'ListContentControl.listItems',
142
+ 'ListItem.getAncestor',
143
+ 'ListItem.getDescendants',
144
+ 'ListItem.level',
145
+ 'ListItem.listString',
146
+ 'ListItem.siblingIndex',
147
+ 'Paragraph.alignment',
148
+ 'Paragraph.attachToList',
149
+ 'Paragraph.delete',
150
+ 'Paragraph.detachFromList',
151
+ 'Paragraph.firstLineIndent',
152
+ 'Paragraph.font',
153
+ 'Paragraph.getComments',
154
+ 'Paragraph.getRange',
155
+ 'Paragraph.getTrackedChanges',
156
+ 'Paragraph.insertBreak',
157
+ 'Paragraph.insertComment',
158
+ 'Paragraph.insertParagraph',
159
+ 'Paragraph.insertText',
160
+ 'Paragraph.isListItem',
161
+ 'Paragraph.leftIndent',
162
+ 'Paragraph.lineSpacing',
163
+ 'Paragraph.list',
164
+ 'Paragraph.listItem',
165
+ 'Paragraph.listItemOrNullObject',
166
+ 'Paragraph.listOrNullObject',
167
+ 'Paragraph.outlineLevel',
168
+ 'Paragraph.rightIndent',
169
+ 'Paragraph.search',
170
+ 'Paragraph.spaceAfter',
171
+ 'Paragraph.spaceBefore',
172
+ 'Paragraph.startNewList',
173
+ 'Paragraph.style',
174
+ 'Paragraph.styleBuiltIn',
175
+ 'Paragraph.text',
176
+ 'PictureContentControl.inlinePicture',
177
+ 'Range.delete',
178
+ 'Range.font',
179
+ 'Range.getComments',
180
+ 'Range.getRange',
181
+ 'Range.getTrackedChanges',
182
+ 'Range.insertComment',
183
+ 'Range.insertParagraph',
184
+ 'Range.insertText',
185
+ 'Range.search',
186
+ 'Range.style',
187
+ 'Range.text',
188
+ 'RepeatingSectionContentControl.allowInsertDeleteSection',
189
+ 'RepeatingSectionContentControl.items',
190
+ 'RepeatingSectionContentControl.sectionTitle',
191
+ 'SearchOptions.matchCase',
192
+ 'SearchOptions.matchWholeWord',
193
+ 'SearchOptions.matchWildcards',
194
+ 'Table.addRows',
195
+ 'Table.delete',
196
+ 'Table.deleteRows',
197
+ 'Table.getCell',
198
+ 'Table.headerRowCount',
199
+ 'Table.rowCount',
200
+ 'Table.rows',
201
+ 'Table.style',
202
+ 'Table.styleBuiltIn',
203
+ 'Table.values',
204
+ 'TableCell.body',
205
+ 'TableCell.cellIndex',
206
+ 'TableCell.columnWidth',
207
+ 'TableCell.parentRow',
208
+ 'TableCell.parentTable',
209
+ 'TableCell.rowIndex',
210
+ 'TableCell.value',
211
+ 'TableCell.width',
212
+ 'TableRow.cellCount',
213
+ 'TableRow.cells',
214
+ 'TableRow.delete',
215
+ 'TableRow.insertRows',
216
+ 'TableRow.isHeader',
217
+ 'TableRow.parentTable',
218
+ 'TableRow.rowIndex',
219
+ 'TableRow.values',
220
+ 'TrackedChange.accept',
221
+ 'TrackedChange.author',
222
+ 'TrackedChange.date',
223
+ 'TrackedChange.getRange',
224
+ 'TrackedChange.reject',
225
+ 'TrackedChange.text',
226
+ 'TrackedChange.type',
227
+ 'XmlMapping.customXmlNode',
228
+ 'XmlMapping.customXmlPart',
229
+ 'XmlMapping.delete',
230
+ 'XmlMapping.isMapped',
231
+ 'XmlMapping.prefixMappings',
232
+ 'XmlMapping.setMapping',
233
+ 'XmlMapping.setMappingByNode',
234
+ 'XmlMapping.xpath',
235
+ ];
@@ -0,0 +1,53 @@
1
+ // `Word.supported`: the `Class.member` strings this package implements, so that a tool (CR-003's
2
+ // console, an agent writing a script) can check an add-in script before running it. The Office JS
3
+ // half is generated from `test/office-js-subset.ts`, which is the compile-time promise that those
4
+ // members exist and have Office JS's shape; the shim's own surface is listed here.
5
+ import { SUBSET_MEMBERS } from './supported.generated.mjs';
6
+ /** What every proxied object answers, whatever its class. */
7
+ const UNIVERSAL_MEMBERS = ['load', 'track', 'untrack', 'isNullObject', 'toJSON'];
8
+ /** The collection members the shim adds to an array of views. */
9
+ const COLLECTION_MEMBERS = ['items', 'getFirst', 'getFirstOrNullObject', 'getLast', 'getLastOrNullObject', 'getCount', 'length', ...UNIVERSAL_MEMBERS];
10
+ /** The classes a collection is of; phases C, E and G fill in the ones whose views are not here yet. */
11
+ const COLLECTION_CLASSES = ['Paragraph', 'Range', 'Table', 'TableRow', 'TableCell', 'ContentControl', 'Comment', 'InlinePicture', 'List', 'ListItem', 'Field', 'TrackedChange', 'CustomXmlPart'];
12
+ /** The shim's own members: the context, the document and what it adds over the views. */
13
+ const SHIM_MEMBERS = [
14
+ 'RequestContext.document', 'RequestContext.sync', 'RequestContext.trackedObjects', 'RequestContext.package_',
15
+ 'Document.body', 'Document.properties', 'Document.changeTrackingMode', 'Document.getSelection', 'Document.getComments',
16
+ 'Document.getOoxml', 'Document.save', 'Document.package_',
17
+ 'DocumentProperties.title', 'DocumentProperties.subject', 'DocumentProperties.author', 'DocumentProperties.comments',
18
+ 'DocumentProperties.keywords', 'DocumentProperties.category', 'DocumentProperties.lastAuthor', 'DocumentProperties.revisionNumber',
19
+ 'DocumentProperties.creationDate', 'DocumentProperties.lastSaveTime', 'DocumentProperties.lastPrintDate',
20
+ 'DocumentProperties.manager', 'DocumentProperties.company', 'DocumentProperties.applicationName', 'DocumentProperties.template',
21
+ 'DocumentProperties.security',
22
+ // over the views (src/office-js/extras.mts) and the extensions the views themselves offer
23
+ 'Body.getOoxml', 'Body.getXml', 'Body.insertXml', 'Body.insertElement', 'Body.content', 'Body.tables',
24
+ 'Body.paragraphAt', 'Body.elementAt', 'Body.addressOf', 'Body.outline', 'Body.getContent',
25
+ 'Paragraph.getOoxml', 'Paragraph.getXml', 'Paragraph.paraId', 'Paragraph.runs', 'Paragraph.element', 'Paragraph.p',
26
+ 'Paragraph.parentBody', 'Paragraph.index', 'Paragraph.splitAt', 'Paragraph.segments',
27
+ 'Range.getOoxml', 'Range.getXml', 'Range.runs', 'Range.paragraph', 'Range.paragraphs', 'Range.start', 'Range.end',
28
+ // lists (CR-002 phase H): the extensions beside the Office JS members the subset declares
29
+ 'Body.listLabels', 'Paragraph.restartList', 'Paragraph.numPr', 'Paragraph.pPr',
30
+ 'List.numId', 'List.definition', 'List.element', 'List.abstractElement', 'List.level',
31
+ 'List.levelExists', 'List.separate', 'List.restart', 'List.body',
32
+ 'ListItem.list', 'ListItem.paragraph',
33
+ ];
34
+ function build() {
35
+ const all = new Set(SUBSET_MEMBERS);
36
+ for (const className of new Set([...SUBSET_MEMBERS].map((m) => m.split('.')[0]))) {
37
+ for (const member of UNIVERSAL_MEMBERS)
38
+ all.add(`${className}.${member}`);
39
+ }
40
+ for (const member of SHIM_MEMBERS)
41
+ all.add(member);
42
+ for (const className of COLLECTION_CLASSES) {
43
+ for (const member of COLLECTION_MEMBERS)
44
+ all.add(`${className}Collection.${member}`);
45
+ }
46
+ return all;
47
+ }
48
+ /**
49
+ * Every member this package implements, as `Class.member` (`'Body.insertParagraph'`). A member
50
+ * that is not here throws `NotSupportedError` when an add-in calls it through the shim.
51
+ */
52
+ export const supported = build();
53
+ export { SUBSET_MEMBERS };