dropsh 0.6.0 → 0.7.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/README.md +223 -4
- package/dist/src/commands/connections.d.ts +37 -0
- package/dist/src/commands/connections.js +42 -0
- package/dist/src/commands/create.d.ts +6 -1
- package/dist/src/commands/create.js +1 -2
- package/dist/src/commands/update.d.ts +13 -1
- package/dist/src/commands/update.js +13 -5
- package/dist/src/core/auth/session-store.d.ts +2 -1
- package/dist/src/core/auth/session-store.js +4 -4
- package/dist/src/core/config.d.ts +2 -0
- package/dist/src/core/config.js +22 -3
- package/dist/src/core/connections.d.ts +58 -0
- package/dist/src/core/connections.js +115 -0
- package/dist/src/core/params/from-parameters.d.ts +12 -0
- package/dist/src/core/params/from-parameters.js +209 -0
- package/dist/src/core/params/help.d.ts +46 -0
- package/dist/src/core/params/help.js +148 -0
- package/dist/src/core/params/parse-args.d.ts +18 -0
- package/dist/src/core/params/parse-args.js +75 -0
- package/dist/src/core/params/schema-fields.d.ts +20 -0
- package/dist/src/core/params/schema-fields.js +65 -0
- package/dist/src/core/paths.d.ts +8 -0
- package/dist/src/core/paths.js +14 -0
- package/dist/src/index.d.ts +12 -0
- package/dist/src/index.js +214 -57
- package/dist/src/plugin-api.d.ts +5 -0
- package/dist/src/plugin-api.js +2 -0
- package/package.json +3 -3
package/dist/src/index.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { parseArgs } from "node:util";
|
|
3
3
|
import { Command } from "commander";
|
|
4
|
+
import { readDataArg } from "./commands/_data.js";
|
|
4
5
|
import { runAuthLogin, runAuthLogout, runAuthStatus, runAuthUse } from "./commands/auth.js";
|
|
6
|
+
import { renderConnectionsTable, runConnectionsList, } from "./commands/connections.js";
|
|
5
7
|
import { runCreate } from "./commands/create.js";
|
|
6
8
|
import { runDelete } from "./commands/delete.js";
|
|
7
9
|
import { runRead } from "./commands/read.js";
|
|
8
10
|
import { applyOperationSchemaPlugins, operationHookPluginIds, runSchema, SCHEMA_PIPELINE_VERSION, schemaCacheMetadataMatches, siteCacheRoot, } from "./commands/schema.js";
|
|
9
11
|
import { runSearch } from "./commands/search.js";
|
|
10
|
-
import { runUpdate } from "./commands/update.js";
|
|
12
|
+
import { assertUpdateTarget, runUpdate, } from "./commands/update.js";
|
|
11
13
|
import { runUploadFile } from "./commands/upload-file.js";
|
|
12
14
|
import { collectProviders, defaultProvider, providerById, sessionlessProvider, } from "./core/auth/registry.js";
|
|
13
15
|
import { readProfiles, writeProfile } from "./core/auth/session-store.js";
|
|
@@ -15,16 +17,17 @@ import { createFileStore } from "./core/cache/file-store.js";
|
|
|
15
17
|
import { createOutput } from "./core/cli/output.js";
|
|
16
18
|
import { createPrompt } from "./core/cli/prompt.js";
|
|
17
19
|
import { loadConfig } from "./core/config.js";
|
|
20
|
+
import { listConnections, resolveConfigSource, resolveConnectionsDir, } from "./core/connections.js";
|
|
18
21
|
import { createHttpClient } from "./core/http.js";
|
|
19
22
|
import { createJsonApiClient } from "./core/jsonapi/client.js";
|
|
23
|
+
import { buildPayloadFromParameters } from "./core/params/from-parameters.js";
|
|
24
|
+
import { describeFields, FIELD_PARAMETER_HELP, renderFieldsTable } from "./core/params/help.js";
|
|
25
|
+
import { parseFieldArgs } from "./core/params/parse-args.js";
|
|
20
26
|
import { composeRequestHooks } from "./core/request-hooks.js";
|
|
21
27
|
import { fetchJsonSchema } from "./core/schema/jsonschema-source.js";
|
|
22
28
|
import { toOperationVariant } from "./core/schema/to-jsonschema.js";
|
|
23
29
|
import { validatePayload } from "./core/schema/validate.js";
|
|
24
|
-
import { AuthError, ConfigError, exitCodeFor } from "./errors.js";
|
|
25
|
-
function resolveConfigPath(override) {
|
|
26
|
-
return override ?? process.env.DROPSH_CONFIG ?? "dropsh.config.js";
|
|
27
|
-
}
|
|
30
|
+
import { AuthError, ConfigError, exitCodeFor, ValidationError } from "./errors.js";
|
|
28
31
|
// Normalizes a variadic --include option into a flat, trimmed list of field
|
|
29
32
|
// names: splits any comma-containing entries (so both `--include a,b` and
|
|
30
33
|
// `--include a b` work) and drops empty strings.
|
|
@@ -149,7 +152,9 @@ export function buildProgram(opts = {}) {
|
|
|
149
152
|
.name("dropsh")
|
|
150
153
|
.description("Entity-agnostic CLI for Drupal 11 JSON:API")
|
|
151
154
|
.version("0.0.0")
|
|
152
|
-
.option("--config <path>", "path to config file (overrides
|
|
155
|
+
.option("--config <path>", "path to config file (overrides every id-based selector)")
|
|
156
|
+
.option("--connection <id>", "named connection to use: <connections-dir>/<id>.js (overrides $DROPSH_CONFIG)")
|
|
157
|
+
.option("--connections-dir <path>", "where named connections live (overrides $DROPSH_CONNECTIONS_DIR)")
|
|
153
158
|
.option("--auth-profile <id>", "auth profile to use (overrides the active profile and $DROPSH_AUTH_PROFILE)")
|
|
154
159
|
.option("--format <id>", "output format: json (default) or a renderer id", "json")
|
|
155
160
|
.option("--view-mode <name>", "entity view mode for interactive formats", "default");
|
|
@@ -159,11 +164,28 @@ export function buildProgram(opts = {}) {
|
|
|
159
164
|
((c) => {
|
|
160
165
|
process.exitCode = c;
|
|
161
166
|
});
|
|
167
|
+
/** The connections directory for this invocation: `--connections-dir` > env > default. */
|
|
168
|
+
function currentConnectionsDir() {
|
|
169
|
+
return resolveConnectionsDir({ flag: program.opts().connectionsDir });
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* The config file this invocation resolves to, and why. Every caller — the
|
|
173
|
+
* command context, the auth wiring, and `connections list` — reads this one
|
|
174
|
+
* answer, so what the listing claims and what the next command does cannot
|
|
175
|
+
* disagree.
|
|
176
|
+
*/
|
|
177
|
+
function currentConfigSource() {
|
|
178
|
+
const o = program.opts();
|
|
179
|
+
return resolveConfigSource({
|
|
180
|
+
config: o.config,
|
|
181
|
+
connection: o.connection,
|
|
182
|
+
connectionsDir: currentConnectionsDir(),
|
|
183
|
+
});
|
|
184
|
+
}
|
|
162
185
|
const contextFactory = opts.contextFactory ??
|
|
163
186
|
(() => {
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
return defaultContext(resolveConfigPath(o.config), profile);
|
|
187
|
+
const profile = program.opts().authProfile ?? process.env.DROPSH_AUTH_PROFILE;
|
|
188
|
+
return defaultContext(currentConfigSource().path, profile);
|
|
167
189
|
});
|
|
168
190
|
const renderers = (opts.plugins ?? []).flatMap((p) => p.renderers ?? []);
|
|
169
191
|
const output = createOutput({
|
|
@@ -201,6 +223,73 @@ export function buildProgram(opts = {}) {
|
|
|
201
223
|
throw new ConfigError(`Unknown format '${f}'. Available: ${["json", ...renderers.map((r) => r.id)].join(", ")}`);
|
|
202
224
|
}
|
|
203
225
|
}
|
|
226
|
+
/**
|
|
227
|
+
* Print a resolved schema as its field listing: a table for a human, or the
|
|
228
|
+
* same data verbatim on an explicit `--format json`. Shared by `create`,
|
|
229
|
+
* `update` and `schema`, so the three cannot drift.
|
|
230
|
+
*/
|
|
231
|
+
function emitFieldListing(schema, rctx) {
|
|
232
|
+
const described = describeFields(schema);
|
|
233
|
+
if (program.getOptionValueSource("format") === "default") {
|
|
234
|
+
stdout(`${renderFieldsTable(described)}\n`);
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
output.emit(described, rctx);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* The write-command wiring `create` and `update` share: decide `--data` vs
|
|
242
|
+
* field parameters, fetch the operation schema at most once, build the payload
|
|
243
|
+
* from the parameters, and hand back the args/deps both `runCreate` and
|
|
244
|
+
* `runUpdate` accept. The two commands differ only in how they identify their
|
|
245
|
+
* target, which is why that part stays in each action.
|
|
246
|
+
*/
|
|
247
|
+
async function writeWiring(input) {
|
|
248
|
+
const { ctx, options } = input;
|
|
249
|
+
// --fields is a discovery request, not a write: resolve the schema through
|
|
250
|
+
// the normal fetch-and-cache pipeline, print the parameters, send nothing.
|
|
251
|
+
// It reads as a table because a human asked what the fields are; an explicit
|
|
252
|
+
// --format json hands back the same data verbatim for a caller to consume.
|
|
253
|
+
if (options.fields === true) {
|
|
254
|
+
emitFieldListing(await loadOrFetchSchema(ctx, input.schemaTarget, input.operation), input.rctx);
|
|
255
|
+
return "listed";
|
|
256
|
+
}
|
|
257
|
+
// Exactly one route produces the document, and it is settled here so the
|
|
258
|
+
// command itself only ever receives a finished payload.
|
|
259
|
+
const fields = parseFieldArgs(input.tokens);
|
|
260
|
+
if (options.data !== undefined && fields.length > 0) {
|
|
261
|
+
throw new ValidationError("--data and field parameters are mutually exclusive; use one or the other");
|
|
262
|
+
}
|
|
263
|
+
if (options.data === undefined && fields.length === 0) {
|
|
264
|
+
throw new ValidationError("provide either --data or field parameters (--<field> <value>)");
|
|
265
|
+
}
|
|
266
|
+
let cached;
|
|
267
|
+
const schema = async () => (cached ??= await loadOrFetchSchema(ctx, input.schemaTarget, input.operation));
|
|
268
|
+
let payload;
|
|
269
|
+
if (options.data !== undefined) {
|
|
270
|
+
payload = await readDataArg(options.data);
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
input.guard?.();
|
|
274
|
+
payload = buildPayloadFromParameters({
|
|
275
|
+
schema: await schema(),
|
|
276
|
+
parameters: fields,
|
|
277
|
+
operation: input.operation,
|
|
278
|
+
...(input.id !== undefined ? { id: input.id } : {}),
|
|
279
|
+
resourceType: input.resourceType,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
const args = { payload };
|
|
283
|
+
if (options.dryRun !== undefined)
|
|
284
|
+
args.dryRun = options.dryRun;
|
|
285
|
+
if (options.validate === false)
|
|
286
|
+
args.noValidate = true;
|
|
287
|
+
const deps = { client: ctx.client, emit: (v) => output.emit(v, input.rctx) };
|
|
288
|
+
if (!args.noValidate) {
|
|
289
|
+
deps.validate = async (payload, t) => validatePayload(await schema(), payload, t);
|
|
290
|
+
}
|
|
291
|
+
return { args, deps };
|
|
292
|
+
}
|
|
204
293
|
function assertJsonOnly(command) {
|
|
205
294
|
const f = currentFormat();
|
|
206
295
|
if (f !== "json") {
|
|
@@ -208,7 +297,7 @@ export function buildProgram(opts = {}) {
|
|
|
208
297
|
}
|
|
209
298
|
}
|
|
210
299
|
async function authDeps() {
|
|
211
|
-
const cfg = await loadConfig(
|
|
300
|
+
const cfg = await loadConfig(currentConfigSource().path);
|
|
212
301
|
return {
|
|
213
302
|
baseUrl: cfg.site.base_url,
|
|
214
303
|
providers: collectProviders(cfg.plugins),
|
|
@@ -347,54 +436,61 @@ Example:
|
|
|
347
436
|
.command("create <entity_type>")
|
|
348
437
|
.description("Create an entity of given type/bundle")
|
|
349
438
|
.requiredOption("--bundle <bundle>")
|
|
350
|
-
.
|
|
439
|
+
.option("--data <json>", "inline JSON or @path")
|
|
351
440
|
.option("--dry-run")
|
|
352
441
|
.option("--no-validate", "skip client-side schema validation")
|
|
353
|
-
.
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
if (o.validate === false)
|
|
358
|
-
args.noValidate = true;
|
|
442
|
+
.option("--fields", "list this bundle's field parameters and exit")
|
|
443
|
+
.allowUnknownOption()
|
|
444
|
+
.addHelpText("after", FIELD_PARAMETER_HELP)
|
|
445
|
+
.action((entityType, o, cmd) => {
|
|
359
446
|
return run(async (ctx) => {
|
|
360
|
-
const
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
|
|
447
|
+
const wiring = await writeWiring({
|
|
448
|
+
ctx,
|
|
449
|
+
operation: "create",
|
|
450
|
+
schemaTarget: `${entityType}/${o.bundle}`,
|
|
451
|
+
resourceType: `${entityType}--${o.bundle}`,
|
|
452
|
+
tokens: cmd.args.slice(1),
|
|
453
|
+
rctx: { command: "create", entityType, bundle: o.bundle },
|
|
454
|
+
options: o,
|
|
455
|
+
});
|
|
456
|
+
if (wiring === "listed")
|
|
457
|
+
return;
|
|
458
|
+
await runCreate({ entityType, bundle: o.bundle, ...wiring.args }, wiring.deps);
|
|
369
459
|
}, assertRenderable);
|
|
370
460
|
});
|
|
371
461
|
program
|
|
372
462
|
.command("update <target>")
|
|
373
463
|
.description("Update an existing entity")
|
|
374
|
-
.
|
|
464
|
+
.option("--data <json>", "inline JSON or @path")
|
|
375
465
|
.option("--dry-run")
|
|
376
466
|
.option("--no-validate", "skip client-side schema validation")
|
|
377
|
-
.
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
if (o.validate === false)
|
|
382
|
-
args.noValidate = true;
|
|
467
|
+
.option("--fields", "list this bundle's field parameters and exit")
|
|
468
|
+
.allowUnknownOption()
|
|
469
|
+
.addHelpText("after", FIELD_PARAMETER_HELP)
|
|
470
|
+
.action((target, o, cmd) => {
|
|
383
471
|
return run(async (ctx) => {
|
|
384
|
-
const [entityType, bundle] = target.split("/");
|
|
472
|
+
const [entityType, bundle, id] = target.split("/");
|
|
385
473
|
const rctx = { command: "update", target };
|
|
386
474
|
if (entityType !== undefined)
|
|
387
475
|
rctx.entityType = entityType;
|
|
388
476
|
if (bundle !== undefined)
|
|
389
477
|
rctx.bundle = bundle;
|
|
390
|
-
const
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
478
|
+
const wiring = await writeWiring({
|
|
479
|
+
ctx,
|
|
480
|
+
operation: "update",
|
|
481
|
+
schemaTarget: `${entityType}/${bundle}`,
|
|
482
|
+
resourceType: `${entityType}--${bundle}`,
|
|
483
|
+
tokens: cmd.args.slice(1),
|
|
484
|
+
rctx,
|
|
485
|
+
options: o,
|
|
486
|
+
...(id !== undefined ? { id } : {}),
|
|
487
|
+
// Guard the target before building, so a malformed one is reported by
|
|
488
|
+
// its own message rather than as a missing data.id.
|
|
489
|
+
guard: () => assertUpdateTarget(target),
|
|
490
|
+
});
|
|
491
|
+
if (wiring === "listed")
|
|
492
|
+
return;
|
|
493
|
+
await runUpdate({ target, ...wiring.args }, wiring.deps);
|
|
398
494
|
}, assertRenderable);
|
|
399
495
|
});
|
|
400
496
|
program
|
|
@@ -426,22 +522,51 @@ Example:
|
|
|
426
522
|
.description("Catalog (no target) or JSON Schema for <entity>/<bundle>")
|
|
427
523
|
.option("--for <op>", "create|update", "create")
|
|
428
524
|
.option("--refresh", "bypass cache for this call")
|
|
525
|
+
.option("--fields", "list the target's field parameters instead of its schema")
|
|
429
526
|
.action((target, o) => {
|
|
430
527
|
const operation = o.for === "update" ? "update" : "create";
|
|
431
528
|
const schemaArgs = target !== undefined
|
|
432
529
|
? { target, operation, refresh: Boolean(o.refresh) }
|
|
433
530
|
: { operation, refresh: Boolean(o.refresh) };
|
|
434
|
-
return run((ctx) =>
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
531
|
+
return run((ctx) => {
|
|
532
|
+
if (o.fields === true && target === undefined) {
|
|
533
|
+
throw new ValidationError("--fields needs a target: dropsh schema <entity_type>/<bundle> --fields");
|
|
534
|
+
}
|
|
535
|
+
// --fields is the same schema, viewed as its parameters: swapping the
|
|
536
|
+
// emitter inherits runSchema's caching and --refresh untouched.
|
|
537
|
+
return runSchema(schemaArgs, {
|
|
538
|
+
http: ctx.http,
|
|
539
|
+
auth: ctx.auth,
|
|
540
|
+
baseUrl: ctx.baseUrl,
|
|
541
|
+
jsonapiPrefix: ctx.jsonapiPrefix,
|
|
542
|
+
cwd: ctx.cwd,
|
|
543
|
+
emit: o.fields === true ? (schema) => emitFieldListing(schema) : output.emit,
|
|
544
|
+
warn: (m) => stderr(`${m}\n`),
|
|
545
|
+
plugins: ctx.plugins,
|
|
546
|
+
});
|
|
547
|
+
}, () => assertJsonOnly("schema"));
|
|
444
548
|
});
|
|
549
|
+
const connections = program.command("connections").description("Manage named connections");
|
|
550
|
+
connections
|
|
551
|
+
.command("list")
|
|
552
|
+
.description("List the connections in the resolved connections directory")
|
|
553
|
+
.action(() =>
|
|
554
|
+
// Builds no CommandContext, so it works with no cwd config present.
|
|
555
|
+
run2(async () => {
|
|
556
|
+
await runConnectionsList({ dir: currentConnectionsDir(), resolved: currentConfigSource() }, {
|
|
557
|
+
list: listConnections,
|
|
558
|
+
// A table because a human asked what the connections are; an
|
|
559
|
+
// explicit --format json hands back the same data verbatim.
|
|
560
|
+
emit: (v) => {
|
|
561
|
+
if (program.getOptionValueSource("format") === "default") {
|
|
562
|
+
stdout(`${renderConnectionsTable(v)}\n`);
|
|
563
|
+
}
|
|
564
|
+
else {
|
|
565
|
+
output.emit(v);
|
|
566
|
+
}
|
|
567
|
+
},
|
|
568
|
+
});
|
|
569
|
+
}));
|
|
445
570
|
const auth = program.command("auth").description("Manage authentication");
|
|
446
571
|
auth
|
|
447
572
|
.command("login")
|
|
@@ -472,17 +597,49 @@ Example:
|
|
|
472
597
|
program.exitOverride();
|
|
473
598
|
return program;
|
|
474
599
|
}
|
|
475
|
-
|
|
600
|
+
/**
|
|
601
|
+
* The config selectors as they appear in raw argv, for the pre-parse plugin
|
|
602
|
+
* bootstrap — which runs before commander sees any option. It feeds the same
|
|
603
|
+
* resolver the commands use, so the early and the late resolution cannot answer
|
|
604
|
+
* differently and load plugins from a different connection than the command
|
|
605
|
+
* being bootstrapped.
|
|
606
|
+
*/
|
|
607
|
+
export function earlyConfigArgs(argv) {
|
|
476
608
|
const { values } = parseArgs({
|
|
477
609
|
args: argv.slice(2),
|
|
478
|
-
options: {
|
|
610
|
+
options: {
|
|
611
|
+
config: { type: "string" },
|
|
612
|
+
connection: { type: "string" },
|
|
613
|
+
"connections-dir": { type: "string" },
|
|
614
|
+
},
|
|
479
615
|
strict: false,
|
|
480
616
|
});
|
|
481
|
-
|
|
617
|
+
const str = (v) => (typeof v === "string" ? v : undefined);
|
|
618
|
+
const config = str(values.config);
|
|
619
|
+
const connection = str(values.connection);
|
|
620
|
+
const connectionsDir = str(values["connections-dir"]);
|
|
621
|
+
return {
|
|
622
|
+
...(config !== undefined ? { config } : {}),
|
|
623
|
+
...(connection !== undefined ? { connection } : {}),
|
|
624
|
+
...(connectionsDir !== undefined ? { connectionsDir } : {}),
|
|
625
|
+
};
|
|
482
626
|
}
|
|
483
627
|
export async function main() {
|
|
484
|
-
const
|
|
485
|
-
|
|
628
|
+
const early = earlyConfigArgs(process.argv);
|
|
629
|
+
// An unresolvable selector is not reported here: the bootstrap only collects
|
|
630
|
+
// plugins, and commander's own resolution raises the error with its exit code.
|
|
631
|
+
const configPath = (() => {
|
|
632
|
+
try {
|
|
633
|
+
return resolveConfigSource({
|
|
634
|
+
...early,
|
|
635
|
+
connectionsDir: resolveConnectionsDir({ flag: early.connectionsDir }),
|
|
636
|
+
}).path;
|
|
637
|
+
}
|
|
638
|
+
catch {
|
|
639
|
+
return null;
|
|
640
|
+
}
|
|
641
|
+
})();
|
|
642
|
+
const cfg = configPath === null ? null : await loadConfig(configPath).catch(() => null);
|
|
486
643
|
const plugins = cfg?.plugins ?? [];
|
|
487
644
|
const program = buildProgram({ plugins });
|
|
488
645
|
try {
|
package/dist/src/plugin-api.d.ts
CHANGED
|
@@ -12,6 +12,11 @@ export { createJsonApiClient } from "./core/jsonapi/client.js";
|
|
|
12
12
|
export type { Collection, FilterOp } from "./core/jsonapi/collection.js";
|
|
13
13
|
export type { JsonApiResourceObject, Resource, } from "./core/jsonapi/resource.js";
|
|
14
14
|
export type { JsonApiDocument, JsonApiResource } from "./core/jsonapi/types.js";
|
|
15
|
+
export type { BuildPayloadInput } from "./core/params/from-parameters.js";
|
|
16
|
+
export { buildPayloadFromParameters } from "./core/params/from-parameters.js";
|
|
17
|
+
export type { RawParameter } from "./core/params/parse-args.js";
|
|
18
|
+
export type { FieldDescriptor, SchemaFieldIndex } from "./core/params/schema-fields.js";
|
|
19
|
+
export { indexSchemaFields, propertiesOf } from "./core/params/schema-fields.js";
|
|
15
20
|
export type { DropSHPlugin, PluginContext, PluginDescriptor, RequestContext, SchemaOperation, } from "./core/plugin.js";
|
|
16
21
|
export { composePlugins } from "./core/plugin.js";
|
|
17
22
|
export { AuthError, ConfigError, HttpError, PluginError } from "./errors.js";
|
package/dist/src/plugin-api.js
CHANGED
|
@@ -3,5 +3,7 @@ export { indexIncluded, isInteractive } from "./core/cli/render.js";
|
|
|
3
3
|
export { loadConfig } from "./core/config.js";
|
|
4
4
|
export { createHttpClient } from "./core/http.js";
|
|
5
5
|
export { createJsonApiClient } from "./core/jsonapi/client.js";
|
|
6
|
+
export { buildPayloadFromParameters } from "./core/params/from-parameters.js";
|
|
7
|
+
export { indexSchemaFields, propertiesOf } from "./core/params/schema-fields.js";
|
|
6
8
|
export { composePlugins } from "./core/plugin.js";
|
|
7
9
|
export { AuthError, ConfigError, HttpError, PluginError } from "./errors.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dropsh",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Entity-agnostic helper CLI for Drupal 11 JSON:API, used by the dropsh Claude skill for editorial publishing workflows.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -66,8 +66,8 @@
|
|
|
66
66
|
"test:watch": "vitest",
|
|
67
67
|
"test:integration": "pnpm run build && pnpm run build:packages && vitest run -c vitest.config.integration.ts",
|
|
68
68
|
"typecheck": "pnpm run build:packages && tsc --noEmit && pnpm -r run typecheck",
|
|
69
|
-
"lint": "biome check src/ packages/ plugins/ tests/integrations/helpers/ tests/integrations/schema/ tests/integrations/*.ts",
|
|
70
|
-
"lint:fix": "biome check --write src/ packages/ plugins/ tests/integrations/helpers/ tests/integrations/schema/ tests/integrations/*.ts",
|
|
69
|
+
"lint": "biome check src/ packages/ plugins/ tests/integrations/helpers/ tests/integrations/params/ tests/integrations/schema/ tests/integrations/*.ts",
|
|
70
|
+
"lint:fix": "biome check --write src/ packages/ plugins/ tests/integrations/helpers/ tests/integrations/params/ tests/integrations/schema/ tests/integrations/*.ts",
|
|
71
71
|
"drupal:up": "bash tests/integrations/bin/drupal-up.sh",
|
|
72
72
|
"drupal:down": "bash tests/integrations/bin/drupal-down.sh",
|
|
73
73
|
"init-worktree": "node scripts/init-worktree.mjs",
|