@quatronic/qore 0.1.5 → 0.1.6

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 CHANGED
@@ -46,7 +46,26 @@ the portal. Working from a personal fork whose `origin` the portal doesn't
46
46
  know? As long as an `upstream` remote points at the real repository, that one
47
47
  resolves — the context line then says `(upstream)`.
48
48
 
49
- Pass `--module <slug|id>` to pick a module explicitly; the flag always wins
49
+ Outside a repository, with a projects folder set (see `qore init`), the
50
+ order is: the project you are standing in; else `[project]` /
51
+ `--project <ref>` (`app`, `app/module`, `tenant/app` or `tenant/app/module`,
52
+ matched against your local checkouts); else an interactive pick. `qore dev`
53
+ takes the reference as an argument (`qore dev <app>`); `qore dev`, `qore env
54
+ pull`, `qore run` and `qore status` take `--project`. `qore run --project`
55
+ only chooses which module's secrets are used; the command still runs in the
56
+ current directory. `qore env pull --project` writes into the located module,
57
+ and a relative `--target` then resolves against that project directory, not
58
+ the directory you ran it from.
59
+
60
+ Logged out with a projects folder set, the local lookup still runs first: a
61
+ folder that holds no projects gives `QORE_PROJECT_NOT_FOUND`; otherwise the
62
+ project is located exactly as when logged in (a match, a picker, or
63
+ `QORE_CONTEXT_REQUIRED` without a terminal), and the login error comes from
64
+ the portal lookup that follows. Only without a projects folder does a logged-out
65
+ command outside a project go straight to the login error.
66
+
67
+ Pass `--module <slug|id>` to pick a module explicitly (it keeps its meaning and,
68
+ like `--app`, still uses the portal lookup when you are not in a project); the flag always wins
50
69
  over the git remote. Inside a repository, `qore` still looks up the remote's
51
70
  own module (from the cache, or with one extra request) only so the context
52
71
  line can tell you when the flag overrides it. If a module is linked to more
@@ -92,7 +111,9 @@ qore env pull
92
111
 
93
112
  - The target file defaults to the module type's own convention (e.g.
94
113
  `.env.local`), or `.qore.json`'s `envFile`, or `--target <path>` — always
95
- resolved against, and required to stay inside, the repository.
114
+ required to stay inside the repository. `envFile` resolves against the
115
+ repository root; `--target` against the current directory, or with
116
+ `--project` against the located project directory.
96
117
  - If the file doesn't exist yet, it's seeded from `.env.example` when one is
97
118
  present.
98
119
  - Existing values you've hand-edited are kept by default. A key the portal
@@ -301,6 +322,39 @@ If a repository resolves to no module on any portal you're logged in to,
301
322
  the error lists the portals it tried and, when a staging repository looks
302
323
  likely, suggests `qore login --portal staging`.
303
324
 
325
+ ### Projects folder & `qore init`
326
+
327
+ `qore init` is the guided setup. It runs four steps and reports each as
328
+ `done`, `already` or `skipped`, so running it again is safe:
329
+
330
+ 1. **Projects folder**: where your apps live (default `~/qore`; `--root <path>`
331
+ sets it without asking). Nothing existing is moved.
332
+ 2. **Login**: skipped when you are already logged in, and with `--no-input`.
333
+ 3. **Tenant**: `already` when a tenant is active (`done` right after the login
334
+ step logged you in). Otherwise skipped with
335
+ `--no-input` or when you are not logged in (run `qore tenant use <slug>`
336
+ later), skipped with no tenants, selected without a prompt when you have
337
+ one, a picker when you have several.
338
+ 4. **First app**: `--clone <app>` (with `--tenant <slug>` to disambiguate)
339
+ clones it; interactively it asks.
340
+
341
+ With `--json`, stdout is one document: `{"projectsRoot": "<path>|null",
342
+ "steps": {"root"|"login"|"tenant"|"clone": {"status", "detail?"}}}`.
343
+
344
+ Apps clone into `<root>/<tenant>/<app>/<module>`. A checkout outside the
345
+ folder registers itself the first time you use it (`qore clone <app> <dir>`,
346
+ `qore dev`, ...); a registered checkout that was deleted is dropped. With a
347
+ projects folder set, `qore dev`, `qore env pull`, `qore run` and `qore status`
348
+ work from any directory (see Repository context).
349
+
350
+ ```sh
351
+ qore config root # show the folder and how many projects it holds
352
+ qore config root <path> # set it
353
+ qore config root --unset # clear it; known projects stay findable
354
+ ```
355
+
356
+ `qore doctor` checks that the folder exists and is writable.
357
+
304
358
  ### Workspaces
305
359
 
306
360
  `qore clone` sets up a local directory holding one or more of an app's
@@ -319,6 +373,9 @@ qore sync # clone any module that's new, fetch the rest
319
373
  qore sync --pull # ...and fast-forward every clean repository with an upstream
320
374
  ```
321
375
 
376
+ - **Where it clones.** Without `[dir]` and with a projects folder set, `qore
377
+ clone` uses `<root>/<tenant>/<app>`. Without a projects folder it behaves as
378
+ described above and prints a tip to run `qore init`.
322
379
  - **`--protocol https|ssh`** picks the clone URL (default `https`). `ssh`
323
380
  rewrites `https://github.com/o/r` to `git@github.com:o/r.git`; your own
324
381
  git `insteadOf` config still applies on top of either.
@@ -485,8 +542,8 @@ qore whoami --json
485
542
  | Code | Meaning |
486
543
  |------|---------|
487
544
  | 0 | Success |
488
- | 1 | Internal error, `git` is not installed or not on `PATH`, the OS keychain is unavailable/access was denied, or qore itself needs a newer Node (`QORE_NODE_VERSION`, checked by `qore doctor`'s own `node` check against qore's own `process.version`); `qore dev`: its package manager isn't installed (`QORE_PACKAGE_MANAGER`), its install failed (`QORE_INSTALL_FAILED`), Docker is missing (`QORE_DOCKER_MISSING`), not running (`QORE_DOCKER_NOT_RUNNING`) or its compose v2 plugin is missing (`QORE_DOCKER_COMPOSE_MISSING`), a `db:up`/service failed, never became healthy (`QORE_SERVICE_UNHEALTHY`) or its data is incompatible (`QORE_SERVICE_DATA_INCOMPATIBLE`), or the repository's own `engines.node` doesn't match the `node` on `PATH` (`QORE_NODE_VERSION`, a different check from qore's own — `qore doctor`'s `node:<module>` check, run only in a trusted repository) |
489
- | 2 | Missing or invalid context (e.g. a bad `--portal` value, or no module selected), or the module is part of several apps and no `--app` was given; `qore dev`: a port is already in use (`QORE_PORT_IN_USE`) or the repository's dev setup isn't supported (`QORE_DEV_UNSUPPORTED`) |
545
+ | 1 | Internal error, `git` is not installed or not on `PATH`, the OS keychain is unavailable/access was denied, or qore itself needs a newer Node (`QORE_NODE_VERSION`, checked by `qore doctor`'s own `node` check against qore's own `process.version`); `qore dev`: its package manager isn't installed (`QORE_PACKAGE_MANAGER`), its install failed (`QORE_INSTALL_FAILED`), Docker is missing (`QORE_DOCKER_MISSING`), not running (`QORE_DOCKER_NOT_RUNNING`) or its compose v2 plugin is missing (`QORE_DOCKER_COMPOSE_MISSING`), a `db:up`/service failed, never became healthy (`QORE_SERVICE_UNHEALTHY`) or its data is incompatible (`QORE_SERVICE_DATA_INCOMPATIBLE`), or the repository's own `engines.node` doesn't match the `node` on `PATH` (`QORE_NODE_VERSION`, a different check from qore's own — `qore doctor`'s `node:<module>` check, run only in a trusted repository); or the projects folder isn't writable (`QORE_ROOT_NOT_WRITABLE`, fix its permissions or choose another folder) |
546
+ | 2 | Missing or invalid context (e.g. a bad `--portal` value, or no module selected), or the module is part of several apps and no `--app` was given; `qore dev`: a port is already in use (`QORE_PORT_IN_USE`) or the repository's dev setup isn't supported (`QORE_DEV_UNSUPPORTED`); projects folder: not set and not inside a project, for a logged-in user (`QORE_ROOT_NOT_SET`, run `qore init`; logged out with no folder you get the login error, exit 4, and logged out with a folder the local lookup runs first, so an empty folder still gives `QORE_PROJECT_NOT_FOUND`), not usable as a folder (`QORE_ROOT_INVALID`, pick another with `qore init --root <path>`), or no local project matches the reference or the folder holds none (`QORE_PROJECT_NOT_FOUND`, run `qore clone <app>`) |
490
547
  | 4 | Not logged in, session/login expired, login denied, or clock skew |
491
548
  | 5 | Access denied — lost tenant access, resource not found, no developer access |
492
549
  | 6 | Auth or API temporarily unreachable/unavailable |
@@ -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]="a8210538-dc3e-507d-ab33-bdf6a49d6d16")}catch(e){}}();
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]="885f6de1-0da7-54a5-86df-beaf550bdd8a")}catch(e){}}();
4
4
  import { createRequire as __qoreCreateRequire } from "node:module"; const require = __qoreCreateRequire(import.meta.url);
5
5
 
6
6
  // src/core/telemetry/scrub.ts
@@ -52,6 +52,21 @@ function replaceHome(s, ctx) {
52
52
  }
53
53
  return out;
54
54
  }
55
+ var PKG = "node_modules/@quatronic/qore/";
56
+ var NM = "node_modules/";
57
+ function rewritePath(p, ctx) {
58
+ if (p.startsWith("app://") || !/^(?:file:\/\/|\/|[A-Za-z]:[\\/])/.test(p)) return { path: p };
59
+ let s = p.replace(/^file:\/\//, "");
60
+ if (ctx.platform === "win32") s = s.replace(/\\/g, "/").replace(/^\/(?=[A-Za-z]:)/, "");
61
+ const pkg = s.lastIndexOf(PKG);
62
+ const nm = s.lastIndexOf(NM);
63
+ if (pkg >= 0 && pkg === nm) return { path: `app:///${s.slice(pkg + PKG.length)}`, inApp: true };
64
+ if (nm >= 0) return { path: `app:///${s.slice(nm)}`, inApp: false };
65
+ return { path: `app:///${replaceHome(s, ctx).replace(/^\/+/, "")}` };
66
+ }
67
+ function framePath(p, ctx) {
68
+ return rewritePath(p, ctx).path;
69
+ }
55
70
  function scrubText(s, ctx) {
56
71
  let out = s;
57
72
  for (const v of ctx.secretEnvValues) out = replaceLiteral(out, v, "[env]", "g");
@@ -83,8 +98,8 @@ function scrubBreadcrumb(b, ctx) {
83
98
  return { ...b, message: b.message === void 0 ? void 0 : scrubText(b.message, ctx), data: void 0 };
84
99
  }
85
100
  function scrubEvent(e, ctx) {
101
+ e.user = { ip_address: null };
86
102
  delete e.server_name;
87
- delete e.user;
88
103
  delete e.request;
89
104
  delete e.extra;
90
105
  delete e.modules;
@@ -97,8 +112,12 @@ function scrubEvent(e, ctx) {
97
112
  for (const v of e.exception?.values ?? []) {
98
113
  if (v.value !== void 0) v.value = scrubText(v.value, ctx);
99
114
  for (const f of v.stacktrace?.frames ?? []) {
100
- if (f.filename) f.filename = replaceHome(f.filename, ctx);
101
- if (f.abs_path) f.abs_path = replaceHome(f.abs_path, ctx);
115
+ for (const k of ["filename", "abs_path"]) {
116
+ if (!f[k]) continue;
117
+ const r = rewritePath(f[k], ctx);
118
+ f[k] = r.path;
119
+ if (r.inApp !== void 0) f.in_app = r.inApp;
120
+ }
102
121
  if (f.module) f.module = replaceHome(f.module, ctx);
103
122
  delete f.vars;
104
123
  delete f.pre_context;
@@ -106,7 +125,7 @@ function scrubEvent(e, ctx) {
106
125
  delete f.post_context;
107
126
  }
108
127
  }
109
- for (const img of e.debug_meta?.images ?? []) if (img.code_file) img.code_file = replaceHome(img.code_file, ctx);
128
+ for (const img of e.debug_meta?.images ?? []) if (img.code_file) img.code_file = framePath(img.code_file, ctx);
110
129
  if (e.breadcrumbs) e.breadcrumbs = e.breadcrumbs.map((b) => scrubBreadcrumb(b, ctx)).filter((b) => b !== null);
111
130
  return e;
112
131
  }
@@ -117,5 +136,5 @@ export {
117
136
  scrubBreadcrumb,
118
137
  scrubEvent
119
138
  };
120
- //# sourceMappingURL=chunk-QYBDINUC.js.map
121
- //# debugId=a8210538-dc3e-507d-ab33-bdf6a49d6d16
139
+ //# sourceMappingURL=chunk-OAU6HJHZ.js.map
140
+ //# debugId=885f6de1-0da7-54a5-86df-beaf550bdd8a