@odla-ai/cli 0.25.19 → 0.25.20
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 +6 -0
- package/dist/bin.cjs +36 -20
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-S3EJ66VG.js → chunk-ONETPJFW.js} +26 -10
- package/dist/chunk-ONETPJFW.js.map +1 -0
- package/dist/index.cjs +36 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-S3EJ66VG.js.map +0 -1
package/README.md
CHANGED
|
@@ -746,6 +746,12 @@ export default {
|
|
|
746
746
|
`db.schema` and `db.rules` may be inline objects, JSON files, or JS modules
|
|
747
747
|
exporting `default`, `schema` / `SCHEMA`, or `rules` / `RULES`.
|
|
748
748
|
|
|
749
|
+
`services` accepts only ids from `@odla-ai/apps`'
|
|
750
|
+
`APP_SERVICE_CATALOG`. The CLI validates the same-environment dependencies
|
|
751
|
+
from that catalog before authentication or mutation; currently `calendar`,
|
|
752
|
+
`chat`, and `kg` require `db`. Application npm integrations remain under
|
|
753
|
+
`integrations`, not `services`.
|
|
754
|
+
|
|
749
755
|
If schema is present and rules are omitted, `defaultRules: "deny"` generates
|
|
750
756
|
deny-all rules for every schema entity. That is the safe default for Workers
|
|
751
757
|
that mediate reads and writes with an app key.
|
package/dist/bin.cjs
CHANGED
|
@@ -968,6 +968,7 @@ var import_node_process8 = __toESM(require("process"), 1);
|
|
|
968
968
|
var import_node_fs4 = require("fs");
|
|
969
969
|
var import_node_path4 = require("path");
|
|
970
970
|
var import_node_url = require("url");
|
|
971
|
+
var import_apps = require("@odla-ai/apps");
|
|
971
972
|
|
|
972
973
|
// src/integration-validation.ts
|
|
973
974
|
function validateIntegrations(cfg, path, defaultServices) {
|
|
@@ -1055,6 +1056,7 @@ async function loadProjectConfig(configPath = "odla.config.mjs") {
|
|
|
1055
1056
|
const dbEndpoint = trimSlash(process.env.ODLA_DB_ENDPOINT || raw.dbEndpoint || platformUrl);
|
|
1056
1057
|
const envs = unique2(raw.envs?.length ? raw.envs : DEFAULT_ENVS);
|
|
1057
1058
|
const services = unique2(raw.services?.length ? raw.services : DEFAULT_SERVICES);
|
|
1059
|
+
validateServices(services, resolved);
|
|
1058
1060
|
validateCalendarConfig(raw, envs, services, resolved);
|
|
1059
1061
|
const local = {
|
|
1060
1062
|
tokenFile: (0, import_node_path4.resolve)(rootDir, raw.local?.tokenFile ?? ".odla/dev-token.json"),
|
|
@@ -1210,7 +1212,19 @@ function validateCalendarConfig(cfg, envs, services, path) {
|
|
|
1210
1212
|
}
|
|
1211
1213
|
}
|
|
1212
1214
|
}
|
|
1213
|
-
|
|
1215
|
+
}
|
|
1216
|
+
function validateServices(services, path) {
|
|
1217
|
+
for (const service of services) {
|
|
1218
|
+
const definition = (0, import_apps.appServiceDefinition)(service);
|
|
1219
|
+
if (!definition) {
|
|
1220
|
+
throw new Error(`${path}: unknown service "${service}" (known: ${(0, import_apps.appServiceIds)().join(", ")})`);
|
|
1221
|
+
}
|
|
1222
|
+
for (const dependency of definition.requires) {
|
|
1223
|
+
if (!services.includes(dependency)) {
|
|
1224
|
+
throw new Error(`${path}: ${service} service requires the ${dependency} service`);
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1214
1228
|
}
|
|
1215
1229
|
function assertOnly(value, allowed, label) {
|
|
1216
1230
|
const extra = Object.keys(value).find((key) => !allowed.includes(key));
|
|
@@ -1534,7 +1548,7 @@ async function adminCommand(parsed, deps = {}) {
|
|
|
1534
1548
|
}
|
|
1535
1549
|
|
|
1536
1550
|
// src/tenant.ts
|
|
1537
|
-
var
|
|
1551
|
+
var import_apps2 = require("@odla-ai/apps");
|
|
1538
1552
|
function resolveEnv(cfg, requested) {
|
|
1539
1553
|
const env = requested ?? (cfg.envs.includes("dev") ? "dev" : cfg.envs[0]);
|
|
1540
1554
|
if (!env || !cfg.envs.includes(env)) {
|
|
@@ -1544,7 +1558,7 @@ function resolveEnv(cfg, requested) {
|
|
|
1544
1558
|
}
|
|
1545
1559
|
function resolveTenant(cfg, requested) {
|
|
1546
1560
|
const env = resolveEnv(cfg, requested);
|
|
1547
|
-
return { env, tenant: (0,
|
|
1561
|
+
return { env, tenant: (0, import_apps2.tenantIdFor)(cfg.app.id, env) };
|
|
1548
1562
|
}
|
|
1549
1563
|
function bothTenants(cfg) {
|
|
1550
1564
|
for (const env of ["dev", "prod"]) {
|
|
@@ -1554,7 +1568,7 @@ function bothTenants(cfg) {
|
|
|
1554
1568
|
);
|
|
1555
1569
|
}
|
|
1556
1570
|
}
|
|
1557
|
-
return { sandbox: (0,
|
|
1571
|
+
return { sandbox: (0, import_apps2.tenantIdFor)(cfg.app.id, "dev"), live: (0, import_apps2.tenantIdFor)(cfg.app.id, "prod") };
|
|
1558
1572
|
}
|
|
1559
1573
|
|
|
1560
1574
|
// src/agent-command.ts
|
|
@@ -3090,6 +3104,7 @@ function harnessOption(value, flag) {
|
|
|
3090
3104
|
// src/init.ts
|
|
3091
3105
|
var import_node_fs11 = require("fs");
|
|
3092
3106
|
var import_node_path9 = require("path");
|
|
3107
|
+
var import_apps3 = require("@odla-ai/apps");
|
|
3093
3108
|
function initProject(options) {
|
|
3094
3109
|
const out = options.stdout ?? console;
|
|
3095
3110
|
const rootDir = (0, import_node_path9.resolve)(options.rootDir ?? process.cwd());
|
|
@@ -3102,7 +3117,13 @@ function initProject(options) {
|
|
|
3102
3117
|
}
|
|
3103
3118
|
const envs = options.envs?.length ? options.envs : ["dev"];
|
|
3104
3119
|
const services = options.services?.length ? options.services : ["db", "ai"];
|
|
3105
|
-
|
|
3120
|
+
for (const service of services) {
|
|
3121
|
+
const definition = (0, import_apps3.appServiceDefinition)(service);
|
|
3122
|
+
if (!definition) throw new Error(`--services contains unknown service "${service}" (known: ${(0, import_apps3.appServiceIds)().join(", ")})`);
|
|
3123
|
+
for (const dependency of definition.requires) {
|
|
3124
|
+
if (!services.includes(dependency)) throw new Error(`--services ${service} requires ${dependency}`);
|
|
3125
|
+
}
|
|
3126
|
+
}
|
|
3106
3127
|
const aiProvider = options.aiProvider ?? "anthropic";
|
|
3107
3128
|
(0, import_node_fs11.mkdirSync)((0, import_node_path9.dirname)(configPath), { recursive: true });
|
|
3108
3129
|
(0, import_node_fs11.mkdirSync)((0, import_node_path9.resolve)(rootDir, "src/odla"), { recursive: true });
|
|
@@ -3292,7 +3313,7 @@ function assertWranglerConfig(cfg) {
|
|
|
3292
3313
|
|
|
3293
3314
|
// src/secrets-set.ts
|
|
3294
3315
|
var import_ai = require("@odla-ai/ai");
|
|
3295
|
-
var
|
|
3316
|
+
var import_apps4 = require("@odla-ai/apps");
|
|
3296
3317
|
var PROD_ENV_NAMES2 = /* @__PURE__ */ new Set(["prod", "production"]);
|
|
3297
3318
|
async function secretsSet(options) {
|
|
3298
3319
|
const name = (options.name ?? "").trim();
|
|
@@ -3344,7 +3365,7 @@ async function resolveVaultWrite(options) {
|
|
|
3344
3365
|
throw new Error(`refusing to store a secret for "${options.env}" without --yes`);
|
|
3345
3366
|
}
|
|
3346
3367
|
const value = await secretInputValue(options, "secret");
|
|
3347
|
-
return { cfg, tenantId: (0,
|
|
3368
|
+
return { cfg, tenantId: (0, import_apps4.tenantIdFor)(cfg.app.id, options.env), value, doFetch, out };
|
|
3348
3369
|
}
|
|
3349
3370
|
|
|
3350
3371
|
// src/skill.ts
|
|
@@ -8972,7 +8993,7 @@ async function read2(url, headers, doFetch) {
|
|
|
8972
8993
|
}
|
|
8973
8994
|
|
|
8974
8995
|
// src/provision.ts
|
|
8975
|
-
var
|
|
8996
|
+
var import_apps7 = require("@odla-ai/apps");
|
|
8976
8997
|
var import_ai3 = require("@odla-ai/ai");
|
|
8977
8998
|
var import_node_process10 = __toESM(require("process"), 1);
|
|
8978
8999
|
|
|
@@ -9029,9 +9050,9 @@ async function responseText(res) {
|
|
|
9029
9050
|
}
|
|
9030
9051
|
|
|
9031
9052
|
// src/provision-credentials.ts
|
|
9032
|
-
var
|
|
9053
|
+
var import_apps5 = require("@odla-ai/apps");
|
|
9033
9054
|
async function provisionEnvCredentials(opts) {
|
|
9034
|
-
const tenantId = (0,
|
|
9055
|
+
const tenantId = (0, import_apps5.tenantIdFor)(opts.cfg.app.id, opts.env);
|
|
9035
9056
|
const prior = opts.credentials?.envs[opts.env];
|
|
9036
9057
|
let credentials = opts.credentials;
|
|
9037
9058
|
let dbKey = opts.cfg.services.includes("db") && !opts.rotateDb ? prior?.dbKey : void 0;
|
|
@@ -9125,18 +9146,13 @@ async function safeText4(res) {
|
|
|
9125
9146
|
|
|
9126
9147
|
// src/provision-helpers.ts
|
|
9127
9148
|
var import_ai2 = require("@odla-ai/ai");
|
|
9128
|
-
var
|
|
9129
|
-
function serviceRank(service) {
|
|
9130
|
-
if (service === "db") return 0;
|
|
9131
|
-
if (service === "calendar") return 2;
|
|
9132
|
-
return 1;
|
|
9133
|
-
}
|
|
9149
|
+
var import_apps6 = require("@odla-ai/apps");
|
|
9134
9150
|
function defaultSecretName(provider) {
|
|
9135
9151
|
const names = import_ai2.DEFAULT_SECRET_NAMES;
|
|
9136
9152
|
return names[provider] ?? `${provider}_api_key`;
|
|
9137
9153
|
}
|
|
9138
9154
|
async function assertTenantAdminAccess(doFetch, cfg, env, token) {
|
|
9139
|
-
const tenantId = (0,
|
|
9155
|
+
const tenantId = (0, import_apps6.tenantIdFor)(cfg.app.id, env);
|
|
9140
9156
|
const res = await doFetch(`${cfg.dbEndpoint}/admin/apps/${encodeURIComponent(tenantId)}/entitlements`, {
|
|
9141
9157
|
headers: { authorization: `Bearer ${token}` }
|
|
9142
9158
|
});
|
|
@@ -9245,7 +9261,7 @@ async function provision(options) {
|
|
|
9245
9261
|
}
|
|
9246
9262
|
const doFetch = options.fetch ?? fetch;
|
|
9247
9263
|
const token = await getDeveloperToken(cfg, options, doFetch, out);
|
|
9248
|
-
const apps = (0,
|
|
9264
|
+
const apps = (0, import_apps7.createAppsClient)({ endpoint: cfg.platformUrl, token, fetcher: { fetch: doFetch } });
|
|
9249
9265
|
const existing = await apps.resolveApp(cfg.app.id);
|
|
9250
9266
|
if (existing) {
|
|
9251
9267
|
out.log(`app: ${cfg.app.id} already exists`);
|
|
@@ -9256,7 +9272,7 @@ async function provision(options) {
|
|
|
9256
9272
|
for (const env of cfg.envs) {
|
|
9257
9273
|
await assertTenantAdminAccess(doFetch, cfg, env, token);
|
|
9258
9274
|
}
|
|
9259
|
-
const serviceOrder =
|
|
9275
|
+
const serviceOrder = (0, import_apps7.orderAppServices)(cfg.services);
|
|
9260
9276
|
for (const env of cfg.envs) {
|
|
9261
9277
|
for (const service of serviceOrder) {
|
|
9262
9278
|
if (service === "ai") {
|
|
@@ -9289,7 +9305,7 @@ async function provision(options) {
|
|
|
9289
9305
|
}
|
|
9290
9306
|
}
|
|
9291
9307
|
for (const env of cfg.envs) {
|
|
9292
|
-
const tenantId = (0,
|
|
9308
|
+
const tenantId = (0, import_apps7.tenantIdFor)(cfg.app.id, env);
|
|
9293
9309
|
credentials = await provisionEnvCredentials({
|
|
9294
9310
|
cfg,
|
|
9295
9311
|
env,
|