applescript-node 1.0.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.
@@ -0,0 +1,725 @@
1
+ import { ExprBuilder } from './expressions.js';
2
+ import type { AppleScriptValue, JsonObjectShape, ScriptBuilder } from './types.js';
3
+ export declare class AppleScriptBuilder implements ScriptBuilder {
4
+ private script;
5
+ private indentLevel;
6
+ private readonly INDENT;
7
+ private blockStack;
8
+ private getIndentation;
9
+ private escapeString;
10
+ private formatValue;
11
+ private makeRecord;
12
+ private validateBlockStack;
13
+ private pushBlock;
14
+ private popBlock;
15
+ private validateBlockType;
16
+ private addLine;
17
+ tell(target: string): this;
18
+ tellTarget(target: string): this;
19
+ tellProcess(processName: string): this;
20
+ on(handlerName: string, parameters?: string[]): this;
21
+ /**
22
+ * Define a handler using the 'to' syntax (alternative to 'on').
23
+ * Both 'on' and 'to' are equivalent in AppleScript.
24
+ * @param handlerName The name of the handler
25
+ * @param parameters Optional array of parameter names
26
+ * @returns This builder instance for method chaining
27
+ * @example
28
+ * .to('sayHello', ['name'])
29
+ * .displayDialog('Hello ' & name)
30
+ * .endto()
31
+ */
32
+ to(handlerName: string, parameters?: string[]): this;
33
+ /**
34
+ * Call/invoke a handler with parameters.
35
+ * @param handlerName The name of the handler to call
36
+ * @param parameters Optional array of parameter values
37
+ * @returns This builder instance for method chaining
38
+ * @example
39
+ * .callHandler('sayHello', ['"John"'])
40
+ * .callHandler('processFile', ['theFile', 'true'])
41
+ */
42
+ callHandler(handlerName: string, parameters?: string[]): this;
43
+ /**
44
+ * Call a handler from within a tell statement using 'my' keyword.
45
+ * Required when calling handlers from within tell blocks.
46
+ * @param handlerName The name of the handler to call
47
+ * @param parameters Optional array of parameter values
48
+ * @returns This builder instance for method chaining
49
+ * @example
50
+ * .tell('Finder')
51
+ * .my('processFile', ['theFile'])
52
+ * .endtell()
53
+ */
54
+ my(handlerName: string, parameters?: string[]): this;
55
+ /**
56
+ * Call a handler from within a tell statement using 'of me' syntax.
57
+ * Alternative to 'my' keyword for calling handlers from within tell blocks.
58
+ * @param handlerName The name of the handler to call
59
+ * @param parameters Optional array of parameter values
60
+ * @returns This builder instance for method chaining
61
+ * @example
62
+ * .tell('Finder')
63
+ * .ofMe('processFile', ['theFile'])
64
+ * .endtell()
65
+ */
66
+ ofMe(handlerName: string, parameters?: string[]): this;
67
+ /**
68
+ * Define a handler with labeled parameters (interleaved syntax).
69
+ * AppleScript supports splitting parameter names with colons and spaces.
70
+ * @param handlerName The name of the handler
71
+ * @param labeledParams Object with parameter labels and values
72
+ * @returns This builder instance for method chaining
73
+ * @example
74
+ * .onLabeled('displayError', { message: 'theErrorMessage', buttons: 'theButtons' })
75
+ * .displayDialog(theErrorMessage, { buttons: theButtons })
76
+ * .endon()
77
+ */
78
+ onLabeled(handlerName: string, labeledParams: Record<string, string>): this;
79
+ /**
80
+ * Define a handler with labeled parameters using 'to' syntax.
81
+ * @param handlerName The name of the handler
82
+ * @param labeledParams Object with parameter labels and values
83
+ * @returns This builder instance for method chaining
84
+ */
85
+ toLabeled(handlerName: string, labeledParams: Record<string, string>): this;
86
+ /**
87
+ * Define a 'run' event handler (implicit or explicit).
88
+ * The run handler is called when a script executes.
89
+ * @param explicit If true, explicitly define the run handler; if false, use implicit
90
+ * @returns This builder instance for method chaining
91
+ * @example
92
+ * .runHandler(true) // Explicit: on run ... end run
93
+ * .displayDialog('Script is running')
94
+ * .endrun()
95
+ */
96
+ runHandler(explicit?: boolean): this;
97
+ /**
98
+ * Define a 'quit' event handler.
99
+ * Called when a script app quits.
100
+ * @returns This builder instance for method chaining
101
+ * @example
102
+ * .quitHandler()
103
+ * .displayDialog('Script is quitting')
104
+ * .endquit()
105
+ */
106
+ quitHandler(): this;
107
+ /**
108
+ * Define an 'open' event handler for drag-and-drop support.
109
+ * Makes the script app drag-and-droppable.
110
+ * @param parameterName Name for the dropped items parameter (default: 'theDroppedItems')
111
+ * @returns This builder instance for method chaining
112
+ * @example
113
+ * .openHandler('theFiles')
114
+ * .repeatWith('aFile', 'theFiles')
115
+ * .displayDialog('Processing: ' & aFile)
116
+ * .endrepeat()
117
+ * .endopen()
118
+ */
119
+ openHandler(parameterName?: string): this;
120
+ /**
121
+ * Define an 'idle' event handler for stay-open applications.
122
+ * Called periodically in stay-open script apps.
123
+ * @param returnSeconds Number of seconds to wait before next idle call (default: 30)
124
+ * @returns This builder instance for method chaining
125
+ * @example
126
+ * .idleHandler(5) // Check every 5 seconds
127
+ * .displayDialog('Idle processing')
128
+ * .return(5) // Return 5 seconds for next idle
129
+ * .endidle()
130
+ */
131
+ idleHandler(_returnSeconds?: number): this;
132
+ end(): this;
133
+ /**
134
+ * Explicitly end an if block.
135
+ * Preferred over end() for clarity when working with multiple nested blocks.
136
+ */
137
+ endif(): this;
138
+ /**
139
+ * Explicitly end a repeat block.
140
+ * Preferred over end() for clarity when working with multiple nested blocks.
141
+ */
142
+ endrepeat(): this;
143
+ /**
144
+ * Explicitly end a try block.
145
+ * Preferred over end() for clarity when working with multiple nested blocks.
146
+ */
147
+ endtry(): this;
148
+ /**
149
+ * Explicitly end a tell block.
150
+ * Preferred over end() for clarity when working with multiple nested blocks.
151
+ */
152
+ endtell(): this;
153
+ /**
154
+ * Explicitly end an on handler block.
155
+ * Preferred over end() for clarity when working with multiple nested blocks.
156
+ */
157
+ endon(): this;
158
+ /**
159
+ * Explicitly end a considering block.
160
+ * Preferred over end() for clarity when working with multiple nested blocks.
161
+ */
162
+ endconsidering(): this;
163
+ /**
164
+ * Explicitly end an ignoring block.
165
+ * Preferred over end() for clarity when working with multiple nested blocks.
166
+ */
167
+ endignoring(): this;
168
+ /**
169
+ * Explicitly end a using block.
170
+ * Preferred over end() for clarity when working with multiple nested blocks.
171
+ */
172
+ endusing(): this;
173
+ /**
174
+ * Explicitly end a with block.
175
+ * Preferred over end() for clarity when working with multiple nested blocks.
176
+ */
177
+ endwith(): this;
178
+ /**
179
+ * Explicitly end a 'to' handler block.
180
+ * Preferred over end() for clarity when working with handlers.
181
+ */
182
+ endto(): this;
183
+ /**
184
+ * Explicitly end a 'run' handler block.
185
+ * Preferred over end() for clarity when working with run handlers.
186
+ */
187
+ endrun(): this;
188
+ /**
189
+ * Explicitly end a 'quit' handler block.
190
+ * Preferred over end() for clarity when working with quit handlers.
191
+ */
192
+ endquit(): this;
193
+ /**
194
+ * Explicitly end an 'open' handler block.
195
+ * Preferred over end() for clarity when working with open handlers.
196
+ */
197
+ endopen(): this;
198
+ /**
199
+ * Explicitly end an 'idle' handler block.
200
+ * Preferred over end() for clarity when working with idle handlers.
201
+ */
202
+ endidle(): this;
203
+ if(condition: string | ((expr: ExprBuilder) => string)): this;
204
+ thenBlock(): this;
205
+ else(): this;
206
+ elseIf(condition: string): this;
207
+ repeat(times?: number): this;
208
+ repeatWith(variable: string, list: string): this;
209
+ repeatUntil(condition: string): this;
210
+ repeatWhile(condition: string): this;
211
+ repeatWithRange(variable: string, start: number | string, end: number | string): this;
212
+ exitRepeat(): this;
213
+ exitRepeatIf(condition: string | ((expr: ExprBuilder) => string)): this;
214
+ continueRepeat(): this;
215
+ considering(attributes: string[]): this;
216
+ ignoring(attributes: string[]): this;
217
+ using(terms: string[]): this;
218
+ with(timeout?: number, transaction?: boolean): this;
219
+ try(): this;
220
+ onError(variableName?: string): this;
221
+ error(message: string, number?: number): this;
222
+ return(value: AppleScriptValue): this;
223
+ returnRaw(expression: string): this;
224
+ /**
225
+ * Build a JSON object string from AppleScript variables.
226
+ * Generates clean, readable JSON without manual string concatenation.
227
+ *
228
+ * @param variableMap Mapping of JSON keys to AppleScript variable names
229
+ * @returns AppleScript expression that evaluates to a JSON string
230
+ *
231
+ * @example
232
+ * // Instead of manual string building:
233
+ * // '"{" & "\\"name\\":\\"" & winName & "\\"}" '
234
+ *
235
+ * // Use:
236
+ * const jsonExpr = builder.buildJsonObject({
237
+ * name: 'winName',
238
+ * position: 'winPosition',
239
+ * size: 'winSize'
240
+ * });
241
+ * builder.returnRaw(jsonExpr);
242
+ *
243
+ * // Generates: '{"name":"Calculator","position":"100,200","size":"800x600"}'
244
+ */
245
+ buildJsonObject(variableMap: Record<string, string>): string;
246
+ /**
247
+ * Build and return a JSON object from AppleScript variables.
248
+ * Convenience method that combines buildJsonObject() with returnRaw().
249
+ *
250
+ * @param variableMap Mapping of JSON keys to AppleScript variable names
251
+ *
252
+ * @example
253
+ * .setExpression('winName', 'name of window 1')
254
+ * .setExpression('winPosition', 'position of window 1 as text')
255
+ * .returnJsonObject({
256
+ * name: 'winName',
257
+ * position: 'winPosition'
258
+ * })
259
+ */
260
+ returnJsonObject<TProperties extends Record<string, string>>(variableMap: TProperties): ScriptBuilder<never, JsonObjectShape<TProperties>>;
261
+ /**
262
+ * Ultra-convenient shorthand for the common "map collection to JSON" pattern.
263
+ * Replaces verbose manual iteration, property extraction, and JSON conversion.
264
+ *
265
+ * This single method handles:
266
+ * - Creating temporary collection list
267
+ * - Iterating through items (with optional limit/condition)
268
+ * - Extracting properties with smart detection (simple vs complex expressions)
269
+ * - Field-level transformations (firstOf, ifExists, type conversion)
270
+ * - Error handling (skip failed items)
271
+ * - JSON serialization and return
272
+ *
273
+ * @param itemVariable Loop variable name (e.g., 'aNote')
274
+ * @param collection Collection to iterate (e.g., 'every note')
275
+ * @param properties Mapping of JSON keys to AppleScript properties or PropertyExtractor objects
276
+ * @param options Optional: limit, until/while conditions, error handling
277
+ *
278
+ * @example
279
+ * // Simple properties
280
+ * .tell('Notes')
281
+ * .mapToJson('aNote', 'every note', {
282
+ * id: 'id',
283
+ * name: 'name',
284
+ * content: 'plaintext',
285
+ * created: 'creation date of aNote as string',
286
+ * }, { limit: 10, skipErrors: true })
287
+ * .endtell()
288
+ *
289
+ * @example
290
+ * // Advanced field extractors (NEW!)
291
+ * .tell('Contacts')
292
+ * .mapToJson('aPerson', 'every person', {
293
+ * id: 'id',
294
+ * name: 'name',
295
+ * email: { property: (e) => e.property('aPerson', 'emails'), firstOf: true },
296
+ * phone: { property: 'phones', firstOf: true },
297
+ * birthday: { property: 'birth date', ifExists: true, asType: 'string' },
298
+ * }, { limit: 50, skipErrors: true })
299
+ * .endtell()
300
+ */
301
+ mapToJson<TProperties extends Record<string, string | {
302
+ readonly property?: string | ((e: ExprBuilder) => string);
303
+ readonly firstOf?: boolean;
304
+ readonly ifExists?: boolean;
305
+ readonly asType?: string;
306
+ readonly default?: string | ((e: ExprBuilder) => string);
307
+ }>>(itemVariable: string, collection: string, properties: TProperties, options?: {
308
+ limit?: number;
309
+ until?: string | ((expr: ExprBuilder) => string);
310
+ while?: string | ((expr: ExprBuilder) => string);
311
+ skipErrors?: boolean;
312
+ }): ScriptBuilder<never, JsonObjectShape<TProperties>[]>;
313
+ /**
314
+ * Return a list of records as a JSON string.
315
+ * Converts AppleScript records to JSON format by manually building the JSON string.
316
+ * Handles proper escaping of strings, booleans, numbers, and null values.
317
+ * @param listVariable Name of the variable containing a list of records
318
+ * @param propertyMap Mapping of JSON keys to AppleScript property names (e.g., {id: 'noteId', name: 'noteName'})
319
+ */
320
+ returnAsJson<TProperties extends Record<string, string>>(listVariable: string, propertyMap: TProperties): ScriptBuilder<never, JsonObjectShape<TProperties>[]>;
321
+ log(message: string): this;
322
+ comment(text: string): this;
323
+ activate(): this;
324
+ quit(): this;
325
+ reopen(): this;
326
+ launch(): this;
327
+ running(): this;
328
+ closeWindow(window?: string): this;
329
+ closeAllWindows(): this;
330
+ minimizeWindow(window?: string): this;
331
+ zoomWindow(window?: string): this;
332
+ click(target: string): this;
333
+ select(target: string): this;
334
+ keystroke(text: string, modifiers?: string[]): this;
335
+ /**
336
+ * Type multiple characters with automatic delays between each keystroke.
337
+ * Convenient shorthand for typing sequences like numbers or text.
338
+ * @param text String of characters to type (each character gets a separate keystroke)
339
+ * @param delayBetween Delay in seconds between each keystroke (default: 0.1)
340
+ * @example
341
+ * // Instead of:
342
+ * // .keystroke('1').delay(0.1).keystroke('2').delay(0.1).keystroke('3')
343
+ * // Use:
344
+ * // .keystrokes('123')
345
+ */
346
+ keystrokes(text: string, delayBetween?: number): this;
347
+ delay(seconds: number): this;
348
+ displayDialog(text: string, options?: {
349
+ buttons?: string[];
350
+ defaultButton?: string;
351
+ withIcon?: 'stop' | 'note' | 'caution';
352
+ givingUpAfter?: number;
353
+ }): ScriptBuilder;
354
+ displayNotification(text: string, options?: {
355
+ title?: string;
356
+ subtitle?: string;
357
+ sound?: string;
358
+ }): ScriptBuilder;
359
+ set<TNewVar extends string>(variable: TNewVar, value: AppleScriptValue): ScriptBuilder<TNewVar>;
360
+ setExpression<TNewVar extends string>(variable: TNewVar, expression: string | Record<string, string> | ((expr: ExprBuilder) => string)): ScriptBuilder<TNewVar>;
361
+ setExpressions(expressions: Record<string, string | ((expr: ExprBuilder) => string)>): this;
362
+ appendTo(variable: string, expression: string | ((expr: ExprBuilder) => string), options?: {
363
+ prependLinefeed?: boolean;
364
+ appendLinefeed?: boolean;
365
+ }): this;
366
+ increment(variable: string, by?: number): this;
367
+ decrement(variable: string, by?: number): this;
368
+ get(property: string): this;
369
+ copy<TNewVar extends string>(value: AppleScriptValue, to: TNewVar): ScriptBuilder<TNewVar>;
370
+ count(items: string): this;
371
+ setCountOf<TNewVar extends string>(variable: TNewVar, items: string): ScriptBuilder<TNewVar>;
372
+ exists(item: string): this;
373
+ setEnd(variable: string, value: AppleScriptValue): this;
374
+ setEndRaw(variable: string, expression: string | Record<string, string> | ((expr: ExprBuilder) => string)): this;
375
+ setEndRecord(listVariable: string, sourceOrExpressions: string | Record<string, string>, propertyMap?: Record<string, string>): this;
376
+ /**
377
+ * Intuitive shorthand for picking properties from a source object and building a record.
378
+ * Automatically detects full expressions vs simple property names:
379
+ * - Simple properties (no special keywords) get "of source" appended
380
+ * - Complex expressions (with 'of', 'as', 'where', etc.) are used as-is
381
+ *
382
+ * @param listVariable Name of the list to append the record to
383
+ * @param sourceObject Name of the source object to extract properties from
384
+ * @param propertyMap Mapping of record keys to property names/expressions
385
+ *
386
+ * @example
387
+ * // Mix simple properties and complex expressions
388
+ * .pickEndRecord('notesList', 'aNote', {
389
+ * noteId: 'id', // => id of aNote
390
+ * noteName: 'name', // => name of aNote
391
+ * noteCreated: 'creation date of aNote as string', // used as-is (has 'as')
392
+ * noteModified: 'modification date as string', // used as-is (has 'as')
393
+ * })
394
+ */
395
+ pickEndRecord(listVariable: string, sourceObject: string, propertyMap: Record<string, string>): this;
396
+ /**
397
+ * Set variable using ternary operator pattern with if-then-else block.
398
+ * Much more concise than manually calling ifThenElse for simple conditional assignments.
399
+ *
400
+ * Generates an if-then-else block that sets the variable conditionally.
401
+ *
402
+ * @param variable - Variable name to set
403
+ * @param condition - Condition to evaluate (string or ExprBuilder callback)
404
+ * @param trueExpression - Expression to use if condition is true
405
+ * @param falseExpression - Expression to use if condition is false
406
+ *
407
+ * @example
408
+ * // With ExprBuilder for type-safe conditions
409
+ * .setTernary('personEmail',
410
+ * (e) => e.gt(e.count(e.property('aPerson', 'emails')), 0),
411
+ * (e) => e.valueOfItem(1, e.property('aPerson', 'emails')),
412
+ * 'missing value'
413
+ * )
414
+ *
415
+ * @example
416
+ * // With strings
417
+ * .setTernary('status',
418
+ * 'count of items > 0',
419
+ * '"active"',
420
+ * '"empty"'
421
+ * )
422
+ *
423
+ * @example
424
+ * // Replaces verbose ifThenElse:
425
+ * // .ifThenElse(
426
+ * // (e) => e.gt('x', 10),
427
+ * // (then_) => then_.set('result', 'high'),
428
+ * // (else_) => else_.set('result', 'low')
429
+ * // )
430
+ * // With concise ternary:
431
+ * .setTernary('result', (e) => e.gt('x', 10), '"high"', '"low"')
432
+ */
433
+ setTernary<TNewVar extends string>(variable: TNewVar, condition: string | ((e: ExprBuilder) => string), trueExpression: string | ((e: ExprBuilder) => string), falseExpression: string | ((e: ExprBuilder) => string)): ScriptBuilder<TNewVar>;
434
+ /**
435
+ * Append to list using ternary operator pattern with if-then-else block.
436
+ * Combines setEndRaw with conditional logic for ultra-concise syntax.
437
+ *
438
+ * Generates an if-then-else block that conditionally appends to the list.
439
+ *
440
+ * @param listVariable - Name of the list to append to
441
+ * @param condition - Condition to evaluate (string or ExprBuilder callback)
442
+ * @param trueExpression - Expression to append if condition is true
443
+ * @param falseExpression - Expression to append if condition is false
444
+ *
445
+ * @example
446
+ * // Conditionally append different values
447
+ * .set('results', [])
448
+ * .forEach('item', 'every file of desktop', (loop) =>
449
+ * loop.setEndTernary('results',
450
+ * (e) => e.gt(e.property('item', 'size'), 1000000),
451
+ * '"large"',
452
+ * '"small"'
453
+ * )
454
+ * )
455
+ *
456
+ * @example
457
+ * // With complex expressions
458
+ * .setEndTernary('emails',
459
+ * 'count of email addresses of person > 0',
460
+ * 'value of item 1 of email addresses of person',
461
+ * 'missing value'
462
+ * )
463
+ */
464
+ setEndTernary(listVariable: string, condition: string | ((e: ExprBuilder) => string), trueExpression: string | ((e: ExprBuilder) => string), falseExpression: string | ((e: ExprBuilder) => string)): ScriptBuilder;
465
+ /**
466
+ * Set variable to first item of collection or default value if collection is empty.
467
+ * Ultra-shorthand for the common "first or default" pattern.
468
+ *
469
+ * Automatically generates an if-then-else block that checks the collection count and sets the variable accordingly.
470
+ *
471
+ * @template TNewVar - The variable name (inferred from first parameter)
472
+ * @param variable - Variable name to set (will be added to scope)
473
+ * @param collection - Collection expression to get first item from
474
+ * @param defaultValue - Value to use if collection is empty (default: 'missing value')
475
+ *
476
+ * @example
477
+ * // Get first email or missing value
478
+ * .setFirstOf('personEmail', (e) => e.property('aPerson', 'emails'))
479
+ *
480
+ * @example
481
+ * // Get first email or custom default
482
+ * .setFirstOf('personEmail', (e) => e.property('aPerson', 'emails'), '"no-email@example.com"')
483
+ *
484
+ * @example
485
+ * // With string expression
486
+ * .setFirstOf('personEmail', 'emails of aPerson', 'missing value')
487
+ *
488
+ * @example
489
+ * // Replaces verbose pattern:
490
+ * // .setTernary('personEmail',
491
+ * // (e) => e.gt(e.count(e.property('aPerson', 'emails')), 0),
492
+ * // (e) => e.valueOfItem(1, e.property('aPerson', 'emails')),
493
+ * // 'missing value'
494
+ * // )
495
+ */
496
+ setFirstOf<TNewVar extends string>(variable: TNewVar, collection: string | ((e: ExprBuilder) => string), defaultValue?: string | ((e: ExprBuilder) => string)): ScriptBuilder<TNewVar>;
497
+ /**
498
+ * Append first item of collection or default value to a list.
499
+ * Ultra-shorthand for the common "first or default" pattern in list building.
500
+ *
501
+ * Automatically generates an if-then-else block that checks the collection count and appends to the list accordingly.
502
+ *
503
+ * @param listVariable - Name of the list to append to
504
+ * @param collection - Collection expression to get first item from
505
+ * @param defaultValue - Value to use if collection is empty (default: 'missing value')
506
+ *
507
+ * @example
508
+ * // Build list of first emails
509
+ * .forEach('person', 'every person', (loop) =>
510
+ * loop.setEndFirstOf('emails', (e) => e.property('person', 'email addresses'))
511
+ * )
512
+ *
513
+ * @example
514
+ * // With custom default
515
+ * .setEndFirstOf('results', 'items of record', '""')
516
+ */
517
+ setEndFirstOf(listVariable: string, collection: string | ((e: ExprBuilder) => string), defaultValue?: string | ((e: ExprBuilder) => string)): ScriptBuilder;
518
+ /**
519
+ * Set variable to property value if it exists, otherwise use default value.
520
+ * Ultra-shorthand for the common "take if exists or default" pattern.
521
+ *
522
+ * Automatically generates an if-then-else block that checks if the property exists
523
+ * and sets the variable accordingly, with optional type conversion.
524
+ *
525
+ * @template TNewVar - The variable name (inferred from first parameter)
526
+ * @param variable - Variable name to set (will be added to scope)
527
+ * @param property - Property expression to check and retrieve
528
+ * @param defaultValue - Value to use if property doesn't exist (default: 'missing value')
529
+ * @param asType - Optional type to convert property to (e.g., 'string', 'integer')
530
+ *
531
+ * @example
532
+ * // Get birth date as string or missing value
533
+ * .setIfExists('personBirthday',
534
+ * (e) => e.property('aPerson', 'birth date'),
535
+ * 'missing value',
536
+ * 'string'
537
+ * )
538
+ *
539
+ * @example
540
+ * // Simpler syntax with string expression
541
+ * .setIfExists('personBirthday', 'birth date of aPerson', 'missing value', 'string')
542
+ *
543
+ * @example
544
+ * // Without type conversion
545
+ * .setIfExists('personNote', 'note of aPerson', '""')
546
+ *
547
+ * @example
548
+ * // Replaces verbose pattern:
549
+ * // .setTernary('personBirthday',
550
+ * // (e) => e.exists(e.property('aPerson', 'birth date')),
551
+ * // (e) => e.asType(e.property('aPerson', 'birth date'), 'string'),
552
+ * // 'missing value'
553
+ * // )
554
+ */
555
+ setIfExists<TNewVar extends string>(variable: TNewVar, property: string | ((e: ExprBuilder) => string), defaultValue?: string | ((e: ExprBuilder) => string), asType?: string): ScriptBuilder<TNewVar>;
556
+ /**
557
+ * Append property value to list if it exists, otherwise append default value.
558
+ * Ultra-shorthand for the common "take if exists or default" pattern in list building.
559
+ *
560
+ * Automatically generates an if-then-else block that checks if the property exists
561
+ * and appends to the list accordingly, with optional type conversion.
562
+ *
563
+ * @param listVariable - Name of the list to append to
564
+ * @param property - Property expression to check and retrieve
565
+ * @param defaultValue - Value to use if property doesn't exist (default: 'missing value')
566
+ * @param asType - Optional type to convert property to (e.g., 'string', 'integer')
567
+ *
568
+ * @example
569
+ * // Build list of birth dates
570
+ * .forEach('person', 'every person', (loop) =>
571
+ * loop.setEndIfExists('dates', 'birth date of person', '""', 'string')
572
+ * )
573
+ *
574
+ * @example
575
+ * // With ExprBuilder
576
+ * .setEndIfExists('notes',
577
+ * (e) => e.property('contact', 'note'),
578
+ * 'missing value'
579
+ * )
580
+ */
581
+ setEndIfExists(listVariable: string, property: string | ((e: ExprBuilder) => string), defaultValue?: string | ((e: ExprBuilder) => string), asType?: string): ScriptBuilder;
582
+ setProperty(variable: string, property: string, value: AppleScriptValue): this;
583
+ makeRecordFrom(variableNames: Record<string, string>): string;
584
+ first(items: string): this;
585
+ last(items: string): this;
586
+ rest(items: string): this;
587
+ reverse(items: string): this;
588
+ some(items: string, test: string): this;
589
+ every(items: string, test: string): this;
590
+ whose(items: string, condition: string): string;
591
+ getEvery(itemType: string, location?: string): this;
592
+ getEveryWhere(itemType: string, condition: string, location?: string): this;
593
+ offset(text: string, in_: string): this;
594
+ contains(text: string, in_: string): this;
595
+ beginsWith(text: string, with_: string): this;
596
+ endsWith(text: string, with_: string): this;
597
+ path(to: string): this;
598
+ info(for_: string): this;
599
+ do(script: string): this;
600
+ doShellScript(command: string, administrator?: boolean): this;
601
+ raw(script: string): this;
602
+ getRunningApplications(): this;
603
+ getFrontmostApplication(): this;
604
+ activateApplication(appName: string): this;
605
+ hideApplication(appName: string): this;
606
+ unhideApplication(appName: string): this;
607
+ quitApplication(appName: string): this;
608
+ isApplicationRunning(appName: string): this;
609
+ getApplicationInfo(appName: string): this;
610
+ getWindowInfo(appName: string, windowName?: string): this;
611
+ getAllWindows(appName: string): this;
612
+ getFrontmostWindow(appName: string): this;
613
+ setWindowBounds(appName: string, windowName: string, bounds: {
614
+ x: number;
615
+ y: number;
616
+ width: number;
617
+ height: number;
618
+ }): this;
619
+ moveWindow(appName: string, windowName: string, x: number, y: number): this;
620
+ resizeWindow(appName: string, windowName: string, width: number, height: number): this;
621
+ arrangeWindows(arrangement: 'cascade' | 'tile' | 'stack'): this;
622
+ focusWindow(appName: string, windowName: string): this;
623
+ switchToWindow(appName: string, windowName: string): this;
624
+ pressKey(key: string, modifiers?: ('command' | 'option' | 'control' | 'shift')[]): this;
625
+ pressKeyCode(keyCode: number, modifiers?: ('command' | 'option' | 'control' | 'shift')[]): this;
626
+ typeText(text: string): this;
627
+ clickButton(buttonName: string): this;
628
+ clickMenuItem(menuName: string, itemName: string): this;
629
+ /**
630
+ * Simplified tell application pattern with automatic block closing.
631
+ * Cleaner than manually calling tell()...end().
632
+ * @param appName Name of the application to tell
633
+ * @param block Callback that builds commands for the application
634
+ */
635
+ tellApp(appName: string, block: (builder: ScriptBuilder) => void): this;
636
+ /**
637
+ * Simplified if-then pattern that automatically closes the if block.
638
+ * Cleaner than manually calling if()...thenBlock()...endif().
639
+ * @param condition The condition to check (string or ExprBuilder callback)
640
+ * @param thenBlock Callback that builds the then branch
641
+ */
642
+ ifThen(condition: string | ((expr: ExprBuilder) => string), thenBlock: (builder: ScriptBuilder) => void): this;
643
+ /**
644
+ * Simplified if-then-else pattern that automatically closes the if block.
645
+ * Cleaner than manually calling if()...thenBlock()...else()...endif().
646
+ * @param condition The condition to check (string or ExprBuilder callback)
647
+ * @param thenBlock Callback that builds the then branch
648
+ * @param elseBlock Callback that builds the else branch
649
+ */
650
+ ifThenElse(condition: string | ((expr: ExprBuilder) => string), thenBlock: (builder: ScriptBuilder) => void, elseBlock: (builder: ScriptBuilder) => void): this;
651
+ /**
652
+ * Simplified try-catch pattern that automatically closes the try block.
653
+ * Cleaner than manually calling try()...onError()...endtry().
654
+ * @param tryBlock Callback that builds the try branch
655
+ * @param catchBlock Callback that builds the on error branch
656
+ */
657
+ tryCatch(tryBlock: (builder: ScriptBuilder) => void, catchBlock: (builder: ScriptBuilder) => void): this;
658
+ /**
659
+ * Simplified try-catch pattern with error variable capture.
660
+ * @param tryBlock Callback that builds the try branch
661
+ * @param errorVarName Name of the variable to capture the error
662
+ * @param catchBlock Callback that builds the on error branch
663
+ */
664
+ tryCatchError(tryBlock: (builder: ScriptBuilder) => void, errorVarName: string, catchBlock: (builder: ScriptBuilder) => void): this;
665
+ /**
666
+ * Iterate over items with automatic block closing.
667
+ * More intuitive name for repeatWith that uses callback pattern.
668
+ * @param variable Loop variable name
669
+ * @param list Expression for the list to iterate (e.g., 'every note')
670
+ * @param block Callback that builds the loop body
671
+ */
672
+ forEach<TNewVar extends string>(variable: TNewVar, list: string, block: (builder: ScriptBuilder<TNewVar>) => void): this;
673
+ /**
674
+ * Iterate over items while a condition is true.
675
+ * Combines forEach with an early exit condition for cleaner syntax.
676
+ * @param variable Loop variable name
677
+ * @param list Expression for the list to iterate (e.g., 'every note')
678
+ * @param condition Condition to check before each iteration (continues while true)
679
+ * @param block Callback that builds the loop body
680
+ */
681
+ forEachWhile<TNewVar extends string>(variable: TNewVar, list: string, condition: string | ((expr: ExprBuilder<TNewVar>) => string), block: (builder: ScriptBuilder<TNewVar>) => void): this;
682
+ /**
683
+ * Iterate over items until a condition becomes true.
684
+ * Combines forEach with an early exit condition for cleaner syntax.
685
+ * @param variable Loop variable name
686
+ * @param list Expression for the list to iterate (e.g., 'every note')
687
+ * @param condition Condition to check before each iteration (exits when true)
688
+ * @param block Callback that builds the loop body
689
+ */
690
+ forEachUntil<TNewVar extends string>(variable: TNewVar, list: string, condition: string | ((expr: ExprBuilder<TNewVar>) => string), block: (builder: ScriptBuilder<TNewVar>) => void): this;
691
+ /**
692
+ * Repeat a fixed number of times with automatic block closing.
693
+ * @param times Number of times to repeat
694
+ * @param block Callback that builds the loop body
695
+ */
696
+ repeatTimes(times: number, block: (builder: ScriptBuilder) => void): this;
697
+ /**
698
+ * Repeat while condition is true with automatic block closing.
699
+ * @param condition Condition to check (continues while true)
700
+ * @param block Callback that builds the loop body
701
+ */
702
+ repeatWhileBlock(condition: string, block: (builder: ScriptBuilder) => void): this;
703
+ /**
704
+ * Repeat until condition is true with automatic block closing.
705
+ * @param condition Condition to check (continues until true)
706
+ * @param block Callback that builds the loop body
707
+ */
708
+ repeatUntilBlock(condition: string, block: (builder: ScriptBuilder) => void): this;
709
+ /**
710
+ * Load an existing AppleScript into the builder, preserving its structure.
711
+ * Parses the script to detect block structure (tell, if, repeat, etc.) and
712
+ * maintains proper nesting so you can continue editing with the builder API.
713
+ * @param script The AppleScript source code to load
714
+ * @returns This builder instance for method chaining
715
+ */
716
+ loadFromScript(script: string): this;
717
+ /**
718
+ * Helper method to extract the target from a tell statement.
719
+ * @param line The tell statement line
720
+ * @returns The extracted target or undefined
721
+ */
722
+ private extractTarget;
723
+ build(): string;
724
+ reset(): this;
725
+ }