primitive-admin 1.1.0-alpha.45 → 1.1.0-alpha.46
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/dist/bin/primitive.js +2 -0
- package/dist/bin/primitive.js.map +1 -1
- package/dist/src/commands/collections.js +11 -0
- package/dist/src/commands/collections.js.map +1 -1
- package/dist/src/commands/databases.js +34 -49
- package/dist/src/commands/databases.js.map +1 -1
- package/dist/src/commands/sync.js +3 -0
- package/dist/src/commands/sync.js.map +1 -1
- package/dist/src/commands/vars.d.ts +8 -0
- package/dist/src/commands/vars.js +110 -0
- package/dist/src/commands/vars.js.map +1 -0
- package/dist/src/commands/workflows.js +23 -82
- package/dist/src/commands/workflows.js.map +1 -1
- package/dist/src/lib/api-client.d.ts +9 -0
- package/dist/src/lib/api-client.js +15 -0
- package/dist/src/lib/api-client.js.map +1 -1
- package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.d.ts +68 -0
- package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js +168 -0
- package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js.map +1 -0
- package/dist/src/lib/generated-allowlist.js +2 -0
- package/dist/src/lib/generated-allowlist.js.map +1 -1
- package/dist/src/lib/toml-metadata-config.d.ts +10 -2
- package/dist/src/lib/toml-metadata-config.js +51 -15
- package/dist/src/lib/toml-metadata-config.js.map +1 -1
- package/dist/src/lib/workflow-codegen/generated-schema-descriptor.d.ts +33 -0
- package/dist/src/lib/workflow-codegen/generated-schema-descriptor.js +158 -1
- package/dist/src/lib/workflow-codegen/generated-schema-descriptor.js.map +1 -1
- package/dist/src/lib/workflow-codegen/generator.d.ts +6 -2
- package/dist/src/lib/workflow-codegen/generator.js +35 -6
- package/dist/src/lib/workflow-codegen/generator.js.map +1 -1
- package/dist/src/lib/workflow-codegen/schemaToTs.d.ts +13 -4
- package/dist/src/lib/workflow-codegen/schemaToTs.js +49 -4
- package/dist/src/lib/workflow-codegen/schemaToTs.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
/**
|
|
3
|
+
* `primitive vars` — non-secret per-app config scalars (issue #1364). The
|
|
4
|
+
* plaintext twin of `primitive secrets`: same key format and limits, but
|
|
5
|
+
* values are NOT secret — `list` shows them, and they appear unmasked in
|
|
6
|
+
* debug traces. Never store a credential in a var; use `primitive secrets`.
|
|
7
|
+
*/
|
|
8
|
+
export declare function registerVarsCommands(program: Command): void;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { ApiClient } from "../lib/api-client.js";
|
|
2
|
+
import { resolveAppId } from "../lib/config.js";
|
|
3
|
+
import { success, error, info, keyValue, formatTable, formatDate, json, } from "../lib/output.js";
|
|
4
|
+
/**
|
|
5
|
+
* `primitive vars` — non-secret per-app config scalars (issue #1364). The
|
|
6
|
+
* plaintext twin of `primitive secrets`: same key format and limits, but
|
|
7
|
+
* values are NOT secret — `list` shows them, and they appear unmasked in
|
|
8
|
+
* debug traces. Never store a credential in a var; use `primitive secrets`.
|
|
9
|
+
*/
|
|
10
|
+
export function registerVarsCommands(program) {
|
|
11
|
+
const vars = program
|
|
12
|
+
.command("vars")
|
|
13
|
+
.description("Manage non-secret app config vars (values are visible; use secrets for credentials)")
|
|
14
|
+
.addHelpText("after", `
|
|
15
|
+
Examples:
|
|
16
|
+
$ primitive vars list
|
|
17
|
+
$ primitive vars set ADMIN_GROUP_ID --value grp_01ABC --summary "Admins group id"
|
|
18
|
+
$ primitive vars set ADMIN_GROUP_ID --value grp_01NEW (updates existing)
|
|
19
|
+
$ primitive vars delete ADMIN_GROUP_ID
|
|
20
|
+
|
|
21
|
+
Vars bind into CEL rules via the declared \`vars.*\` namespace — declare them
|
|
22
|
+
with \`vars = ["ADMIN_GROUP_ID"]\` in the config's access manifest.
|
|
23
|
+
`);
|
|
24
|
+
// List vars (values shown — non-secret)
|
|
25
|
+
vars
|
|
26
|
+
.command("list")
|
|
27
|
+
.description("List all config vars for an app (values are shown)")
|
|
28
|
+
.option("--app <app-id>", "App ID (uses current app if not specified)")
|
|
29
|
+
.option("--json", "Output as JSON")
|
|
30
|
+
.action(async (options) => {
|
|
31
|
+
const resolvedAppId = resolveAppId(undefined, options);
|
|
32
|
+
const client = new ApiClient();
|
|
33
|
+
try {
|
|
34
|
+
const varsList = await client.listAppConfigVars(resolvedAppId);
|
|
35
|
+
if (options.json) {
|
|
36
|
+
json(varsList);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (!varsList || varsList.length === 0) {
|
|
40
|
+
info("No vars found.");
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
console.log(formatTable(varsList, [
|
|
44
|
+
{ header: "KEY", key: "key" },
|
|
45
|
+
{ header: "VALUE", key: "value" },
|
|
46
|
+
{ header: "SUMMARY", key: "summary" },
|
|
47
|
+
{ header: "CREATED", key: "createdAt", format: formatDate },
|
|
48
|
+
{ header: "UPDATED", key: "updatedAt", format: formatDate },
|
|
49
|
+
]));
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
error(err.message);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
// Set var (create or update — by-key upsert)
|
|
57
|
+
vars
|
|
58
|
+
.command("set")
|
|
59
|
+
.description("Create or update a config var")
|
|
60
|
+
.argument("<key>", "Var key (e.g., ADMIN_GROUP_ID)")
|
|
61
|
+
.option("--value <value>", "Var value (non-secret)")
|
|
62
|
+
.option("--summary <text>", "Description of the var")
|
|
63
|
+
.option("--app <app-id>", "App ID (uses current app if not specified)")
|
|
64
|
+
.option("--json", "Output as JSON")
|
|
65
|
+
.action(async (key, options) => {
|
|
66
|
+
const resolvedAppId = resolveAppId(undefined, options);
|
|
67
|
+
if (!options.value) {
|
|
68
|
+
error("--value is required");
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
const client = new ApiClient();
|
|
72
|
+
try {
|
|
73
|
+
const payload = { value: options.value };
|
|
74
|
+
if (options.summary !== undefined) {
|
|
75
|
+
payload.summary = options.summary;
|
|
76
|
+
}
|
|
77
|
+
const result = await client.upsertAppConfigVar(resolvedAppId, key, payload);
|
|
78
|
+
if (options.json) {
|
|
79
|
+
json(result);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
success(`Var '${key}' saved.`);
|
|
83
|
+
keyValue("Key", result?.key || key);
|
|
84
|
+
keyValue("Value", result?.value ?? options.value);
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
error(err.message);
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
// Delete var (key-addressed — no id lookup needed)
|
|
92
|
+
vars
|
|
93
|
+
.command("delete")
|
|
94
|
+
.description("Delete a config var")
|
|
95
|
+
.argument("<key>", "Var key (e.g., ADMIN_GROUP_ID)")
|
|
96
|
+
.option("--app <app-id>", "App ID (uses current app if not specified)")
|
|
97
|
+
.action(async (key, options) => {
|
|
98
|
+
const resolvedAppId = resolveAppId(undefined, options);
|
|
99
|
+
const client = new ApiClient();
|
|
100
|
+
try {
|
|
101
|
+
await client.deleteAppConfigVar(resolvedAppId, key);
|
|
102
|
+
success(`Var '${key}' deleted.`);
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
error(err.message);
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=vars.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vars.js","sourceRoot":"","sources":["../../../src/commands/vars.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readFileSync, writeFileSync, statSync,
|
|
1
|
+
import { readFileSync, writeFileSync, statSync, readdirSync, } from "fs";
|
|
2
2
|
import { basename } from "path";
|
|
3
3
|
import * as path from "path";
|
|
4
4
|
import { parseConfigToml, stringifyConfigToml } from "../lib/config-toml.js";
|
|
@@ -6,6 +6,7 @@ import { lookup as mimeLookup } from "mime-types";
|
|
|
6
6
|
import { generateWorkflowTypes, } from "../lib/workflow-codegen/generator.js";
|
|
7
7
|
import { ApiClient } from "../lib/api-client.js";
|
|
8
8
|
import { resolveAppId } from "../lib/config.js";
|
|
9
|
+
import { resolveCodegenSourceDir } from "../lib/codegen-shared/resolveCodegenSourceDir.js";
|
|
9
10
|
import { validateWorkflowToml, formatWorkflowTomlErrors, } from "../lib/workflow-toml-validator.js";
|
|
10
11
|
import { expandWorkflow } from "../lib/workflow-fragments.js";
|
|
11
12
|
import { buildWorkflowPayloadFromToml } from "../lib/workflow-payload.js";
|
|
@@ -2472,91 +2473,31 @@ Examples:
|
|
|
2472
2473
|
.option("--json", "Output the result summary as JSON")
|
|
2473
2474
|
.action(async (workflowKey, options) => {
|
|
2474
2475
|
try {
|
|
2475
|
-
// 1.
|
|
2476
|
-
//
|
|
2477
|
-
//
|
|
2478
|
-
//
|
|
2479
|
-
//
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
const candidate = path.join(options.syncDir, "workflows");
|
|
2485
|
-
if (existsSync(candidate)) {
|
|
2486
|
-
workflowDirs.push(candidate);
|
|
2487
|
-
}
|
|
2488
|
-
}
|
|
2489
|
-
else {
|
|
2490
|
-
const root = path.join(process.cwd(), ".primitive", "sync");
|
|
2491
|
-
if (existsSync(root)) {
|
|
2492
|
-
for (const env of readdirSync(root)) {
|
|
2493
|
-
const envDir = path.join(root, env);
|
|
2494
|
-
try {
|
|
2495
|
-
for (const app of readdirSync(envDir)) {
|
|
2496
|
-
if (options.app && app !== options.app)
|
|
2497
|
-
continue;
|
|
2498
|
-
const candidate = path.join(envDir, app, "workflows");
|
|
2499
|
-
if (existsSync(candidate)) {
|
|
2500
|
-
workflowDirs.push(candidate);
|
|
2501
|
-
}
|
|
2502
|
-
}
|
|
2503
|
-
}
|
|
2504
|
-
catch {
|
|
2505
|
-
// skip non-dirs
|
|
2506
|
-
}
|
|
2507
|
-
}
|
|
2508
|
-
}
|
|
2509
|
-
}
|
|
2510
|
-
if (workflowDirs.length === 0) {
|
|
2511
|
-
error(options.app
|
|
2512
|
-
? `No workflows/ directory found for app "${options.app}" under .primitive/sync/. Check the --app id, pass --sync-dir, or run \`primitive sync pull\` first.`
|
|
2513
|
-
: "No workflows/ directory found. Pass --sync-dir or run `primitive sync pull` first.");
|
|
2514
|
-
process.exit(1);
|
|
2515
|
-
}
|
|
2516
|
-
// Codegen writes one <key>.generated.ts per workflow into a single
|
|
2517
|
-
// output dir derived from the first source dir below. Generating from
|
|
2518
|
-
// more than one discovered workflows/ directory (multiple apps, or the
|
|
2519
|
-
// same app across multiple synced envs) would combine unrelated apps'
|
|
2520
|
-
// workflows into the first one's output dir and write nothing for the
|
|
2521
|
-
// rest. Require the caller to disambiguate rather than combining.
|
|
2522
|
-
if (workflowDirs.length > 1) {
|
|
2523
|
-
const appsFound = [
|
|
2524
|
-
...new Set(workflowDirs.map((d) => path.basename(path.dirname(d)))),
|
|
2525
|
-
];
|
|
2526
|
-
error(`Found workflows/ directories for more than one app/env:\n` +
|
|
2527
|
-
workflowDirs
|
|
2528
|
-
.map((d) => ` ${path.relative(process.cwd(), d)}`)
|
|
2529
|
-
.join("\n") +
|
|
2530
|
-
`\nCodegen writes into one output dir, so it must run against` +
|
|
2531
|
-
` one app. ` +
|
|
2532
|
-
(options.app
|
|
2533
|
-
? `App "${options.app}" resolves to multiple synced envs — pass --sync-dir to pick one.`
|
|
2534
|
-
: `Pass --app <app-id> (found: ${appsFound.join(", ")}) or` +
|
|
2535
|
-
` --sync-dir to select one.`));
|
|
2536
|
-
process.exit(1);
|
|
2537
|
-
}
|
|
2476
|
+
// 1. Resolve the single source workflows/ directory via the shared
|
|
2477
|
+
// active-environment resolver (issue #1510). Honors --sync-dir /
|
|
2478
|
+
// --app overrides, resolves the active env
|
|
2479
|
+
// (--env → PRIMITIVE_ENV → defaultEnvironment → single-env), and
|
|
2480
|
+
// preserves the legacy per-app scan fallback in bare-dir mode.
|
|
2481
|
+
const workflowsSourceDir = resolveCodegenSourceDir({
|
|
2482
|
+
subdir: "workflows",
|
|
2483
|
+
options: { app: options.app, syncDir: options.syncDir },
|
|
2484
|
+
});
|
|
2538
2485
|
// 2. Collect the source .toml files (one per workflow), filtered to a
|
|
2539
2486
|
// single workflow when an argument is given. Match on the file stem;
|
|
2540
2487
|
// the generator resolves the real key from `[workflow].key`.
|
|
2541
2488
|
const inputs = [];
|
|
2542
|
-
const
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
inputs.push({
|
|
2555
|
-
fileStem: stem,
|
|
2556
|
-
tomlPath,
|
|
2557
|
-
tomlContent: readFileSync(tomlPath, "utf-8"),
|
|
2558
|
-
});
|
|
2559
|
-
}
|
|
2489
|
+
for (const fileName of readdirSync(workflowsSourceDir)) {
|
|
2490
|
+
if (!fileName.endsWith(".toml"))
|
|
2491
|
+
continue;
|
|
2492
|
+
const stem = fileName.slice(0, -".toml".length);
|
|
2493
|
+
if (workflowKey && stem !== workflowKey)
|
|
2494
|
+
continue;
|
|
2495
|
+
const tomlPath = path.join(workflowsSourceDir, fileName);
|
|
2496
|
+
inputs.push({
|
|
2497
|
+
fileStem: stem,
|
|
2498
|
+
tomlPath,
|
|
2499
|
+
tomlContent: readFileSync(tomlPath, "utf-8"),
|
|
2500
|
+
});
|
|
2560
2501
|
}
|
|
2561
2502
|
if (inputs.length === 0) {
|
|
2562
2503
|
error(workflowKey
|