@quatronic/qore 0.1.9 → 0.2.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/dist/cli.js +104 -7
- package/package.json +1 -1
- package/viewer/dist/assets/{elk.bundled-C8gcDXx2.js → elk.bundled-De6CfWzt.js} +1 -1
- package/viewer/dist/assets/{index-BRgYtLRN.css → index-C0qjacg4.css} +1 -1
- package/viewer/dist/assets/{index-VDGZO23h.js → index-DKF4ZW0j.js} +2 -2
- package/viewer/dist/index.html +2 -2
package/README.md
CHANGED
|
@@ -24,6 +24,7 @@ qore version # CLI + portal version info
|
|
|
24
24
|
qore env pull # write this module's local secrets into an env file
|
|
25
25
|
qore run -- <command> # run a command with those secrets in its environment
|
|
26
26
|
qore roles list # roles in your code, on local, and yours there
|
|
27
|
+
qore roles sync # announce your code's roles for local, keep yours
|
|
27
28
|
qore roles use <role…> # announce your code's roles for local and take these
|
|
28
29
|
|
|
29
30
|
qore errors --env stag # recent unresolved errors
|
|
@@ -149,7 +150,9 @@ the portal's own audit trail, which records key names only (see
|
|
|
149
150
|
|
|
150
151
|
#### `qore roles`
|
|
151
152
|
|
|
152
|
-
Run in the app's frontend module. `qore roles
|
|
153
|
+
Run in the app's frontend module. `qore roles sync` does the announcing alone:
|
|
154
|
+
local learns every role in `permissions.ts` and your own roles stay as they are.
|
|
155
|
+
`qore roles use inspector` reads the roles in
|
|
153
156
|
`src/lib/permissions.ts`, tells the portal they exist on `local` (only there —
|
|
154
157
|
staging and production learn roles from the code that environment deploys:
|
|
155
158
|
`main` for staging, the `production` branch for production), and makes exactly
|
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
3
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="1ed12b18-46cb-578f-b1ed-2917841ea3d0")}catch(e){}}();
|
|
4
4
|
import { createRequire as __qoreCreateRequire } from "node:module"; const require = __qoreCreateRequire(import.meta.url);
|
|
5
5
|
import {
|
|
6
6
|
addSecretValues,
|
|
@@ -3164,12 +3164,25 @@ async function wholeAppWanted(ctx) {
|
|
|
3164
3164
|
const ws = await findWorkspace(ctx.deps.cwd, ctx.deps.home);
|
|
3165
3165
|
const repo = ws && await findRepoRoot(ctx.deps.cwd);
|
|
3166
3166
|
if (!ws || !repo || repo === ws.root || !isInside(ws.root, repo)) return null;
|
|
3167
|
+
if (await appModuleCount(ctx, ws) === 1) return null;
|
|
3167
3168
|
const pick2 = await ctx.io.select("Which data model?", [
|
|
3168
3169
|
{ name: "the whole app", value: "app" },
|
|
3169
3170
|
{ name: `only ${basename3(repo)}`, value: "module" }
|
|
3170
3171
|
]);
|
|
3171
3172
|
return pick2 === "app" ? ws : null;
|
|
3172
3173
|
}
|
|
3174
|
+
async function appModuleCount(ctx, ws) {
|
|
3175
|
+
const g = ctx.opts();
|
|
3176
|
+
try {
|
|
3177
|
+
const portal = await flagPortal(ctx.deps, g.portal, ws);
|
|
3178
|
+
const session = await openSession(ctx.deps, portal, "db erd", g.verbose ? (l) => ctx.io.err(l) : void 0);
|
|
3179
|
+
await ensureCapability(ctx.deps, portal.apiOrigin, "app.modules");
|
|
3180
|
+
return (await workspaceAppModules(session, portal, ws)).modules.length;
|
|
3181
|
+
} catch (e) {
|
|
3182
|
+
if (e instanceof CancelledError) throw e;
|
|
3183
|
+
return null;
|
|
3184
|
+
}
|
|
3185
|
+
}
|
|
3173
3186
|
async function serve(ctx, f, server) {
|
|
3174
3187
|
try {
|
|
3175
3188
|
const url = `http://127.0.0.1:${server.port}`;
|
|
@@ -6716,6 +6729,11 @@ async function useLocalRoles(deps2, mc, app, roles, use) {
|
|
|
6716
6729
|
await ensureCapability(deps2, mc.portal.apiOrigin, CAPABILITY);
|
|
6717
6730
|
return explained(mc, () => mc.session.api.post(path(mc, app), { roles, use }));
|
|
6718
6731
|
}
|
|
6732
|
+
var ANNOUNCE_CAPABILITY = "module.local-roles-announce";
|
|
6733
|
+
async function announceLocalRoles(deps2, mc, app, roles) {
|
|
6734
|
+
await ensureCapability(deps2, mc.portal.apiOrigin, ANNOUNCE_CAPABILITY);
|
|
6735
|
+
return explained(mc, () => mc.session.api.post(path(mc, app), { roles }));
|
|
6736
|
+
}
|
|
6719
6737
|
async function explained(mc, call) {
|
|
6720
6738
|
try {
|
|
6721
6739
|
return await call();
|
|
@@ -6846,8 +6864,26 @@ function registerRoles(program, ctx) {
|
|
|
6846
6864
|
c.io.out(`Known on local ${[...known].join(", ") || "\u2014"}`);
|
|
6847
6865
|
c.io.out(`Yours on local ${local.effective.join(", ") || "\u2014"}`);
|
|
6848
6866
|
if (fresh.length) {
|
|
6849
|
-
c.io.out(`New in your code: ${fresh.join(", ")} \u2014 \`qore roles use <role...>\`
|
|
6867
|
+
c.io.out(`New in your code: ${fresh.join(", ")} \u2014 \`qore roles sync\` makes local know them; \`qore roles use <role...>\` also makes them yours.`);
|
|
6868
|
+
}
|
|
6869
|
+
});
|
|
6870
|
+
withFlags(roles.command("sync").description("Announce your code's roles for local; your own roles stay as they are")).action(async (f) => {
|
|
6871
|
+
const { c, mc, app, code } = await rolesContext(ctx, f, "roles sync");
|
|
6872
|
+
const res = await announceLocalRoles(c.deps, mc, app, code);
|
|
6873
|
+
if (c.opts().json) {
|
|
6874
|
+
renderJson(c.io, {
|
|
6875
|
+
context: contextJson(mc, app),
|
|
6876
|
+
added: res.added,
|
|
6877
|
+
local: res.roles.map((r) => r.slug),
|
|
6878
|
+
direct: res.direct,
|
|
6879
|
+
effective: res.effective
|
|
6880
|
+
});
|
|
6881
|
+
return;
|
|
6850
6882
|
}
|
|
6883
|
+
c.io.err(contextLine(mc, app));
|
|
6884
|
+
c.io.out(`\u2713 Known on local: ${res.roles.map((r) => r.slug).join(", ")}`);
|
|
6885
|
+
if (res.added.length) c.io.out(` New on local: ${res.added.join(", ")} \u2014 teammates can pick it in the Access tab too.`);
|
|
6886
|
+
c.io.out(` Your roles on local: ${res.effective.join(", ") || "\u2014"} (unchanged; \`qore roles use <role...>\` to change them)`);
|
|
6851
6887
|
});
|
|
6852
6888
|
withFlags(roles.command("use").description("Announce your code's roles for local and make exactly these yours there").argument("<role...>", "the roles you want on local")).action(async (wanted, f) => {
|
|
6853
6889
|
const { c, mc, app, code } = await rolesContext(ctx, f, "roles use");
|
|
@@ -7530,8 +7566,64 @@ function classifyKeychainError(e, platform) {
|
|
|
7530
7566
|
cause: e
|
|
7531
7567
|
});
|
|
7532
7568
|
}
|
|
7533
|
-
var
|
|
7534
|
-
|
|
7569
|
+
var MAX_ENTRY_CHARS = 1200;
|
|
7570
|
+
var HEAD2 = /^qore-chunked:v1:(\d+):(\d+)$/;
|
|
7571
|
+
var ChunkedKeychain = class {
|
|
7572
|
+
constructor(store, maxChars = MAX_ENTRY_CHARS) {
|
|
7573
|
+
this.store = store;
|
|
7574
|
+
this.maxChars = maxChars;
|
|
7575
|
+
}
|
|
7576
|
+
store;
|
|
7577
|
+
maxChars;
|
|
7578
|
+
head(raw) {
|
|
7579
|
+
const m = raw === null ? null : HEAD2.exec(raw);
|
|
7580
|
+
return m ? { gen: Number(m[1]), n: Number(m[2]) } : null;
|
|
7581
|
+
}
|
|
7582
|
+
split(value) {
|
|
7583
|
+
const parts = [];
|
|
7584
|
+
for (let i = 0; i < value.length; ) {
|
|
7585
|
+
let end2 = Math.min(i + this.maxChars, value.length);
|
|
7586
|
+
if (end2 < value.length && /[\uD800-\uDBFF]/.test(value[end2 - 1])) end2--;
|
|
7587
|
+
parts.push(value.slice(i, end2));
|
|
7588
|
+
i = end2;
|
|
7589
|
+
}
|
|
7590
|
+
return parts;
|
|
7591
|
+
}
|
|
7592
|
+
async deleteChunks(account, h) {
|
|
7593
|
+
for (let i = 1; i <= h.n; i++) await this.store.delete(`${account}#${h.gen}.${i}`);
|
|
7594
|
+
}
|
|
7595
|
+
async get(account) {
|
|
7596
|
+
const raw = await this.store.get(account);
|
|
7597
|
+
const h = this.head(raw);
|
|
7598
|
+
if (!h) return raw;
|
|
7599
|
+
let value = "";
|
|
7600
|
+
for (let i = 1; i <= h.n; i++) {
|
|
7601
|
+
const part = await this.store.get(`${account}#${h.gen}.${i}`);
|
|
7602
|
+
if (part === null) return null;
|
|
7603
|
+
value += part;
|
|
7604
|
+
}
|
|
7605
|
+
return value;
|
|
7606
|
+
}
|
|
7607
|
+
async set(account, value) {
|
|
7608
|
+
const old = this.head(await this.store.get(account));
|
|
7609
|
+
if (value.length <= this.maxChars) {
|
|
7610
|
+
await this.store.set(account, value);
|
|
7611
|
+
} else {
|
|
7612
|
+
const gen = (old?.gen ?? 0) + 1;
|
|
7613
|
+
const parts = this.split(value);
|
|
7614
|
+
for (const [i, part] of parts.entries()) await this.store.set(`${account}#${gen}.${i + 1}`, part);
|
|
7615
|
+
await this.store.set(account, `qore-chunked:v1:${gen}:${parts.length}`);
|
|
7616
|
+
}
|
|
7617
|
+
if (old) await this.deleteChunks(account, old);
|
|
7618
|
+
}
|
|
7619
|
+
async delete(account) {
|
|
7620
|
+
const old = this.head(await this.store.get(account));
|
|
7621
|
+
await this.store.delete(account);
|
|
7622
|
+
if (old) await this.deleteChunks(account, old);
|
|
7623
|
+
}
|
|
7624
|
+
};
|
|
7625
|
+
var EntryKeychain = class {
|
|
7626
|
+
constructor(platform) {
|
|
7535
7627
|
this.platform = platform;
|
|
7536
7628
|
}
|
|
7537
7629
|
platform;
|
|
@@ -7556,6 +7648,11 @@ var OsKeychain = class {
|
|
|
7556
7648
|
});
|
|
7557
7649
|
}
|
|
7558
7650
|
};
|
|
7651
|
+
var OsKeychain = class extends ChunkedKeychain {
|
|
7652
|
+
constructor(platform = process.platform) {
|
|
7653
|
+
super(new EntryKeychain(platform));
|
|
7654
|
+
}
|
|
7655
|
+
};
|
|
7559
7656
|
|
|
7560
7657
|
// src/platform/lock.ts
|
|
7561
7658
|
import { mkdir as mkdir5, writeFile as writeFile5 } from "fs/promises";
|
|
@@ -7860,7 +7957,7 @@ async function connectPostgres(url, o) {
|
|
|
7860
7957
|
|
|
7861
7958
|
// src/buildInfo.ts
|
|
7862
7959
|
var SENTRY_DSN = true ? "https://50b592efb53dbc1a31cb10d3945c6d52@o4512129906049024.ingest.de.sentry.io/4512174341750864" : "";
|
|
7863
|
-
var SENTRY_ENVIRONMENT =
|
|
7960
|
+
var SENTRY_ENVIRONMENT = false ? "production" : "development";
|
|
7864
7961
|
|
|
7865
7962
|
// src/platform/proxy.ts
|
|
7866
7963
|
import { execFile as execFile3 } from "child_process";
|
|
@@ -7924,7 +8021,7 @@ function systemProxy(platform = process.platform) {
|
|
|
7924
8021
|
}
|
|
7925
8022
|
|
|
7926
8023
|
// src/version.ts
|
|
7927
|
-
var VERSION = true ? "0.1
|
|
8024
|
+
var VERSION = true ? "0.2.0-rc.1" : "0.0.0-dev";
|
|
7928
8025
|
|
|
7929
8026
|
// src/cli.ts
|
|
7930
8027
|
if (process.env.HTTPS_PROXY || process.env.https_proxy || process.env.HTTP_PROXY) setGlobalDispatcher(new EnvHttpProxyAgent());
|
|
@@ -8004,4 +8101,4 @@ if (!drained) {
|
|
|
8004
8101
|
process.exit();
|
|
8005
8102
|
}
|
|
8006
8103
|
//# sourceMappingURL=cli.js.map
|
|
8007
|
-
//# debugId=
|
|
8104
|
+
//# debugId=1ed12b18-46cb-578f-b1ed-2917841ea3d0
|