@patchstack/connect 0.3.29 → 0.3.31
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/AGENT-INSTALL.md +42 -23
- package/README.md +40 -11
- package/dist/{chunk-MJOTFUDE.js → chunk-LLKP5EJS.js} +1 -1
- package/dist/chunk-LLKP5EJS.js.map +1 -0
- package/dist/cli.js +1265 -287
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +456 -111
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +76 -10
- package/dist/index.d.ts +76 -10
- package/dist/index.js +449 -104
- package/dist/index.js.map +1 -1
- package/dist/protect/templates/astro-middleware.ts +33 -13
- package/dist/protect/templates/demo-rules.json +2 -3
- package/dist/protect/templates/express-guard.cjs +26 -15
- package/dist/protect/templates/express-guard.js +26 -15
- package/dist/protect/templates/express-guard.ts +33 -16
- package/dist/protect/templates/fastify-plugin.cjs +33 -11
- package/dist/protect/templates/fastify-plugin.js +33 -11
- package/dist/protect/templates/fastify-plugin.ts +40 -12
- package/dist/protect/templates/generic-guard.cjs +28 -12
- package/dist/protect/templates/generic-guard.js +28 -13
- package/dist/protect/templates/generic-guard.ts +41 -20
- package/dist/protect/templates/guard.ts +47 -27
- package/dist/protect/templates/next-middleware.ts +29 -12
- package/dist/protect/templates/nuxt-middleware.ts +29 -12
- package/dist/protect/templates/rules.json +2 -2
- package/dist/protect/templates/sveltekit-hooks.ts +33 -13
- package/dist/protect.cjs +1204 -252
- package/dist/protect.cjs.map +1 -1
- package/dist/protect.d.ts +39 -11
- package/dist/protect.edge.js +792 -143
- package/dist/protect.edge.js.map +4 -4
- package/dist/protect.js +794 -145
- package/dist/protect.js.map +1 -1
- package/dist/{refresh-manifest-VRBE6RH6.js → refresh-manifest-KNZQBC4V.js} +387 -100
- package/dist/refresh-manifest-KNZQBC4V.js.map +1 -0
- package/package.json +5 -2
- package/dist/chunk-MJOTFUDE.js.map +0 -1
- package/dist/refresh-manifest-VRBE6RH6.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -74,7 +74,7 @@ declare class PatchstackError extends Error {
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
type LockfileFilename = 'package-lock.json' | 'bun.lock' | 'bun.lockb' | 'yarn.lock' | 'pnpm-lock.yaml';
|
|
77
|
-
type DetectionStrategy = 'npm-lockfile' | 'node-modules-walk' | 'pnpm-lockfile' | 'yarn-lockfile';
|
|
77
|
+
type DetectionStrategy = 'npm-lockfile' | 'bun-lockfile' | 'node-modules-walk' | 'pnpm-lockfile' | 'yarn-lockfile';
|
|
78
78
|
interface DetectedLockfile {
|
|
79
79
|
ecosystem: 'npm';
|
|
80
80
|
filePath: string;
|
|
@@ -87,10 +87,45 @@ declare function scanLockfile(cwd: string): Promise<Manifest>;
|
|
|
87
87
|
interface WirePackage {
|
|
88
88
|
name: string;
|
|
89
89
|
version: string;
|
|
90
|
+
/**
|
|
91
|
+
* Where this exact name+version is installed, repo-relative and sorted.
|
|
92
|
+
*
|
|
93
|
+
* The same package can be installed more than once at different versions — a workspace pinning an old
|
|
94
|
+
* copy under `apps/api/node_modules`, a transitive dependency getting its own nested install. Without
|
|
95
|
+
* the locations, `lodash@4.17.11` and `lodash@4.17.21` arrive as two bare pairs and nothing can say
|
|
96
|
+
* WHICH one the app's own import resolves to. A consumer then has to treat every installed version as
|
|
97
|
+
* if the code used it: it warns on a copy nothing reaches, or pins a rule to a route running the safe
|
|
98
|
+
* one — a rule that never fires while reporting as protection.
|
|
99
|
+
*
|
|
100
|
+
* Node resolves an import by walking up from the importing file, so the map's import sites plus these
|
|
101
|
+
* paths together answer the question. Neither half answers it alone.
|
|
102
|
+
*
|
|
103
|
+
* OPT-IN. Absent unless the caller asks for locations (`scan --install-paths`), and absent even then
|
|
104
|
+
* when the scan source does not record them — see `installPathsComplete`, which is what separates
|
|
105
|
+
* "not installed there" from "we were not told".
|
|
106
|
+
*
|
|
107
|
+
* Off by default because it changes what leaves the machine. The package's standing promise is that
|
|
108
|
+
* `scan` sends names and versions and no paths of any kind; locations are a real widening of that, and
|
|
109
|
+
* an upload that widens it should be an explicit choice rather than a consequence of upgrading.
|
|
110
|
+
*/
|
|
111
|
+
paths?: string[];
|
|
90
112
|
}
|
|
91
113
|
interface WirePayload {
|
|
92
114
|
ecosystem: Manifest['ecosystem'];
|
|
93
115
|
packages: WirePackage[];
|
|
116
|
+
/**
|
|
117
|
+
* Whether every entry's `paths` is the complete set of locations for it.
|
|
118
|
+
*
|
|
119
|
+
* False when locations were not requested at all, when the scan source cannot supply them (a yarn.lock
|
|
120
|
+
* is flat — hoisting is decided at install time and the file does not record it; a v1 npm lockfile
|
|
121
|
+
* describes the dependency graph, not the tree), or when only some entries had one. A consumer MUST NOT
|
|
122
|
+
* read a missing or short `paths` as "installed nowhere else" while this is false; absence is then "not
|
|
123
|
+
* recorded", which is not an answer.
|
|
124
|
+
*
|
|
125
|
+
* The default is therefore `false`, and that is the safe direction: the field withholds a negative
|
|
126
|
+
* rather than granting one.
|
|
127
|
+
*/
|
|
128
|
+
installPathsComplete: boolean;
|
|
94
129
|
}
|
|
95
130
|
interface NormalizeStats {
|
|
96
131
|
uniqueNames: number;
|
|
@@ -101,7 +136,14 @@ interface NormalizeResult {
|
|
|
101
136
|
payload: WirePayload;
|
|
102
137
|
stats: NormalizeStats;
|
|
103
138
|
}
|
|
104
|
-
|
|
139
|
+
interface WireOptions {
|
|
140
|
+
/**
|
|
141
|
+
* Include each package's install location. Off by default — see `WirePackage.paths`: it widens what
|
|
142
|
+
* `scan` transmits, so it is the caller's explicit choice, not a side effect of upgrading.
|
|
143
|
+
*/
|
|
144
|
+
installPaths?: boolean;
|
|
145
|
+
}
|
|
146
|
+
declare function buildWirePayload(manifest: Manifest, options?: WireOptions): NormalizeResult;
|
|
105
147
|
declare function compareVersions(a: string, b: string): number;
|
|
106
148
|
|
|
107
149
|
declare const DEFAULT_ENDPOINT = "https://api.patchstack.com/monitor/pulse/manifest";
|
|
@@ -145,21 +187,40 @@ interface ResolveConfigOptions {
|
|
|
145
187
|
}
|
|
146
188
|
declare function resolveConfig(options: ResolveConfigOptions): Promise<Config>;
|
|
147
189
|
declare function writeConfigFile(cwd: string, config: ConfigFile): Promise<string>;
|
|
190
|
+
/**
|
|
191
|
+
* What happened to the credential file, so a caller can say only what is true.
|
|
192
|
+
*
|
|
193
|
+
* `ignored` is the OUTCOME of the ignore entry, verified by reading the file back — not the fact that a
|
|
194
|
+
* write was attempted. Telling somebody their credential is ignored when it is not is worse than telling
|
|
195
|
+
* them nothing: they stop looking, and a credential committed once is in the history whether or not the
|
|
196
|
+
* file is removed afterwards.
|
|
197
|
+
*/
|
|
198
|
+
interface SecretFileResult {
|
|
199
|
+
/** Absolute path of the credential file. */
|
|
200
|
+
path: string;
|
|
201
|
+
/** True only when `.gitignore` was read back and really covers it. */
|
|
202
|
+
ignored: boolean;
|
|
203
|
+
/** Why not, when it is not — for the caller to print instead of a false assurance. */
|
|
204
|
+
reason?: string;
|
|
205
|
+
}
|
|
148
206
|
/**
|
|
149
207
|
* Merge a new siteUuid into the existing `.patchstackrc.json` (or create it).
|
|
150
208
|
* Preserves any `endpoint` / `timeoutMs` / `apiKey` the user already wrote.
|
|
151
209
|
*/
|
|
152
210
|
declare function persistSiteUuid(cwd: string, siteUuid: string): Promise<string>;
|
|
153
211
|
/**
|
|
154
|
-
* Persist the WP-format api_key issued at provision. Authenticates both the
|
|
155
|
-
*
|
|
156
|
-
* disclosure widget.
|
|
212
|
+
* Persist the WP-format api_key issued at provision. Authenticates both the Pulse endpoints and connector
|
|
213
|
+
* log reporting. Never embed it in the public disclosure widget.
|
|
157
214
|
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
215
|
+
* Written to the credential file, which setup adds to the project's ignore list — the public config is
|
|
216
|
+
* meant to be committed, so a credential in it is a credential in the repository.
|
|
217
|
+
*
|
|
218
|
+
* Any copy in the committed config is REMOVED at the same time. Leaving it would mean the value that just
|
|
219
|
+
* got moved is still in the file everyone commits, which is the state this split exists to end. `pulseAuth`
|
|
220
|
+
* goes with it: that field resolves ahead of `apiKey`, so a stale copy would keep authenticating with a
|
|
221
|
+
* credential the server has replaced.
|
|
161
222
|
*/
|
|
162
|
-
declare function persistApiKey(cwd: string, apiKey: string): Promise<
|
|
223
|
+
declare function persistApiKey(cwd: string, apiKey: string): Promise<SecretFileResult>;
|
|
163
224
|
/**
|
|
164
225
|
* Persist a Pulse-specific credential.
|
|
165
226
|
*
|
|
@@ -167,7 +228,7 @@ declare function persistApiKey(cwd: string, apiKey: string): Promise<string>;
|
|
|
167
228
|
* credentials; they share one today, so `persistApiKey` covers both. Retained
|
|
168
229
|
* for callers that separate them.
|
|
169
230
|
*/
|
|
170
|
-
declare function persistPulseAuth(cwd: string, pulseAuth: string): Promise<
|
|
231
|
+
declare function persistPulseAuth(cwd: string, pulseAuth: string): Promise<SecretFileResult>;
|
|
171
232
|
|
|
172
233
|
/**
|
|
173
234
|
* A best-effort description of the stack a build was produced with, derived
|
|
@@ -251,6 +312,11 @@ declare function ensureSourceWidget(cwd: string, siteUuid: string): SourceWidget
|
|
|
251
312
|
interface ScanAndReportOptions {
|
|
252
313
|
cwd?: string;
|
|
253
314
|
config?: Config;
|
|
315
|
+
/**
|
|
316
|
+
* Include each package's install location in the uploaded payload. Off by default: it widens what
|
|
317
|
+
* leaves the machine, so it is an explicit choice rather than something an upgrade turns on.
|
|
318
|
+
*/
|
|
319
|
+
installPaths?: boolean;
|
|
254
320
|
}
|
|
255
321
|
interface ScanAndReportResult {
|
|
256
322
|
manifest: Manifest;
|
package/dist/index.d.ts
CHANGED
|
@@ -74,7 +74,7 @@ declare class PatchstackError extends Error {
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
type LockfileFilename = 'package-lock.json' | 'bun.lock' | 'bun.lockb' | 'yarn.lock' | 'pnpm-lock.yaml';
|
|
77
|
-
type DetectionStrategy = 'npm-lockfile' | 'node-modules-walk' | 'pnpm-lockfile' | 'yarn-lockfile';
|
|
77
|
+
type DetectionStrategy = 'npm-lockfile' | 'bun-lockfile' | 'node-modules-walk' | 'pnpm-lockfile' | 'yarn-lockfile';
|
|
78
78
|
interface DetectedLockfile {
|
|
79
79
|
ecosystem: 'npm';
|
|
80
80
|
filePath: string;
|
|
@@ -87,10 +87,45 @@ declare function scanLockfile(cwd: string): Promise<Manifest>;
|
|
|
87
87
|
interface WirePackage {
|
|
88
88
|
name: string;
|
|
89
89
|
version: string;
|
|
90
|
+
/**
|
|
91
|
+
* Where this exact name+version is installed, repo-relative and sorted.
|
|
92
|
+
*
|
|
93
|
+
* The same package can be installed more than once at different versions — a workspace pinning an old
|
|
94
|
+
* copy under `apps/api/node_modules`, a transitive dependency getting its own nested install. Without
|
|
95
|
+
* the locations, `lodash@4.17.11` and `lodash@4.17.21` arrive as two bare pairs and nothing can say
|
|
96
|
+
* WHICH one the app's own import resolves to. A consumer then has to treat every installed version as
|
|
97
|
+
* if the code used it: it warns on a copy nothing reaches, or pins a rule to a route running the safe
|
|
98
|
+
* one — a rule that never fires while reporting as protection.
|
|
99
|
+
*
|
|
100
|
+
* Node resolves an import by walking up from the importing file, so the map's import sites plus these
|
|
101
|
+
* paths together answer the question. Neither half answers it alone.
|
|
102
|
+
*
|
|
103
|
+
* OPT-IN. Absent unless the caller asks for locations (`scan --install-paths`), and absent even then
|
|
104
|
+
* when the scan source does not record them — see `installPathsComplete`, which is what separates
|
|
105
|
+
* "not installed there" from "we were not told".
|
|
106
|
+
*
|
|
107
|
+
* Off by default because it changes what leaves the machine. The package's standing promise is that
|
|
108
|
+
* `scan` sends names and versions and no paths of any kind; locations are a real widening of that, and
|
|
109
|
+
* an upload that widens it should be an explicit choice rather than a consequence of upgrading.
|
|
110
|
+
*/
|
|
111
|
+
paths?: string[];
|
|
90
112
|
}
|
|
91
113
|
interface WirePayload {
|
|
92
114
|
ecosystem: Manifest['ecosystem'];
|
|
93
115
|
packages: WirePackage[];
|
|
116
|
+
/**
|
|
117
|
+
* Whether every entry's `paths` is the complete set of locations for it.
|
|
118
|
+
*
|
|
119
|
+
* False when locations were not requested at all, when the scan source cannot supply them (a yarn.lock
|
|
120
|
+
* is flat — hoisting is decided at install time and the file does not record it; a v1 npm lockfile
|
|
121
|
+
* describes the dependency graph, not the tree), or when only some entries had one. A consumer MUST NOT
|
|
122
|
+
* read a missing or short `paths` as "installed nowhere else" while this is false; absence is then "not
|
|
123
|
+
* recorded", which is not an answer.
|
|
124
|
+
*
|
|
125
|
+
* The default is therefore `false`, and that is the safe direction: the field withholds a negative
|
|
126
|
+
* rather than granting one.
|
|
127
|
+
*/
|
|
128
|
+
installPathsComplete: boolean;
|
|
94
129
|
}
|
|
95
130
|
interface NormalizeStats {
|
|
96
131
|
uniqueNames: number;
|
|
@@ -101,7 +136,14 @@ interface NormalizeResult {
|
|
|
101
136
|
payload: WirePayload;
|
|
102
137
|
stats: NormalizeStats;
|
|
103
138
|
}
|
|
104
|
-
|
|
139
|
+
interface WireOptions {
|
|
140
|
+
/**
|
|
141
|
+
* Include each package's install location. Off by default — see `WirePackage.paths`: it widens what
|
|
142
|
+
* `scan` transmits, so it is the caller's explicit choice, not a side effect of upgrading.
|
|
143
|
+
*/
|
|
144
|
+
installPaths?: boolean;
|
|
145
|
+
}
|
|
146
|
+
declare function buildWirePayload(manifest: Manifest, options?: WireOptions): NormalizeResult;
|
|
105
147
|
declare function compareVersions(a: string, b: string): number;
|
|
106
148
|
|
|
107
149
|
declare const DEFAULT_ENDPOINT = "https://api.patchstack.com/monitor/pulse/manifest";
|
|
@@ -145,21 +187,40 @@ interface ResolveConfigOptions {
|
|
|
145
187
|
}
|
|
146
188
|
declare function resolveConfig(options: ResolveConfigOptions): Promise<Config>;
|
|
147
189
|
declare function writeConfigFile(cwd: string, config: ConfigFile): Promise<string>;
|
|
190
|
+
/**
|
|
191
|
+
* What happened to the credential file, so a caller can say only what is true.
|
|
192
|
+
*
|
|
193
|
+
* `ignored` is the OUTCOME of the ignore entry, verified by reading the file back — not the fact that a
|
|
194
|
+
* write was attempted. Telling somebody their credential is ignored when it is not is worse than telling
|
|
195
|
+
* them nothing: they stop looking, and a credential committed once is in the history whether or not the
|
|
196
|
+
* file is removed afterwards.
|
|
197
|
+
*/
|
|
198
|
+
interface SecretFileResult {
|
|
199
|
+
/** Absolute path of the credential file. */
|
|
200
|
+
path: string;
|
|
201
|
+
/** True only when `.gitignore` was read back and really covers it. */
|
|
202
|
+
ignored: boolean;
|
|
203
|
+
/** Why not, when it is not — for the caller to print instead of a false assurance. */
|
|
204
|
+
reason?: string;
|
|
205
|
+
}
|
|
148
206
|
/**
|
|
149
207
|
* Merge a new siteUuid into the existing `.patchstackrc.json` (or create it).
|
|
150
208
|
* Preserves any `endpoint` / `timeoutMs` / `apiKey` the user already wrote.
|
|
151
209
|
*/
|
|
152
210
|
declare function persistSiteUuid(cwd: string, siteUuid: string): Promise<string>;
|
|
153
211
|
/**
|
|
154
|
-
* Persist the WP-format api_key issued at provision. Authenticates both the
|
|
155
|
-
*
|
|
156
|
-
* disclosure widget.
|
|
212
|
+
* Persist the WP-format api_key issued at provision. Authenticates both the Pulse endpoints and connector
|
|
213
|
+
* log reporting. Never embed it in the public disclosure widget.
|
|
157
214
|
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
215
|
+
* Written to the credential file, which setup adds to the project's ignore list — the public config is
|
|
216
|
+
* meant to be committed, so a credential in it is a credential in the repository.
|
|
217
|
+
*
|
|
218
|
+
* Any copy in the committed config is REMOVED at the same time. Leaving it would mean the value that just
|
|
219
|
+
* got moved is still in the file everyone commits, which is the state this split exists to end. `pulseAuth`
|
|
220
|
+
* goes with it: that field resolves ahead of `apiKey`, so a stale copy would keep authenticating with a
|
|
221
|
+
* credential the server has replaced.
|
|
161
222
|
*/
|
|
162
|
-
declare function persistApiKey(cwd: string, apiKey: string): Promise<
|
|
223
|
+
declare function persistApiKey(cwd: string, apiKey: string): Promise<SecretFileResult>;
|
|
163
224
|
/**
|
|
164
225
|
* Persist a Pulse-specific credential.
|
|
165
226
|
*
|
|
@@ -167,7 +228,7 @@ declare function persistApiKey(cwd: string, apiKey: string): Promise<string>;
|
|
|
167
228
|
* credentials; they share one today, so `persistApiKey` covers both. Retained
|
|
168
229
|
* for callers that separate them.
|
|
169
230
|
*/
|
|
170
|
-
declare function persistPulseAuth(cwd: string, pulseAuth: string): Promise<
|
|
231
|
+
declare function persistPulseAuth(cwd: string, pulseAuth: string): Promise<SecretFileResult>;
|
|
171
232
|
|
|
172
233
|
/**
|
|
173
234
|
* A best-effort description of the stack a build was produced with, derived
|
|
@@ -251,6 +312,11 @@ declare function ensureSourceWidget(cwd: string, siteUuid: string): SourceWidget
|
|
|
251
312
|
interface ScanAndReportOptions {
|
|
252
313
|
cwd?: string;
|
|
253
314
|
config?: Config;
|
|
315
|
+
/**
|
|
316
|
+
* Include each package's install location in the uploaded payload. Off by default: it widens what
|
|
317
|
+
* leaves the machine, so it is an explicit choice rather than something an upgrade turns on.
|
|
318
|
+
*/
|
|
319
|
+
installPaths?: boolean;
|
|
254
320
|
}
|
|
255
321
|
interface ScanAndReportResult {
|
|
256
322
|
manifest: Manifest;
|