@maka/maka-cli 5.7.0 → 5.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/typescript/package.json +1 -1
- package/bundle/typescript/src/commands/deploy/ubuntu.sub.cmd.js +16 -31
- package/bundle/typescript/src/commands/deploy/ubuntu.sub.cmd.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/archetypes.js +6 -4
- package/bundle/typescript/src/commands/game/sideQuest/archetypes.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/advance.js +3 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/advance.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/ask.js +19 -7
- package/bundle/typescript/src/commands/game/sideQuest/commands/ask.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/assense.js +3 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/assense.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/attack.js +35 -9
- package/bundle/typescript/src/commands/game/sideQuest/commands/attack.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.js +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/buy.js +2 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/buy.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/bypass-command.js +31 -4
- package/bundle/typescript/src/commands/game/sideQuest/commands/bypass-command.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/call.js +16 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/call.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/cast.d.ts +7 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/cast.js +118 -29
- package/bundle/typescript/src/commands/game/sideQuest/commands/cast.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/companions.d.ts +33 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/companions.js +138 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/companions.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/contacts.js +2 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/contacts.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/equip.js +5 -4
- package/bundle/typescript/src/commands/game/sideQuest/commands/equip.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/equipment.js +2 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/equipment.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/give.js +5 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/give.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/go.d.ts +6 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/go.js +138 -19
- package/bundle/typescript/src/commands/game/sideQuest/commands/go.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/grapple.d.ts +38 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/grapple.js +178 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/grapple.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js +14 -5
- package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/haggle.js +7 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/haggle.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/hints.d.ts +10 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/hints.js +24 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/hints.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/initiate.js +2 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/initiate.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/inv.js +2 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/inv.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/jump.js +25 -3
- package/bundle/typescript/src/commands/game/sideQuest/commands/jump.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/lifestyle.js +2 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/lifestyle.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/look.js +53 -8
- package/bundle/typescript/src/commands/game/sideQuest/commands/look.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/map.js +3 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/map.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/move.d.ts +41 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/move.js +160 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/move.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/order.d.ts +19 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/order.js +152 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/order.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/persuade.js +5 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/persuade.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/pick.js +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/pick.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/project.js +2 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/project.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/quality-trade.js +2 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/quality-trade.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/rest.js +3 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/rest.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/say.js +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/say.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/search.js +24 -6
- package/bundle/typescript/src/commands/game/sideQuest/commands/search.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/sell.js +7 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/sell.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/silent.js +2 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/silent.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/sneak.js +3 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/sneak.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/solve.js +11 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/solve.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/spells.js +24 -13
- package/bundle/typescript/src/commands/game/sideQuest/commands/spells.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/summon.d.ts +19 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/summon.js +113 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/summon.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/surrender.js +4 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/surrender.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/take.js +37 -4
- package/bundle/typescript/src/commands/game/sideQuest/commands/take.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/talk.js +6 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/talk.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/treat.js +5 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/treat.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/unlock.js +9 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/unlock.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/work.js +2 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/work.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/item-factory.js +2 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/item-factory.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/puzzle-factory.js +2 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/puzzle-factory.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/room-factory.js +5 -0
- package/bundle/typescript/src/commands/game/sideQuest/factories/room-factory.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.d.ts +11 -0
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js +138 -23
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js +12 -0
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/game.d.ts +91 -0
- package/bundle/typescript/src/commands/game/sideQuest/game.js +501 -23
- package/bundle/typescript/src/commands/game/sideQuest/game.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/item.d.ts +2 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/item.js +3 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/item.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.d.ts +44 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.js +349 -9
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/player.d.ts +10 -2
- package/bundle/typescript/src/commands/game/sideQuest/models/player.js +36 -7
- package/bundle/typescript/src/commands/game/sideQuest/models/player.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.d.ts +2 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.js +9 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/room.d.ts +13 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/room.js +57 -4
- package/bundle/typescript/src/commands/game/sideQuest/models/room.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/scene.d.ts +28 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/scene.js +172 -4
- package/bundle/typescript/src/commands/game/sideQuest/models/scene.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/scenes/scene1.json +76 -20
- package/bundle/typescript/src/commands/game/sideQuest/scenes/scene2.json +157 -34
- package/bundle/typescript/src/commands/game/sideQuest/types/seed/exit-seed.d.ts +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/seed/item-seed.d.ts +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/seed/player-seed.d.ts +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/seed/puzzle-seed.d.ts +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/seed/room-seed.d.ts +6 -0
- package/bundle/typescript/src/commands/game/sideQuest/ui.js +81 -5
- package/bundle/typescript/src/commands/game/sideQuest/ui.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/auto-fight.js +21 -5
- package/bundle/typescript/src/commands/game/sideQuest/utilities/auto-fight.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.d.ts +25 -3
- package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js +128 -28
- package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/dice.d.ts +7 -4
- package/bundle/typescript/src/commands/game/sideQuest/utilities/dice.js +8 -5
- package/bundle/typescript/src/commands/game/sideQuest/utilities/dice.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/grapple.d.ts +36 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/grapple.js +57 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/grapple.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/hints.d.ts +4 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/hints.js +55 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/hints.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/log-style.d.ts +14 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/log-style.js +15 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/log-style.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/logger.d.ts +16 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/logger.js +49 -4
- package/bundle/typescript/src/commands/game/sideQuest/utilities/logger.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.js +31 -7
- package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/spots.d.ts +121 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/spots.js +315 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/spots.js.map +1 -0
- package/bundle/typescript/src/commands/ssl.js +10 -15
- package/bundle/typescript/src/commands/ssl.js.map +1 -1
- package/bundle/typescript/src/templates/react/kit/mui/auth/password-reset/basic-password-reset-page.js.tsx +3 -4
- package/bundle/typescript/src/tools/ssl/ssl.class.d.ts +8 -0
- package/bundle/typescript/src/tools/ssl/ssl.class.js +53 -0
- package/bundle/typescript/src/tools/ssl/ssl.class.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import type { Room, IRoomSpot } from '../models/room.js';
|
|
2
|
+
import type { Player } from '../models/player.js';
|
|
3
|
+
import { Direction } from '../types/shared/direction-enum.js';
|
|
4
|
+
/**
|
|
5
|
+
* Intra-room locations ("at" spots -- player request: every room felt
|
|
6
|
+
* like everything stood at your elbow; walking into the bar had both
|
|
7
|
+
* NPCs on you instantly, and you could pick a lock from across the
|
|
8
|
+
* room). A room MAY declare named spots (door, bar, booths...); actors,
|
|
9
|
+
* items, and puzzles MAY be positioned at one.
|
|
10
|
+
*
|
|
11
|
+
* THE COMPAT RULE (sacred, two layers):
|
|
12
|
+
* 1. A room with NO spots is one implicit whole-room spot -- every
|
|
13
|
+
* helper here short-circuits and behavior is exactly the pre-spots
|
|
14
|
+
* game. Old seeds never set spots.
|
|
15
|
+
* 2. UNPOSITIONED = CIRCULATING: anything without an atSpot is
|
|
16
|
+
* "anywhere in the room" -- it reaches everything and everything
|
|
17
|
+
* reaches it, and it gets no cover. Companions, spirits, and
|
|
18
|
+
* un-migrated NPCs can never strand. Only explicitly positioned
|
|
19
|
+
* things gate.
|
|
20
|
+
*
|
|
21
|
+
* Spots are a MEAT-plane concept: a Matrix host has no barstools, and
|
|
22
|
+
* astral space overlays the room whole -- off-meat actors read as
|
|
23
|
+
* unpositioned.
|
|
24
|
+
*
|
|
25
|
+
* Every spot comparison in the game goes through these helpers -- no
|
|
26
|
+
* call site rolls its own.
|
|
27
|
+
*/
|
|
28
|
+
/** Movement distance between spots, scaled by the room's size. */
|
|
29
|
+
export declare const SIZE_COST: Record<'small' | 'medium' | 'large', number>;
|
|
30
|
+
export declare function spotsActive(room: Room | undefined): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* The IMPLICIT spot every spotted room has: the open floor. "move away"
|
|
33
|
+
* stands you here -- deliberately at none of the named places (player
|
|
34
|
+
* request: "I don't want to be at the door, bar, booths, or back
|
|
35
|
+
* corner"). It is a REAL position, not the circulating compat state:
|
|
36
|
+
* you don't reach the bar from out here, and an NPC who wants you
|
|
37
|
+
* steps onto the open floor too -- that's where you both are. No cover,
|
|
38
|
+
* always visible: standing apart has a price.
|
|
39
|
+
*/
|
|
40
|
+
export declare const OPEN_FLOOR = "open floor";
|
|
41
|
+
/** Fuzzy-resolves a typed name ("booth") to a declared spot ("booths"),
|
|
42
|
+
* or "away"/"open floor"/"middle" to the implicit OPEN_FLOOR. */
|
|
43
|
+
export declare function resolveSpot(room: Room | undefined, name: string): IRoomSpot | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* The actor's validated position: undefined when the room isn't
|
|
46
|
+
* spotted, the actor is off-meat, unpositioned, or names a spot the
|
|
47
|
+
* room no longer has (stale writes read as circulating, never as a
|
|
48
|
+
* phantom position).
|
|
49
|
+
*/
|
|
50
|
+
export declare function spotOf(actor: Player): string | undefined;
|
|
51
|
+
/** Whether two actors share a spot (callers already gate same-room). */
|
|
52
|
+
export declare function sameSpot(a: Player, b: Player): boolean;
|
|
53
|
+
/** Whether an actor can reach a positioned thing (item/puzzle/exit). */
|
|
54
|
+
export declare function canReach(actor: Player, targetSpot: string | undefined): boolean;
|
|
55
|
+
export declare function moveCost(room: Room): number;
|
|
56
|
+
/**
|
|
57
|
+
* The spot an exit is reachable from. Seed-declared (room.exitSpots)
|
|
58
|
+
* first; else a spot named like a doorway; else undefined = the exit is
|
|
59
|
+
* usable from anywhere (compat).
|
|
60
|
+
*/
|
|
61
|
+
export declare function exitSpot(room: Room, direction: Direction): string | undefined;
|
|
62
|
+
/** Where an arrival through `direction` (the direction WALKED, from the
|
|
63
|
+
* far side) stands: at this room's matching exit spot; else the room's
|
|
64
|
+
* doorway-named spot; else its first spot (a positioned room always
|
|
65
|
+
* positions the arriving player -- that's what makes gating bite). */
|
|
66
|
+
export declare function entrySpotFor(room: Room, arrivedFrom: Direction | undefined): string | undefined;
|
|
67
|
+
/** One refusal voice for every spot gate -- always names the cure. */
|
|
68
|
+
export declare function spotRefusal(targetLabel: string, spotName: string): string;
|
|
69
|
+
/**
|
|
70
|
+
* Auto-move for object work (take/pick/hack/solve): out of combat you
|
|
71
|
+
* just walk over -- one narration line, no ceremony (the user's ask was
|
|
72
|
+
* that you CAN'T do it from across the room, not that you must type two
|
|
73
|
+
* commands). Mid-exchange nobody strolls: refuse like go.ts does, and
|
|
74
|
+
* the Phase-2 crossing machinery will make it cost instead.
|
|
75
|
+
*/
|
|
76
|
+
export declare function ensureAtSpot(actor: Player, targetSpot: string | undefined): {
|
|
77
|
+
line?: string;
|
|
78
|
+
refusal?: string;
|
|
79
|
+
};
|
|
80
|
+
export declare const SPOT_COLOR = "yellow";
|
|
81
|
+
/**
|
|
82
|
+
* Weaves the room's places into its PROSE: every spot name already in
|
|
83
|
+
* the description gets the keyword color. When the full name isn't
|
|
84
|
+
* there, the spot's HEAD NOUN is tried next -- generated prose
|
|
85
|
+
* paraphrases ("stacked with crates" for the "stacked crates" spot),
|
|
86
|
+
* and coloring the noun the author actually wrote beats bolting a list
|
|
87
|
+
* onto good prose (playtest note: the "Also here:" tail didn't flow).
|
|
88
|
+
* Only places the prose never touches at all get appended, as a
|
|
89
|
+
* sentence in the game's voice.
|
|
90
|
+
*/
|
|
91
|
+
export declare function highlightSpots(room: Room, text: string): string;
|
|
92
|
+
export declare const ACTOR_COLOR = "green";
|
|
93
|
+
/**
|
|
94
|
+
* Colors the names of PRESENT, OBVIOUS people in a room's prose (player
|
|
95
|
+
* request: places got the keyword treatment; actual NPCs deserve one
|
|
96
|
+
* too). Only actors standing in the open are painted: coloring someone
|
|
97
|
+
* tucked behind cover would confirm a presence the Perception check is
|
|
98
|
+
* supposed to guard -- if stale prose names a hidden watcher, the text
|
|
99
|
+
* stays flat and gives nothing away. Tries the full name, then its
|
|
100
|
+
* distinctive words ("Krow" for "Mr. Krow").
|
|
101
|
+
*/
|
|
102
|
+
export declare function highlightActors(room: Room, text: string, viewer: Player): string;
|
|
103
|
+
/**
|
|
104
|
+
* The compact who-stands-where line ('look' reads "You at the door,
|
|
105
|
+
* Patch at the bar, Old Cray at the booths (cover)"): OCCUPIED places
|
|
106
|
+
* only, viewer first, co-occupants grouped, circulating actors trailing.
|
|
107
|
+
*
|
|
108
|
+
* Casing the room is a PERCEPTION check (player ruling): pass the
|
|
109
|
+
* viewer's Observe-in-Detail hits and occupants tucked at cover-tagged
|
|
110
|
+
* spots need the RAW thresholds (p.135-136: Normal 2 for partial cover,
|
|
111
|
+
* Hidden 4 for good cover) or they're silently omitted -- the booth ate
|
|
112
|
+
* them. People in the open, at YOUR spot, or circulating are simply
|
|
113
|
+
* seen, no dice (a pedestrian in plain view isn't a test). Omit `hits`
|
|
114
|
+
* for the all-seeing form (NPC prompts -- residents know their room).
|
|
115
|
+
*/
|
|
116
|
+
export declare function whoIsWhereLine(room: Room, viewer: Player, hits?: number): string;
|
|
117
|
+
/**
|
|
118
|
+
* The "who stands where" lines for the bare "move" list and NPC prompts:
|
|
119
|
+
* door (you), bar -- Mama Wu, booths (cover)
|
|
120
|
+
*/
|
|
121
|
+
export declare function describeSpotRoster(room: Room, viewer?: Player): string[];
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import { significantWords, wordsAreCloseEnough } from './fuzzy-match.js';
|
|
2
|
+
import { hint } from './hints.js';
|
|
3
|
+
/**
|
|
4
|
+
* Intra-room locations ("at" spots -- player request: every room felt
|
|
5
|
+
* like everything stood at your elbow; walking into the bar had both
|
|
6
|
+
* NPCs on you instantly, and you could pick a lock from across the
|
|
7
|
+
* room). A room MAY declare named spots (door, bar, booths...); actors,
|
|
8
|
+
* items, and puzzles MAY be positioned at one.
|
|
9
|
+
*
|
|
10
|
+
* THE COMPAT RULE (sacred, two layers):
|
|
11
|
+
* 1. A room with NO spots is one implicit whole-room spot -- every
|
|
12
|
+
* helper here short-circuits and behavior is exactly the pre-spots
|
|
13
|
+
* game. Old seeds never set spots.
|
|
14
|
+
* 2. UNPOSITIONED = CIRCULATING: anything without an atSpot is
|
|
15
|
+
* "anywhere in the room" -- it reaches everything and everything
|
|
16
|
+
* reaches it, and it gets no cover. Companions, spirits, and
|
|
17
|
+
* un-migrated NPCs can never strand. Only explicitly positioned
|
|
18
|
+
* things gate.
|
|
19
|
+
*
|
|
20
|
+
* Spots are a MEAT-plane concept: a Matrix host has no barstools, and
|
|
21
|
+
* astral space overlays the room whole -- off-meat actors read as
|
|
22
|
+
* unpositioned.
|
|
23
|
+
*
|
|
24
|
+
* Every spot comparison in the game goes through these helpers -- no
|
|
25
|
+
* call site rolls its own.
|
|
26
|
+
*/
|
|
27
|
+
/** Movement distance between spots, scaled by the room's size. */
|
|
28
|
+
export const SIZE_COST = {
|
|
29
|
+
small: 1, medium: 2, large: 4,
|
|
30
|
+
};
|
|
31
|
+
export function spotsActive(room) {
|
|
32
|
+
return (room?.spots?.length ?? 0) > 0;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The IMPLICIT spot every spotted room has: the open floor. "move away"
|
|
36
|
+
* stands you here -- deliberately at none of the named places (player
|
|
37
|
+
* request: "I don't want to be at the door, bar, booths, or back
|
|
38
|
+
* corner"). It is a REAL position, not the circulating compat state:
|
|
39
|
+
* you don't reach the bar from out here, and an NPC who wants you
|
|
40
|
+
* steps onto the open floor too -- that's where you both are. No cover,
|
|
41
|
+
* always visible: standing apart has a price.
|
|
42
|
+
*/
|
|
43
|
+
export const OPEN_FLOOR = 'open floor';
|
|
44
|
+
const OPEN_FLOOR_ALIASES = /^(away|apart|open floor|the floor|floor|middle|center|centre)$/i;
|
|
45
|
+
/** Fuzzy-resolves a typed name ("booth") to a declared spot ("booths"),
|
|
46
|
+
* or "away"/"open floor"/"middle" to the implicit OPEN_FLOOR. */
|
|
47
|
+
export function resolveSpot(room, name) {
|
|
48
|
+
if (!room || !spotsActive(room) || !name.trim())
|
|
49
|
+
return undefined;
|
|
50
|
+
const typed = name.trim().toLowerCase();
|
|
51
|
+
if (OPEN_FLOOR_ALIASES.test(typed))
|
|
52
|
+
return { name: OPEN_FLOOR };
|
|
53
|
+
const spots = room.spots ?? [];
|
|
54
|
+
const exact = spots.find(s => s.name.toLowerCase() === typed);
|
|
55
|
+
if (exact)
|
|
56
|
+
return exact;
|
|
57
|
+
const substr = spots.filter(s => s.name.toLowerCase().includes(typed) || typed.includes(s.name.toLowerCase()));
|
|
58
|
+
if (substr.length === 1)
|
|
59
|
+
return substr[0];
|
|
60
|
+
const typedWords = significantWords(typed);
|
|
61
|
+
const scored = spots.filter(s => significantWords(s.name.toLowerCase()).some(sw => typedWords.some(tw => wordsAreCloseEnough(tw, sw))));
|
|
62
|
+
return scored.length === 1 ? scored[0] : undefined;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* The actor's validated position: undefined when the room isn't
|
|
66
|
+
* spotted, the actor is off-meat, unpositioned, or names a spot the
|
|
67
|
+
* room no longer has (stale writes read as circulating, never as a
|
|
68
|
+
* phantom position).
|
|
69
|
+
*/
|
|
70
|
+
export function spotOf(actor) {
|
|
71
|
+
const room = actor.currentLocation;
|
|
72
|
+
if (!spotsActive(room) || actor.plane !== 'meat' || !actor.atSpot)
|
|
73
|
+
return undefined;
|
|
74
|
+
if (actor.atSpot === OPEN_FLOOR)
|
|
75
|
+
return OPEN_FLOOR;
|
|
76
|
+
return room.spots.some(s => s.name === actor.atSpot) ? actor.atSpot : undefined;
|
|
77
|
+
}
|
|
78
|
+
/** Whether two actors share a spot (callers already gate same-room). */
|
|
79
|
+
export function sameSpot(a, b) {
|
|
80
|
+
const room = a.currentLocation;
|
|
81
|
+
if (!spotsActive(room))
|
|
82
|
+
return true;
|
|
83
|
+
const sa = spotOf(a);
|
|
84
|
+
const sb = spotOf(b);
|
|
85
|
+
if (sa === undefined || sb === undefined)
|
|
86
|
+
return true; // circulating reaches everyone
|
|
87
|
+
return sa === sb;
|
|
88
|
+
}
|
|
89
|
+
/** Whether an actor can reach a positioned thing (item/puzzle/exit). */
|
|
90
|
+
export function canReach(actor, targetSpot) {
|
|
91
|
+
if (targetSpot === undefined)
|
|
92
|
+
return true;
|
|
93
|
+
const room = actor.currentLocation;
|
|
94
|
+
if (!spotsActive(room))
|
|
95
|
+
return true;
|
|
96
|
+
const mine = spotOf(actor);
|
|
97
|
+
if (mine === undefined)
|
|
98
|
+
return true;
|
|
99
|
+
return mine === targetSpot;
|
|
100
|
+
}
|
|
101
|
+
export function moveCost(room) {
|
|
102
|
+
return SIZE_COST[room.size ?? 'medium'];
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The spot an exit is reachable from. Seed-declared (room.exitSpots)
|
|
106
|
+
* first; else a spot named like a doorway; else undefined = the exit is
|
|
107
|
+
* usable from anywhere (compat).
|
|
108
|
+
*/
|
|
109
|
+
export function exitSpot(room, direction) {
|
|
110
|
+
if (!spotsActive(room))
|
|
111
|
+
return undefined;
|
|
112
|
+
const declared = room.exitSpots.get(direction);
|
|
113
|
+
if (declared && room.spots.some(s => s.name === declared))
|
|
114
|
+
return declared;
|
|
115
|
+
const doorish = room.spots.find(s => /door|entrance|entry|threshold|gate/i.test(s.name));
|
|
116
|
+
return doorish?.name;
|
|
117
|
+
}
|
|
118
|
+
/** Where an arrival through `direction` (the direction WALKED, from the
|
|
119
|
+
* far side) stands: at this room's matching exit spot; else the room's
|
|
120
|
+
* doorway-named spot; else its first spot (a positioned room always
|
|
121
|
+
* positions the arriving player -- that's what makes gating bite). */
|
|
122
|
+
export function entrySpotFor(room, arrivedFrom) {
|
|
123
|
+
if (!spotsActive(room))
|
|
124
|
+
return undefined;
|
|
125
|
+
if (arrivedFrom !== undefined) {
|
|
126
|
+
const viaExit = exitSpot(room, room.getOppositeDirection(arrivedFrom));
|
|
127
|
+
if (viaExit)
|
|
128
|
+
return viaExit;
|
|
129
|
+
}
|
|
130
|
+
const doorish = room.spots.find(s => /door|entrance|entry|threshold|gate/i.test(s.name));
|
|
131
|
+
return doorish?.name ?? room.spots[0]?.name;
|
|
132
|
+
}
|
|
133
|
+
/** One refusal voice for every spot gate -- always names the cure. */
|
|
134
|
+
export function spotRefusal(targetLabel, spotName) {
|
|
135
|
+
return `${targetLabel} is across the room at the ${spotName} -- "move to ${spotName}" first.`;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Auto-move for object work (take/pick/hack/solve): out of combat you
|
|
139
|
+
* just walk over -- one narration line, no ceremony (the user's ask was
|
|
140
|
+
* that you CAN'T do it from across the room, not that you must type two
|
|
141
|
+
* commands). Mid-exchange nobody strolls: refuse like go.ts does, and
|
|
142
|
+
* the Phase-2 crossing machinery will make it cost instead.
|
|
143
|
+
*/
|
|
144
|
+
export function ensureAtSpot(actor, targetSpot) {
|
|
145
|
+
if (canReach(actor, targetSpot))
|
|
146
|
+
return {};
|
|
147
|
+
if (actor.inExchange) {
|
|
148
|
+
return { refusal: `That's over at the ${targetSpot} -- and you're mid-exchange. Crossing open floor now means eating lead.` };
|
|
149
|
+
}
|
|
150
|
+
actor.atSpot = targetSpot;
|
|
151
|
+
actor.performAction('moves to', `the ${targetSpot}`);
|
|
152
|
+
return { line: `You cross to the ${targetSpot}.` };
|
|
153
|
+
}
|
|
154
|
+
// Place names render in this color wherever they appear -- the classic
|
|
155
|
+
// MUD "interactive keyword" convention (player request: places should
|
|
156
|
+
// live IN the room's prose, color-coded, not in a separate list).
|
|
157
|
+
export const SPOT_COLOR = 'yellow';
|
|
158
|
+
const hl = (name) => `{${SPOT_COLOR}-fg}${name}{/${SPOT_COLOR}-fg}`;
|
|
159
|
+
/**
|
|
160
|
+
* Weaves the room's places into its PROSE: every spot name already in
|
|
161
|
+
* the description gets the keyword color. When the full name isn't
|
|
162
|
+
* there, the spot's HEAD NOUN is tried next -- generated prose
|
|
163
|
+
* paraphrases ("stacked with crates" for the "stacked crates" spot),
|
|
164
|
+
* and coloring the noun the author actually wrote beats bolting a list
|
|
165
|
+
* onto good prose (playtest note: the "Also here:" tail didn't flow).
|
|
166
|
+
* Only places the prose never touches at all get appended, as a
|
|
167
|
+
* sentence in the game's voice.
|
|
168
|
+
*/
|
|
169
|
+
export function highlightSpots(room, text) {
|
|
170
|
+
if (!spotsActive(room))
|
|
171
|
+
return text;
|
|
172
|
+
const missing = [];
|
|
173
|
+
let out = text;
|
|
174
|
+
const esc = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
175
|
+
// Longest first so "back corner" wins before "bar" ever could.
|
|
176
|
+
for (const s of [...room.spots].sort((a, b) => b.name.length - a.name.length)) {
|
|
177
|
+
const full = new RegExp(`\\b(${esc(s.name)})\\b`, 'i');
|
|
178
|
+
if (full.test(out)) {
|
|
179
|
+
out = out.replace(full, (m) => hl(m));
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
const noun = s.name.trim().split(/\s+/).pop();
|
|
183
|
+
// The noun fallback must not land inside an already-painted tag --
|
|
184
|
+
// require the match not be immediately followed by a closing tag.
|
|
185
|
+
const nounRe = new RegExp(`\\b(${esc(noun)})\\b(?!\\{/)`, 'i');
|
|
186
|
+
if (noun.length >= 3 && nounRe.test(out)) {
|
|
187
|
+
out = out.replace(nounRe, (m) => hl(m));
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
missing.push(hl(s.name));
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (missing.length > 0) {
|
|
194
|
+
const named = missing.reverse().map(m => `the ${m}`);
|
|
195
|
+
const list = named.length === 1 ? named[0]
|
|
196
|
+
: `${named.slice(0, -1).join(', ')} and ${named[named.length - 1]}`;
|
|
197
|
+
out += ` Your eye picks out ${list}.`;
|
|
198
|
+
}
|
|
199
|
+
return out;
|
|
200
|
+
}
|
|
201
|
+
// People render in this color wherever prose names them -- green, the
|
|
202
|
+
// color NPC speech already wears.
|
|
203
|
+
export const ACTOR_COLOR = 'green';
|
|
204
|
+
/**
|
|
205
|
+
* Colors the names of PRESENT, OBVIOUS people in a room's prose (player
|
|
206
|
+
* request: places got the keyword treatment; actual NPCs deserve one
|
|
207
|
+
* too). Only actors standing in the open are painted: coloring someone
|
|
208
|
+
* tucked behind cover would confirm a presence the Perception check is
|
|
209
|
+
* supposed to guard -- if stale prose names a hidden watcher, the text
|
|
210
|
+
* stays flat and gives nothing away. Tries the full name, then its
|
|
211
|
+
* distinctive words ("Krow" for "Mr. Krow").
|
|
212
|
+
*/
|
|
213
|
+
export function highlightActors(room, text, viewer) {
|
|
214
|
+
let out = text;
|
|
215
|
+
const esc = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
216
|
+
const paint = (m) => `{${ACTOR_COLOR}-fg}${m}{/${ACTOR_COLOR}-fg}`;
|
|
217
|
+
for (const a of room.getActors()) {
|
|
218
|
+
if (a === viewer || !viewer.canPerceive(a))
|
|
219
|
+
continue;
|
|
220
|
+
// Obvious only: circulating, on the open floor, or at an untagged spot.
|
|
221
|
+
const s = spotOf(a);
|
|
222
|
+
if (s !== undefined && s !== OPEN_FLOOR) {
|
|
223
|
+
const covered = (room.spots ?? []).some(sp => sp.name === s && (sp.tags ?? []).some(t => t.startsWith('cover')));
|
|
224
|
+
if (covered)
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
const full = new RegExp(`\\b(${esc(a.name)})\\b`);
|
|
228
|
+
if (full.test(out)) {
|
|
229
|
+
out = out.replace(full, paint);
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
const word = a.name.split(/\s+/).filter(w => w.length >= 4).pop();
|
|
233
|
+
if (word) {
|
|
234
|
+
const wordRe = new RegExp(`\\b(${esc(word)})\\b(?!\\{/)`);
|
|
235
|
+
if (wordRe.test(out))
|
|
236
|
+
out = out.replace(wordRe, paint);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return out;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* The compact who-stands-where line ('look' reads "You at the door,
|
|
243
|
+
* Patch at the bar, Old Cray at the booths (cover)"): OCCUPIED places
|
|
244
|
+
* only, viewer first, co-occupants grouped, circulating actors trailing.
|
|
245
|
+
*
|
|
246
|
+
* Casing the room is a PERCEPTION check (player ruling): pass the
|
|
247
|
+
* viewer's Observe-in-Detail hits and occupants tucked at cover-tagged
|
|
248
|
+
* spots need the RAW thresholds (p.135-136: Normal 2 for partial cover,
|
|
249
|
+
* Hidden 4 for good cover) or they're silently omitted -- the booth ate
|
|
250
|
+
* them. People in the open, at YOUR spot, or circulating are simply
|
|
251
|
+
* seen, no dice (a pedestrian in plain view isn't a test). Omit `hits`
|
|
252
|
+
* for the all-seeing form (NPC prompts -- residents know their room).
|
|
253
|
+
*/
|
|
254
|
+
export function whoIsWhereLine(room, viewer, hits) {
|
|
255
|
+
if (!spotsActive(room))
|
|
256
|
+
return '';
|
|
257
|
+
const actors = room.getActors().filter(a => a === viewer || viewer.canPerceive(a));
|
|
258
|
+
const viewerSpot = spotOf(viewer);
|
|
259
|
+
const parts = [];
|
|
260
|
+
for (const s of room.spots) {
|
|
261
|
+
let here = actors.filter(a => a.atSpot === s.name);
|
|
262
|
+
if (hits !== undefined && s.name !== viewerSpot) {
|
|
263
|
+
const covered = (s.tags ?? []).some(t => t.startsWith('cover'));
|
|
264
|
+
const threshold = (s.tags ?? []).includes('cover-good') ? 4 : covered ? 2 : 0;
|
|
265
|
+
if (threshold > 0 && hits < threshold) {
|
|
266
|
+
here = here.filter(a => a === viewer);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (here.length === 0)
|
|
270
|
+
continue;
|
|
271
|
+
const names = here.map(a => a === viewer ? 'You' : a.name);
|
|
272
|
+
if (here.includes(viewer))
|
|
273
|
+
names.sort(n => n === 'You' ? -1 : 1);
|
|
274
|
+
const tags = [...new Set((s.tags ?? []).map(t => t.startsWith('cover') ? 'cover' : t))];
|
|
275
|
+
parts.push(`${names.join(' and ')} at the ${hl(s.name)}${tags.length > 0 ? ` (${tags.join(', ')})` : ''}`);
|
|
276
|
+
}
|
|
277
|
+
// The open floor: always visible (no cover out there), phrased "on",
|
|
278
|
+
// not "at" -- it's the neutral ground, not a fixture.
|
|
279
|
+
const onFloor = actors.filter(a => a.atSpot === OPEN_FLOOR);
|
|
280
|
+
if (onFloor.length > 0) {
|
|
281
|
+
const names = onFloor.map(a => a === viewer ? 'You' : a.name);
|
|
282
|
+
if (onFloor.includes(viewer))
|
|
283
|
+
names.sort(n => n === 'You' ? -1 : 1);
|
|
284
|
+
parts.push(`${names.join(' and ')} on the ${hl(OPEN_FLOOR)}`);
|
|
285
|
+
}
|
|
286
|
+
const drifting = actors.filter(a => a !== viewer && !a.atSpot && a.plane === 'meat');
|
|
287
|
+
if (drifting.length > 0)
|
|
288
|
+
parts.push(`${drifting.map(a => a.name).join(', ')} moving through`);
|
|
289
|
+
return parts.join(', ');
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* The "who stands where" lines for the bare "move" list and NPC prompts:
|
|
293
|
+
* door (you), bar -- Mama Wu, booths (cover)
|
|
294
|
+
*/
|
|
295
|
+
export function describeSpotRoster(room, viewer) {
|
|
296
|
+
if (!spotsActive(room))
|
|
297
|
+
return [];
|
|
298
|
+
const actors = room.getActors();
|
|
299
|
+
const lines = room.spots.map(s => {
|
|
300
|
+
const here = actors.filter(a => a !== viewer && a.atSpot === s.name && (viewer ? viewer.canPerceive(a) : true)).map(a => a.name);
|
|
301
|
+
const you = viewer && spotOf(viewer) === s.name ? ['you'] : [];
|
|
302
|
+
const tags = (s.tags ?? []).map(t => t.startsWith('cover') ? 'cover' : t);
|
|
303
|
+
const tagNote = tags.length > 0 ? ` (${[...new Set(tags)].join(', ')})` : '';
|
|
304
|
+
const who = [...you, ...here];
|
|
305
|
+
return `${s.name}${tagNote}${who.length > 0 ? ` -- ${who.join(', ')}` : ''}`;
|
|
306
|
+
});
|
|
307
|
+
// The implicit neutral ground rides along ("move away" stands here).
|
|
308
|
+
const onFloor = [
|
|
309
|
+
...(viewer && spotOf(viewer) === OPEN_FLOOR ? ['you'] : []),
|
|
310
|
+
...actors.filter(a => a !== viewer && a.atSpot === OPEN_FLOOR && (viewer ? viewer.canPerceive(a) : true)).map(a => a.name),
|
|
311
|
+
];
|
|
312
|
+
lines.push(`${OPEN_FLOOR}${hint(' ("move away")')}${onFloor.length > 0 ? ` -- ${onFloor.join(', ')}` : ''}`);
|
|
313
|
+
return lines;
|
|
314
|
+
}
|
|
315
|
+
//# sourceMappingURL=spots.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spots.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/utilities/spots.ts"],"names":[],"mappings":"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"}
|
|
@@ -73,23 +73,18 @@ Command.create({
|
|
|
73
73
|
Log.error(e);
|
|
74
74
|
return;
|
|
75
75
|
}
|
|
76
|
-
const spinHandle = Log.withSpinner();
|
|
77
|
-
spinHandle.start('Verifying Letsencrypt configuration');
|
|
78
|
-
await SSH.ssh('sudo snap install core; sudo snap refresh core', {
|
|
79
|
-
...sshConfig
|
|
80
|
-
});
|
|
81
|
-
await SSH.ssh('sudo snap install --classic certbot', {
|
|
82
|
-
...sshConfig
|
|
83
|
-
});
|
|
84
|
-
await SSH.ssh('sudo ln -s /snap/bin/certbot /usr/bin/certbot', {
|
|
85
|
-
...sshConfig
|
|
86
|
-
});
|
|
87
|
-
spinHandle.success();
|
|
88
76
|
const domainNames = (configDomains) ? configDomains : await Actions.ask('[?] Domains to register: ');
|
|
89
77
|
const emailUpdate = (configEmail) ? configEmail : await Actions.ask('Email to use for auto-updates: ');
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
78
|
+
const spinHandle = Log.withSpinner();
|
|
79
|
+
spinHandle.start('Verifying Letsencrypt configuration and requesting certificate');
|
|
80
|
+
try {
|
|
81
|
+
await SSL.setupLetsEncrypt(sshConfig, { domains: domainNames, email: emailUpdate });
|
|
82
|
+
}
|
|
83
|
+
catch (e) {
|
|
84
|
+
spinHandle.failure();
|
|
85
|
+
throw e;
|
|
86
|
+
}
|
|
87
|
+
spinHandle.success();
|
|
93
88
|
const letsEncryptConfig = {
|
|
94
89
|
domainNames,
|
|
95
90
|
emailUpdate
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssl.js","sourceRoot":"","sources":["../../../../src/commands/ssl.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ssl.js","sourceRoot":"","sources":["../../../../src/commands/ssl.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import React, { useContext } from 'react';
|
|
2
2
|
import { Container, Paper, Typography, TextField, Button } from '@mui/material';
|
|
3
|
-
import { useNavigate } from 'react-router-dom';
|
|
3
|
+
import { useNavigate, useParams } from 'react-router-dom';
|
|
4
4
|
|
|
5
|
-
export const BasicPasswordResetPage = (
|
|
6
|
-
const {
|
|
7
|
-
const { token } = params;
|
|
5
|
+
export const BasicPasswordResetPage = () => {
|
|
6
|
+
const { token } = useParams();
|
|
8
7
|
|
|
9
8
|
const { resetPassword } = useContext(AuthContext);
|
|
10
9
|
const navigate = useNavigate();
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { IDefaultProps } from '../ssh/ssh.interfaces.js';
|
|
1
2
|
interface ISSLGenCSR {
|
|
2
3
|
keyName: string;
|
|
3
4
|
csrName: string;
|
|
@@ -10,8 +11,15 @@ interface ISSLGenSSC {
|
|
|
10
11
|
cwd?: string;
|
|
11
12
|
useConfig?: boolean;
|
|
12
13
|
}
|
|
14
|
+
interface ILetsEncryptSetup {
|
|
15
|
+
domains: string;
|
|
16
|
+
email: string;
|
|
17
|
+
retries?: number;
|
|
18
|
+
retryDelayMs?: number;
|
|
19
|
+
}
|
|
13
20
|
export declare class SSL {
|
|
14
21
|
static genCSR(opts: ISSLGenCSR): void;
|
|
15
22
|
static genSSC(opts: ISSLGenSSC): void;
|
|
23
|
+
static setupLetsEncrypt(sshConfig: IDefaultProps, opts: ILetsEncryptSetup): Promise<void>;
|
|
16
24
|
}
|
|
17
25
|
export {};
|
|
@@ -1,4 +1,19 @@
|
|
|
1
1
|
import { spawnSync } from 'child_process';
|
|
2
|
+
import { SSH } from '../ssh/ssh.class.js';
|
|
3
|
+
import { Log } from '../log/log.class.js';
|
|
4
|
+
// Errors that mean "already in the desired state" rather than a real failure -
|
|
5
|
+
// these commands are re-run on every deploy/ssl invocation and aren't idempotent
|
|
6
|
+
// on their own.
|
|
7
|
+
const LETSENCRYPT_IGNORE_ERRORS = [
|
|
8
|
+
'snap "core" is already installed',
|
|
9
|
+
'snap "core" has no updates available',
|
|
10
|
+
'snap "certbot" is already installed',
|
|
11
|
+
"ln: failed to create symbolic link '/usr/bin/certbot': File exists",
|
|
12
|
+
'Certificate not yet due for renewal'
|
|
13
|
+
];
|
|
14
|
+
function sleep(ms) {
|
|
15
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
16
|
+
}
|
|
2
17
|
export class SSL {
|
|
3
18
|
static genCSR(opts) {
|
|
4
19
|
const cwd = (opts.cwd) ? opts.cwd : process.cwd();
|
|
@@ -50,5 +65,43 @@ export class SSL {
|
|
|
50
65
|
spawnSync('openssl', args, { stdio: 'inherit', cwd });
|
|
51
66
|
}
|
|
52
67
|
}
|
|
68
|
+
// Installs certbot via snap and obtains/renews a cert with the nginx plugin.
|
|
69
|
+
// Shared by `maka ssl --env <env> letsencrypt` and `maka deploy:ubuntu --letsencrypt`
|
|
70
|
+
// so both paths behave identically and stay idempotent on re-runs.
|
|
71
|
+
static async setupLetsEncrypt(sshConfig, opts) {
|
|
72
|
+
const retries = opts.retries ?? 3;
|
|
73
|
+
const retryDelayMs = opts.retryDelayMs ?? 15000;
|
|
74
|
+
function run(command) {
|
|
75
|
+
const result = SSH.sshSync(command, sshConfig, { silentOutput: true });
|
|
76
|
+
if (!result) {
|
|
77
|
+
throw new Error(`No result received from command: ${command}`);
|
|
78
|
+
}
|
|
79
|
+
const shouldIgnore = LETSENCRYPT_IGNORE_ERRORS.some(err => result.stderr.includes(err));
|
|
80
|
+
if (result.status !== 0 && !shouldIgnore) {
|
|
81
|
+
throw new Error(`Command failed (status ${result.status}): ${command}\n${(result.stderr || result.stdout).trim()}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// On a freshly-booted Ubuntu host, snapd may not have finished seeding yet;
|
|
85
|
+
// `snap install` fails with "too early for operation" if it's not waited for.
|
|
86
|
+
run('sudo snap wait system seed.loaded');
|
|
87
|
+
run('sudo snap install core; sudo snap refresh core');
|
|
88
|
+
run('sudo snap install --classic certbot');
|
|
89
|
+
run('sudo ln -s /snap/bin/certbot /usr/bin/certbot');
|
|
90
|
+
const certbotCmd = `sudo certbot --nginx --agree-tos --expand -n --domains ${opts.domains} --email ${opts.email}`;
|
|
91
|
+
for (let attempt = 1; attempt <= retries; attempt++) {
|
|
92
|
+
try {
|
|
93
|
+
run(certbotCmd);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
catch (e) {
|
|
97
|
+
const isLastAttempt = attempt === retries;
|
|
98
|
+
if (isLastAttempt)
|
|
99
|
+
throw e;
|
|
100
|
+
Log.warn(`Certbot attempt ${attempt}/${retries} failed, retrying in ${retryDelayMs / 1000}s (DNS may still be propagating, or a firewall rule hasn't taken effect yet):`);
|
|
101
|
+
Log.warn(String(e instanceof Error ? e.message : e));
|
|
102
|
+
await sleep(retryDelayMs);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
53
106
|
}
|
|
54
107
|
//# sourceMappingURL=ssl.class.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssl.class.js","sourceRoot":"","sources":["../../../../../src/tools/ssl/ssl.class.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"ssl.class.js","sourceRoot":"","sources":["../../../../../src/tools/ssl/ssl.class.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maka/maka-cli",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.9.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"summary": "A command line tool for scaffolding Meteor 2.x applications using either React.",
|
|
6
6
|
"description": "A command line tool for scaffolding Meteor 2.x applications using React.",
|