@squidcloud/cli 1.0.462 → 1.0.464
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/index.js +200 -113
- package/dist/resources/claude/skills/squid-development/SKILL.md +2 -1
- package/dist/resources/claude/skills/squid-development/reference/backend.md +40 -1
- package/dist/resources/claude/skills/squid-development/reference/client.md +1 -1
- package/dist/resources/claude/skills/squid-development/reference/openai.md +4 -4
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -11217,25 +11217,17 @@ const fs = __webpack_require__(9896)
|
|
|
11217
11217
|
const path = __webpack_require__(6928)
|
|
11218
11218
|
const os = __webpack_require__(857)
|
|
11219
11219
|
const crypto = __webpack_require__(6982)
|
|
11220
|
-
const packageJson = __webpack_require__(2108)
|
|
11221
|
-
|
|
11222
|
-
const version = packageJson.version
|
|
11223
11220
|
|
|
11224
11221
|
// Array of tips to display randomly
|
|
11225
11222
|
const TIPS = [
|
|
11226
|
-
'
|
|
11227
|
-
'
|
|
11228
|
-
'
|
|
11229
|
-
'
|
|
11230
|
-
'
|
|
11231
|
-
'
|
|
11232
|
-
'
|
|
11233
|
-
'
|
|
11234
|
-
'⚙️ enable debug logging with { debug: true }',
|
|
11235
|
-
'⚙️ override existing env vars with { override: true }',
|
|
11236
|
-
'⚙️ suppress all logs with { quiet: true }',
|
|
11237
|
-
'⚙️ write to custom object with { processEnv: myObject }',
|
|
11238
|
-
'⚙️ load multiple .env files with { path: [\'.env.local\', \'.env\'] }'
|
|
11223
|
+
'◈ encrypted .env [www.dotenvx.com]',
|
|
11224
|
+
'◈ secrets for agents [www.dotenvx.com]',
|
|
11225
|
+
'⌁ auth for agents [www.vestauth.com]',
|
|
11226
|
+
'⌘ custom filepath { path: \'/custom/path/.env\' }',
|
|
11227
|
+
'⌘ enable debugging { debug: true }',
|
|
11228
|
+
'⌘ override existing { override: true }',
|
|
11229
|
+
'⌘ suppress logs { quiet: true }',
|
|
11230
|
+
'⌘ multiple files { path: [\'.env.local\', \'.env\'] }'
|
|
11239
11231
|
]
|
|
11240
11232
|
|
|
11241
11233
|
// Get a random tip from the tips array
|
|
@@ -11343,15 +11335,15 @@ function _parseVault (options) {
|
|
|
11343
11335
|
}
|
|
11344
11336
|
|
|
11345
11337
|
function _warn (message) {
|
|
11346
|
-
console.error(
|
|
11338
|
+
console.error(`⚠ ${message}`)
|
|
11347
11339
|
}
|
|
11348
11340
|
|
|
11349
11341
|
function _debug (message) {
|
|
11350
|
-
console.log(
|
|
11342
|
+
console.log(`┆ ${message}`)
|
|
11351
11343
|
}
|
|
11352
11344
|
|
|
11353
11345
|
function _log (message) {
|
|
11354
|
-
console.log(
|
|
11346
|
+
console.log(`◇ ${message}`)
|
|
11355
11347
|
}
|
|
11356
11348
|
|
|
11357
11349
|
function _dotenvKey (options) {
|
|
@@ -11445,7 +11437,7 @@ function _configVault (options) {
|
|
|
11445
11437
|
const quiet = parseBoolean(process.env.DOTENV_CONFIG_QUIET || (options && options.quiet))
|
|
11446
11438
|
|
|
11447
11439
|
if (debug || !quiet) {
|
|
11448
|
-
_log('
|
|
11440
|
+
_log('loading env from encrypted .env.vault')
|
|
11449
11441
|
}
|
|
11450
11442
|
|
|
11451
11443
|
const parsed = DotenvModule._parseVault(options)
|
|
@@ -11474,7 +11466,7 @@ function configDotenv (options) {
|
|
|
11474
11466
|
encoding = options.encoding
|
|
11475
11467
|
} else {
|
|
11476
11468
|
if (debug) {
|
|
11477
|
-
_debug('
|
|
11469
|
+
_debug('no encoding is specified (UTF-8 is used by default)')
|
|
11478
11470
|
}
|
|
11479
11471
|
}
|
|
11480
11472
|
|
|
@@ -11502,7 +11494,7 @@ function configDotenv (options) {
|
|
|
11502
11494
|
DotenvModule.populate(parsedAll, parsed, options)
|
|
11503
11495
|
} catch (e) {
|
|
11504
11496
|
if (debug) {
|
|
11505
|
-
_debug(`
|
|
11497
|
+
_debug(`failed to load ${path} ${e.message}`)
|
|
11506
11498
|
}
|
|
11507
11499
|
lastError = e
|
|
11508
11500
|
}
|
|
@@ -11523,13 +11515,13 @@ function configDotenv (options) {
|
|
|
11523
11515
|
shortPaths.push(relative)
|
|
11524
11516
|
} catch (e) {
|
|
11525
11517
|
if (debug) {
|
|
11526
|
-
_debug(`
|
|
11518
|
+
_debug(`failed to load ${filePath} ${e.message}`)
|
|
11527
11519
|
}
|
|
11528
11520
|
lastError = e
|
|
11529
11521
|
}
|
|
11530
11522
|
}
|
|
11531
11523
|
|
|
11532
|
-
_log(`
|
|
11524
|
+
_log(`injected env (${keysCount}) from ${shortPaths.join(',')} ${dim(`// tip: ${_getRandomTip()}`)}`)
|
|
11533
11525
|
}
|
|
11534
11526
|
|
|
11535
11527
|
if (lastError) {
|
|
@@ -11550,7 +11542,7 @@ function config (options) {
|
|
|
11550
11542
|
|
|
11551
11543
|
// dotenvKey exists but .env.vault file does not exist
|
|
11552
11544
|
if (!vaultPath) {
|
|
11553
|
-
_warn(`
|
|
11545
|
+
_warn(`you set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}`)
|
|
11554
11546
|
|
|
11555
11547
|
return DotenvModule.configDotenv(options)
|
|
11556
11548
|
}
|
|
@@ -19067,6 +19059,7 @@ module.exports = memoize;
|
|
|
19067
19059
|
(module, __unused_webpack_exports, __webpack_require__) {
|
|
19068
19060
|
|
|
19069
19061
|
"use strict";
|
|
19062
|
+
var __webpack_unused_export__;
|
|
19070
19063
|
/*
|
|
19071
19064
|
MIT License http://www.opensource.org/licenses/mit-license.php
|
|
19072
19065
|
Author Tobias Koppers @sokra
|
|
@@ -19311,11 +19304,11 @@ module.exports.PathType = PathType;
|
|
|
19311
19304
|
module.exports.cachedDirname = cachedDirname;
|
|
19312
19305
|
module.exports.cachedJoin = cachedJoin;
|
|
19313
19306
|
module.exports.deprecatedInvalidSegmentRegEx = deprecatedInvalidSegmentRegEx;
|
|
19314
|
-
|
|
19307
|
+
__webpack_unused_export__ = dirname;
|
|
19315
19308
|
module.exports.getType = getType;
|
|
19316
19309
|
module.exports.invalidSegmentRegEx = invalidSegmentRegEx;
|
|
19317
19310
|
module.exports.isSubPath = isSubPath;
|
|
19318
|
-
|
|
19311
|
+
__webpack_unused_export__ = join;
|
|
19319
19312
|
module.exports.normalize = normalize;
|
|
19320
19313
|
|
|
19321
19314
|
|
|
@@ -24930,19 +24923,49 @@ class Hook {
|
|
|
24930
24923
|
|
|
24931
24924
|
_tap(type, options, fn) {
|
|
24932
24925
|
if (typeof options === "string") {
|
|
24933
|
-
options
|
|
24934
|
-
|
|
24935
|
-
}
|
|
24936
|
-
|
|
24937
|
-
|
|
24938
|
-
|
|
24939
|
-
|
|
24940
|
-
|
|
24941
|
-
}
|
|
24942
|
-
|
|
24943
|
-
|
|
24926
|
+
// Fast path: a string options ("name") is by far the most common
|
|
24927
|
+
// case. Build the final descriptor in a single allocation instead
|
|
24928
|
+
// of creating `{ name }` and then `Object.assign`ing it.
|
|
24929
|
+
const name = options.trim();
|
|
24930
|
+
if (name === "") {
|
|
24931
|
+
throw new Error("Missing name for tap");
|
|
24932
|
+
}
|
|
24933
|
+
options = { type, fn, name };
|
|
24934
|
+
} else {
|
|
24935
|
+
if (typeof options !== "object" || options === null) {
|
|
24936
|
+
throw new Error("Invalid tap options");
|
|
24937
|
+
}
|
|
24938
|
+
let { name } = options;
|
|
24939
|
+
if (typeof name === "string") {
|
|
24940
|
+
name = name.trim();
|
|
24941
|
+
}
|
|
24942
|
+
if (typeof name !== "string" || name === "") {
|
|
24943
|
+
throw new Error("Missing name for tap");
|
|
24944
|
+
}
|
|
24945
|
+
if (typeof options.context !== "undefined") {
|
|
24946
|
+
deprecateContext();
|
|
24947
|
+
}
|
|
24948
|
+
// Fast path: only `name` is set. Build the descriptor as a literal
|
|
24949
|
+
// so `_insert` and downstream consumers see the same hidden class
|
|
24950
|
+
// as the string-options path, avoiding a polymorphic call site.
|
|
24951
|
+
// Scan with `for...in` (cheaper than allocating `Object.keys`)
|
|
24952
|
+
// to verify no other user-provided properties exist - e.g.
|
|
24953
|
+
// webpack's `additionalAssets` - otherwise they'd be dropped.
|
|
24954
|
+
let onlyName = true;
|
|
24955
|
+
for (const key in options) {
|
|
24956
|
+
if (key !== "name") {
|
|
24957
|
+
onlyName = false;
|
|
24958
|
+
break;
|
|
24959
|
+
}
|
|
24960
|
+
}
|
|
24961
|
+
if (onlyName) {
|
|
24962
|
+
options = { type, fn, name };
|
|
24963
|
+
} else {
|
|
24964
|
+
options.name = name;
|
|
24965
|
+
// Preserve previous precedence: user-provided keys win over the internal `type`/`fn`.
|
|
24966
|
+
options = Object.assign({ type, fn }, options);
|
|
24967
|
+
}
|
|
24944
24968
|
}
|
|
24945
|
-
options = Object.assign({ type, fn }, options);
|
|
24946
24969
|
options = this._runRegisterInterceptors(options);
|
|
24947
24970
|
this._insert(options);
|
|
24948
24971
|
}
|
|
@@ -24960,7 +24983,12 @@ class Hook {
|
|
|
24960
24983
|
}
|
|
24961
24984
|
|
|
24962
24985
|
_runRegisterInterceptors(options) {
|
|
24963
|
-
|
|
24986
|
+
const { interceptors } = this;
|
|
24987
|
+
const { length } = interceptors;
|
|
24988
|
+
// Common case: no interceptors.
|
|
24989
|
+
if (length === 0) return options;
|
|
24990
|
+
for (let i = 0; i < length; i++) {
|
|
24991
|
+
const interceptor = interceptors[i];
|
|
24964
24992
|
if (interceptor.register) {
|
|
24965
24993
|
const newOptions = interceptor.register(options);
|
|
24966
24994
|
if (newOptions !== undefined) {
|
|
@@ -25008,21 +25036,36 @@ class Hook {
|
|
|
25008
25036
|
|
|
25009
25037
|
_insert(item) {
|
|
25010
25038
|
this._resetCompilation();
|
|
25039
|
+
const { taps } = this;
|
|
25040
|
+
const stage = typeof item.stage === "number" ? item.stage : 0;
|
|
25041
|
+
|
|
25042
|
+
// Fast path: the overwhelmingly common `hook.tap("name", fn)` case
|
|
25043
|
+
// has no `before` and default stage 0. If the list is empty or the
|
|
25044
|
+
// last tap's stage is <= the new item's stage the item belongs at
|
|
25045
|
+
// the end - append in O(1), skipping the Set allocation and the
|
|
25046
|
+
// shift loop.
|
|
25047
|
+
if (!(typeof item.before === "string" || Array.isArray(item.before))) {
|
|
25048
|
+
const n = taps.length;
|
|
25049
|
+
if (n === 0 || (taps[n - 1].stage || 0) <= stage) {
|
|
25050
|
+
taps[n] = item;
|
|
25051
|
+
return;
|
|
25052
|
+
}
|
|
25053
|
+
}
|
|
25054
|
+
|
|
25011
25055
|
let before;
|
|
25056
|
+
|
|
25012
25057
|
if (typeof item.before === "string") {
|
|
25013
25058
|
before = new Set([item.before]);
|
|
25014
25059
|
} else if (Array.isArray(item.before)) {
|
|
25015
25060
|
before = new Set(item.before);
|
|
25016
25061
|
}
|
|
25017
|
-
|
|
25018
|
-
|
|
25019
|
-
|
|
25020
|
-
}
|
|
25021
|
-
let i = this.taps.length;
|
|
25062
|
+
|
|
25063
|
+
let i = taps.length;
|
|
25064
|
+
|
|
25022
25065
|
while (i > 0) {
|
|
25023
25066
|
i--;
|
|
25024
|
-
const tap =
|
|
25025
|
-
|
|
25067
|
+
const tap = taps[i];
|
|
25068
|
+
taps[i + 1] = tap;
|
|
25026
25069
|
const xStage = tap.stage || 0;
|
|
25027
25070
|
if (before) {
|
|
25028
25071
|
if (before.has(tap.name)) {
|
|
@@ -25039,7 +25082,7 @@ class Hook {
|
|
|
25039
25082
|
i++;
|
|
25040
25083
|
break;
|
|
25041
25084
|
}
|
|
25042
|
-
|
|
25085
|
+
taps[i] = item;
|
|
25043
25086
|
}
|
|
25044
25087
|
}
|
|
25045
25088
|
|
|
@@ -25070,7 +25113,7 @@ class HookCodeFactory {
|
|
|
25070
25113
|
create(options) {
|
|
25071
25114
|
this.init(options);
|
|
25072
25115
|
let fn;
|
|
25073
|
-
switch (
|
|
25116
|
+
switch (options.type) {
|
|
25074
25117
|
case "sync":
|
|
25075
25118
|
fn = new Function(
|
|
25076
25119
|
this.args(),
|
|
@@ -25133,7 +25176,13 @@ class HookCodeFactory {
|
|
|
25133
25176
|
}
|
|
25134
25177
|
|
|
25135
25178
|
setup(instance, options) {
|
|
25136
|
-
|
|
25179
|
+
const { taps } = options;
|
|
25180
|
+
const { length } = taps;
|
|
25181
|
+
const fns = Array.from({ length });
|
|
25182
|
+
for (let i = 0; i < length; i++) {
|
|
25183
|
+
fns[i] = taps[i].fn;
|
|
25184
|
+
}
|
|
25185
|
+
instance._x = fns;
|
|
25137
25186
|
}
|
|
25138
25187
|
|
|
25139
25188
|
/**
|
|
@@ -25141,12 +25190,17 @@ class HookCodeFactory {
|
|
|
25141
25190
|
*/
|
|
25142
25191
|
init(options) {
|
|
25143
25192
|
this.options = options;
|
|
25144
|
-
|
|
25193
|
+
// `_args` is only read (length / join / [0]) - never mutated - so we
|
|
25194
|
+
// can share the caller's array directly instead of paying for a copy
|
|
25195
|
+
// on every compile.
|
|
25196
|
+
this._args = options.args;
|
|
25197
|
+
this._joinedArgs = undefined;
|
|
25145
25198
|
}
|
|
25146
25199
|
|
|
25147
25200
|
deinit() {
|
|
25148
25201
|
this.options = undefined;
|
|
25149
25202
|
this._args = undefined;
|
|
25203
|
+
this._joinedArgs = undefined;
|
|
25150
25204
|
}
|
|
25151
25205
|
|
|
25152
25206
|
contentWithInterceptors(options) {
|
|
@@ -25221,7 +25275,10 @@ class HookCodeFactory {
|
|
|
25221
25275
|
}
|
|
25222
25276
|
|
|
25223
25277
|
needContext() {
|
|
25224
|
-
|
|
25278
|
+
const { taps } = this.options;
|
|
25279
|
+
for (let i = 0; i < taps.length; i++) {
|
|
25280
|
+
if (taps[i].context) return true;
|
|
25281
|
+
}
|
|
25225
25282
|
return false;
|
|
25226
25283
|
}
|
|
25227
25284
|
|
|
@@ -25330,17 +25387,30 @@ class HookCodeFactory {
|
|
|
25330
25387
|
doneReturns,
|
|
25331
25388
|
rethrowIfPossible
|
|
25332
25389
|
}) {
|
|
25333
|
-
|
|
25334
|
-
const
|
|
25390
|
+
const { taps } = this.options;
|
|
25391
|
+
const tapsLength = taps.length;
|
|
25392
|
+
if (tapsLength === 0) return onDone();
|
|
25393
|
+
// Inlined findIndex to avoid the callback allocation.
|
|
25394
|
+
let firstAsync = -1;
|
|
25395
|
+
for (let i = 0; i < tapsLength; i++) {
|
|
25396
|
+
if (taps[i].type !== "sync") {
|
|
25397
|
+
firstAsync = i;
|
|
25398
|
+
break;
|
|
25399
|
+
}
|
|
25400
|
+
}
|
|
25335
25401
|
const somethingReturns = resultReturns || doneReturns;
|
|
25402
|
+
// doneBreak doesn't depend on the loop variable - hoist to allocate once.
|
|
25403
|
+
const doneBreak = (skipDone) => {
|
|
25404
|
+
if (skipDone) return "";
|
|
25405
|
+
return onDone();
|
|
25406
|
+
};
|
|
25336
25407
|
let code = "";
|
|
25337
25408
|
let current = onDone;
|
|
25338
25409
|
let unrollCounter = 0;
|
|
25339
|
-
for (let j =
|
|
25410
|
+
for (let j = tapsLength - 1; j >= 0; j--) {
|
|
25340
25411
|
const i = j;
|
|
25341
25412
|
const unroll =
|
|
25342
|
-
current !== onDone &&
|
|
25343
|
-
(this.options.taps[i].type !== "sync" || unrollCounter++ > 20);
|
|
25413
|
+
current !== onDone && (taps[i].type !== "sync" || unrollCounter++ > 20);
|
|
25344
25414
|
if (unroll) {
|
|
25345
25415
|
unrollCounter = 0;
|
|
25346
25416
|
code += `function _next${i}() {\n`;
|
|
@@ -25349,10 +25419,6 @@ class HookCodeFactory {
|
|
|
25349
25419
|
current = () => `${somethingReturns ? "return " : ""}_next${i}();\n`;
|
|
25350
25420
|
}
|
|
25351
25421
|
const done = current;
|
|
25352
|
-
const doneBreak = (skipDone) => {
|
|
25353
|
-
if (skipDone) return "";
|
|
25354
|
-
return onDone();
|
|
25355
|
-
};
|
|
25356
25422
|
const content = this.callTap(i, {
|
|
25357
25423
|
onError: (error) => onError(i, error, done, doneBreak),
|
|
25358
25424
|
onResult:
|
|
@@ -25426,7 +25492,9 @@ class HookCodeFactory {
|
|
|
25426
25492
|
rethrowIfPossible,
|
|
25427
25493
|
onTap = (i, run) => run()
|
|
25428
25494
|
}) {
|
|
25429
|
-
|
|
25495
|
+
const { taps } = this.options;
|
|
25496
|
+
const tapsLength = taps.length;
|
|
25497
|
+
if (tapsLength <= 1) {
|
|
25430
25498
|
return this.callTapsSeries({
|
|
25431
25499
|
onError,
|
|
25432
25500
|
onResult,
|
|
@@ -25434,23 +25502,25 @@ class HookCodeFactory {
|
|
|
25434
25502
|
rethrowIfPossible
|
|
25435
25503
|
});
|
|
25436
25504
|
}
|
|
25505
|
+
// done and doneBreak don't depend on the loop variable - hoist them
|
|
25506
|
+
// so they're allocated once per compile instead of once per tap.
|
|
25507
|
+
const done = () => {
|
|
25508
|
+
if (onDone) return "if(--_counter === 0) _done();\n";
|
|
25509
|
+
return "--_counter;";
|
|
25510
|
+
};
|
|
25511
|
+
const doneBreak = (skipDone) => {
|
|
25512
|
+
if (skipDone || !onDone) return "_counter = 0;\n";
|
|
25513
|
+
return "_counter = 0;\n_done();\n";
|
|
25514
|
+
};
|
|
25437
25515
|
let code = "";
|
|
25438
25516
|
code += "do {\n";
|
|
25439
|
-
code += `var _counter = ${
|
|
25517
|
+
code += `var _counter = ${tapsLength};\n`;
|
|
25440
25518
|
if (onDone) {
|
|
25441
25519
|
code += "var _done = (function() {\n";
|
|
25442
25520
|
code += onDone();
|
|
25443
25521
|
code += "});\n";
|
|
25444
25522
|
}
|
|
25445
|
-
for (let i = 0; i <
|
|
25446
|
-
const done = () => {
|
|
25447
|
-
if (onDone) return "if(--_counter === 0) _done();\n";
|
|
25448
|
-
return "--_counter;";
|
|
25449
|
-
};
|
|
25450
|
-
const doneBreak = (skipDone) => {
|
|
25451
|
-
if (skipDone || !onDone) return "_counter = 0;\n";
|
|
25452
|
-
return "_counter = 0;\n_done();\n";
|
|
25453
|
-
};
|
|
25523
|
+
for (let i = 0; i < tapsLength; i++) {
|
|
25454
25524
|
code += "if(_counter <= 0) break;\n";
|
|
25455
25525
|
code += onTap(
|
|
25456
25526
|
i,
|
|
@@ -25484,14 +25554,23 @@ class HookCodeFactory {
|
|
|
25484
25554
|
}
|
|
25485
25555
|
|
|
25486
25556
|
args({ before, after } = {}) {
|
|
25487
|
-
|
|
25488
|
-
|
|
25489
|
-
|
|
25490
|
-
|
|
25491
|
-
|
|
25557
|
+
// Hot during code generation. Join `_args` once and cache the result,
|
|
25558
|
+
// then build the customized variants via string concat instead of
|
|
25559
|
+
// allocating temporary `[before, ...allArgs]` / `[...allArgs, after]`
|
|
25560
|
+
// arrays and re-joining.
|
|
25561
|
+
let joined = this._joinedArgs;
|
|
25562
|
+
if (joined === undefined) {
|
|
25563
|
+
joined = this._args.length === 0 ? "" : this._args.join(", ");
|
|
25564
|
+
this._joinedArgs = joined;
|
|
25492
25565
|
}
|
|
25493
|
-
|
|
25494
|
-
|
|
25566
|
+
if (!before && !after) return joined;
|
|
25567
|
+
if (joined.length === 0) {
|
|
25568
|
+
if (before && after) return `${before}, ${after}`;
|
|
25569
|
+
return before || after;
|
|
25570
|
+
}
|
|
25571
|
+
if (before && after) return `${before}, ${joined}, ${after}`;
|
|
25572
|
+
if (before) return `${before}, ${joined}`;
|
|
25573
|
+
return `${joined}, ${after}`;
|
|
25495
25574
|
}
|
|
25496
25575
|
|
|
25497
25576
|
getTapFn(idx) {
|
|
@@ -25539,7 +25618,11 @@ class HookMap {
|
|
|
25539
25618
|
}
|
|
25540
25619
|
|
|
25541
25620
|
for(key) {
|
|
25542
|
-
|
|
25621
|
+
// Hot path: inline the map lookup to skip the `this.get(key)`
|
|
25622
|
+
// indirection. This gets hit on every hook access in consumers
|
|
25623
|
+
// like webpack.
|
|
25624
|
+
const map = this._map;
|
|
25625
|
+
const hook = map.get(key);
|
|
25543
25626
|
if (hook !== undefined) {
|
|
25544
25627
|
return hook;
|
|
25545
25628
|
}
|
|
@@ -25548,7 +25631,7 @@ class HookMap {
|
|
|
25548
25631
|
for (let i = 0; i < interceptors.length; i++) {
|
|
25549
25632
|
newHook = interceptors[i].factory(key, newHook);
|
|
25550
25633
|
}
|
|
25551
|
-
|
|
25634
|
+
map.set(key, newHook);
|
|
25552
25635
|
return newHook;
|
|
25553
25636
|
}
|
|
25554
25637
|
|
|
@@ -25606,33 +25689,38 @@ class MultiHook {
|
|
|
25606
25689
|
}
|
|
25607
25690
|
|
|
25608
25691
|
tap(options, fn) {
|
|
25609
|
-
|
|
25610
|
-
|
|
25692
|
+
const { hooks } = this;
|
|
25693
|
+
for (let i = 0; i < hooks.length; i++) {
|
|
25694
|
+
hooks[i].tap(options, fn);
|
|
25611
25695
|
}
|
|
25612
25696
|
}
|
|
25613
25697
|
|
|
25614
25698
|
tapAsync(options, fn) {
|
|
25615
|
-
|
|
25616
|
-
|
|
25699
|
+
const { hooks } = this;
|
|
25700
|
+
for (let i = 0; i < hooks.length; i++) {
|
|
25701
|
+
hooks[i].tapAsync(options, fn);
|
|
25617
25702
|
}
|
|
25618
25703
|
}
|
|
25619
25704
|
|
|
25620
25705
|
tapPromise(options, fn) {
|
|
25621
|
-
|
|
25622
|
-
|
|
25706
|
+
const { hooks } = this;
|
|
25707
|
+
for (let i = 0; i < hooks.length; i++) {
|
|
25708
|
+
hooks[i].tapPromise(options, fn);
|
|
25623
25709
|
}
|
|
25624
25710
|
}
|
|
25625
25711
|
|
|
25626
25712
|
isUsed() {
|
|
25627
|
-
|
|
25628
|
-
|
|
25713
|
+
const { hooks } = this;
|
|
25714
|
+
for (let i = 0; i < hooks.length; i++) {
|
|
25715
|
+
if (hooks[i].isUsed()) return true;
|
|
25629
25716
|
}
|
|
25630
25717
|
return false;
|
|
25631
25718
|
}
|
|
25632
25719
|
|
|
25633
25720
|
intercept(interceptor) {
|
|
25634
|
-
|
|
25635
|
-
|
|
25721
|
+
const { hooks } = this;
|
|
25722
|
+
for (let i = 0; i < hooks.length; i++) {
|
|
25723
|
+
hooks[i].intercept(interceptor);
|
|
25636
25724
|
}
|
|
25637
25725
|
}
|
|
25638
25726
|
|
|
@@ -25886,25 +25974,26 @@ module.exports = SyncWaterfallHook;
|
|
|
25886
25974
|
(module, __unused_webpack_exports, __webpack_require__) {
|
|
25887
25975
|
|
|
25888
25976
|
"use strict";
|
|
25977
|
+
var __webpack_unused_export__;
|
|
25889
25978
|
/*
|
|
25890
25979
|
MIT License http://www.opensource.org/licenses/mit-license.php
|
|
25891
25980
|
Author Tobias Koppers @sokra
|
|
25892
25981
|
*/
|
|
25893
25982
|
|
|
25894
25983
|
|
|
25895
|
-
|
|
25896
|
-
|
|
25984
|
+
/* unused reexport */ __webpack_require__(6066);
|
|
25985
|
+
/* unused reexport */ __webpack_require__(7806);
|
|
25897
25986
|
module.exports.AsyncSeriesBailHook = __webpack_require__(2412);
|
|
25898
25987
|
module.exports.AsyncSeriesHook = __webpack_require__(1468);
|
|
25899
|
-
|
|
25900
|
-
|
|
25901
|
-
|
|
25902
|
-
|
|
25903
|
-
|
|
25988
|
+
/* unused reexport */ __webpack_require__(6170);
|
|
25989
|
+
/* unused reexport */ __webpack_require__(2522);
|
|
25990
|
+
/* unused reexport */ __webpack_require__(4517);
|
|
25991
|
+
/* unused reexport */ __webpack_require__(9552);
|
|
25992
|
+
/* unused reexport */ __webpack_require__(2440);
|
|
25904
25993
|
module.exports.SyncHook = __webpack_require__(8752);
|
|
25905
|
-
|
|
25906
|
-
|
|
25907
|
-
|
|
25994
|
+
/* unused reexport */ __webpack_require__(4502);
|
|
25995
|
+
/* unused reexport */ __webpack_require__(470);
|
|
25996
|
+
__webpack_unused_export__ = true;
|
|
25908
25997
|
|
|
25909
25998
|
|
|
25910
25999
|
/***/ },
|
|
@@ -29799,7 +29888,14 @@ function isIntegrationEmbeddingModelSpec(model) {
|
|
|
29799
29888
|
* The supported AI image generation model names.
|
|
29800
29889
|
* @category AI
|
|
29801
29890
|
*/
|
|
29802
|
-
exports.OPENAI_IMAGE_MODEL_NAMES = [
|
|
29891
|
+
exports.OPENAI_IMAGE_MODEL_NAMES = [
|
|
29892
|
+
'gpt-image-1',
|
|
29893
|
+
'gpt-image-1-mini',
|
|
29894
|
+
'gpt-image-1.5',
|
|
29895
|
+
'gpt-image-2',
|
|
29896
|
+
'gpt-image-2-2026-04-21',
|
|
29897
|
+
'chatgpt-image-latest',
|
|
29898
|
+
];
|
|
29803
29899
|
/**
|
|
29804
29900
|
* @category AI
|
|
29805
29901
|
*/
|
|
@@ -30131,7 +30227,7 @@ function getConsoleAppRegionByStage(stage) {
|
|
|
30131
30227
|
case 'sandbox':
|
|
30132
30228
|
return 'us-east-1.aws.sandbox';
|
|
30133
30229
|
case 'staging':
|
|
30134
|
-
return '
|
|
30230
|
+
return 'squidai.westus3.azure.staging';
|
|
30135
30231
|
}
|
|
30136
30232
|
}
|
|
30137
30233
|
|
|
@@ -30456,7 +30552,6 @@ exports.KOTLIN_CONTROLLERS = [
|
|
|
30456
30552
|
'scheduler',
|
|
30457
30553
|
'secret',
|
|
30458
30554
|
'ws',
|
|
30459
|
-
'internal-extraction',
|
|
30460
30555
|
'notification',
|
|
30461
30556
|
];
|
|
30462
30557
|
function getEnvironmentPrefix(shard, region, cloudId, stage) {
|
|
@@ -37355,14 +37450,6 @@ terminalLink.stderr = (text, url, options = {}) => terminalLink(text, url, {targ
|
|
|
37355
37450
|
terminalLink.stderr.isSupported = supports_hyperlinks.stderr;
|
|
37356
37451
|
|
|
37357
37452
|
|
|
37358
|
-
/***/ },
|
|
37359
|
-
|
|
37360
|
-
/***/ 2108
|
|
37361
|
-
(module) {
|
|
37362
|
-
|
|
37363
|
-
"use strict";
|
|
37364
|
-
module.exports = /*#__PURE__*/JSON.parse('{"name":"dotenv","version":"17.3.1","description":"Loads environment variables from .env file","main":"lib/main.js","types":"lib/main.d.ts","exports":{".":{"types":"./lib/main.d.ts","require":"./lib/main.js","default":"./lib/main.js"},"./config":"./config.js","./config.js":"./config.js","./lib/env-options":"./lib/env-options.js","./lib/env-options.js":"./lib/env-options.js","./lib/cli-options":"./lib/cli-options.js","./lib/cli-options.js":"./lib/cli-options.js","./package.json":"./package.json"},"scripts":{"dts-check":"tsc --project tests/types/tsconfig.json","lint":"standard","pretest":"npm run lint && npm run dts-check","test":"tap run tests/**/*.js --allow-empty-coverage --disable-coverage --timeout=60000","test:coverage":"tap run tests/**/*.js --show-full-coverage --timeout=60000 --coverage-report=text --coverage-report=lcov","prerelease":"npm test","release":"standard-version"},"repository":{"type":"git","url":"git://github.com/motdotla/dotenv.git"},"homepage":"https://github.com/motdotla/dotenv#readme","funding":"https://dotenvx.com","keywords":["dotenv","env",".env","environment","variables","config","settings"],"readmeFilename":"README.md","license":"BSD-2-Clause","devDependencies":{"@types/node":"^18.11.3","decache":"^4.6.2","sinon":"^14.0.1","standard":"^17.0.0","standard-version":"^9.5.0","tap":"^19.2.0","typescript":"^4.8.4"},"engines":{"node":">=12"},"browser":{"fs":false}}');
|
|
37365
|
-
|
|
37366
37453
|
/***/ },
|
|
37367
37454
|
|
|
37368
37455
|
/***/ 1994
|
|
@@ -37377,7 +37464,7 @@ module.exports = /*#__PURE__*/JSON.parse('{"name":"seek-bzip","version":"1.0.6",
|
|
|
37377
37464
|
(module) {
|
|
37378
37465
|
|
|
37379
37466
|
"use strict";
|
|
37380
|
-
module.exports = /*#__PURE__*/JSON.parse('{"name":"@squidcloud/cli","version":"1.0.
|
|
37467
|
+
module.exports = /*#__PURE__*/JSON.parse('{"name":"@squidcloud/cli","version":"1.0.464","description":"The Squid CLI","main":"dist/index.js","scripts":{"start":"node dist/index.js","start-ts":"ts-node -r tsconfig-paths/register src/index.ts","prebuild":"rimraf dist","build":"webpack --mode=production","build:dev":"webpack --mode=development","lint":"eslint","link":"npm run build && chmod 755 dist/index.js && npm link","watch":"webpack --watch","deploy":"npm run build && npm pack --silent | xargs -I {} mv {} package.tgz && npm install -g package.tgz && rm -rf package.tgz","publish:public":"npm run build && npm publish --access public"},"files":["dist/**/*"],"bin":{"squid":"dist/index.js"},"keywords":[],"author":"","license":"ISC","engines":{"node":">=18.0.0"},"dependencies":{"@squidcloud/local-backend":"^1.0.464","adm-zip":"^0.5.16","copy-webpack-plugin":"^14.0.0","decompress":"^4.2.1","logpipes":"^1.11.0","nodemon":"^3.1.9","terser-webpack-plugin":"^5.5.0","ts-loader":"^9.5.1","ts-node":"^10.9.2","tsconfig-paths":"^4.2.0","tsconfig-paths-webpack-plugin":"^4.1.0","webpack":"^5.106.2","zip-webpack-plugin":"^4.0.1"},"devDependencies":{"@types/adm-zip":"^0.5.7","@types/decompress":"^4.2.7","@types/node":"^20.19.9","terminal-link":"^3.0.0"}}');
|
|
37381
37468
|
|
|
37382
37469
|
/***/ }
|
|
37383
37470
|
|
|
@@ -26,7 +26,7 @@ Squid is a backend-as-a-service platform that provides:
|
|
|
26
26
|
- **[ai.md](reference/ai.md)** → AI agents, chat, ask, askWithAnnotations, askAsync, askWithVoiceResponse, transcribeAndChat, transcribeAndAsk, knowledge bases, RAG, embeddings, image generation, audio, transcription, text-to-speech, TTS, connectedAgents, connectedIntegrations, connectedKnowledgeBases, @aiFunction, @secureAiAgent, @secureAiQuery, memory, memoryOptions, voiceOptions, OpenAI, Anthropic, Gemini, Grok, DALL-E, Whisper, MCP, @mcpServer, @mcpTool, executeAiQuery, executeAiApiCall, extraction, createPdf, upsert agent, listAgents
|
|
27
27
|
- **[chat-widget.md](reference/chat-widget.md)** → AI chat widget, @squidcloud/react-chat-widget, squid-chat-widget, squid-chat-widget-with-fab-button, embeddable chat, custom API webhook, AI query mode, chain-of-thought, status updates, session management, agentContext, memoryOptions, squid-ai-custom-api-url, squid-ai-agent-chat-options, FAB button, theming, CSS variables, localization, RTL, menu items slots, suggested prompts, voice transcription, error formatting, authentication, squid-auth-provider, onChange events
|
|
28
28
|
- **[databases.md](reference/databases.md)** → collections, documents, queries, subscriptions, snapshots, insert, update, delete, CRUD, real-time, dereference, pagination, transactions, query operators, eq, neq, gt, gte, lt, lte, like, in, nin, arrayIncludesSome, arrayIncludesAll, sortBy, limit, join queries, OR queries, @trigger, native queries, SQL, MongoDB, Elasticsearch, incrementInPath, decrementInPath, watch changes, doc(), projectFields, field projection, __docId__, __id
|
|
29
|
-
- **[backend.md](reference/backend.md)** → SquidService, @executable, @webhook, @trigger, TriggerRequest, @scheduler, @limits, rate limiting, quotas, decorators, backend functions, WebhookRequest, CronExpression, cron, file handling, SquidFile, getUserAuth, isAuthenticated, assertIsAuthenticated, createWebhookResponse, this.squid, this.secrets, @clientConnectionStateHandler, CLI, squid init, squid start, squid deploy, squid build, project structure, multiple services, service architecture, squidInject, cross-service communication
|
|
29
|
+
- **[backend.md](reference/backend.md)** → SquidService, @executable, @webhook, @trigger, TriggerRequest, @scheduler, @limits, rate limiting, quotas, decorators, backend functions, WebhookRequest, CronExpression, cron, file handling, SquidFile, getUserAuth, isAuthenticated, assertIsAuthenticated, createWebhookResponse, this.squid, this.secrets, @clientConnectionStateHandler, @onQueueMessage, QueueMessageRequest, queue message handler, server-side queue consumer, CLI, squid init, squid start, squid deploy, squid build, project structure, multiple services, service architecture, squidInject, cross-service communication
|
|
30
30
|
- **[security.md](reference/security.md)** → security rules, @secureDatabase, @secureCollection, @secureTopic, @secureStorage, @secureApi, @secureNativeQuery, @secureAiQuery, @secureAiAgent, @secureDistributedLock, @secureGraphQL, QueryContext, MutationContext, isSubqueryOf, affectsPath, permissions, authorization, row-level security, role-based access
|
|
31
31
|
- **[admin.md](reference/admin.md)** → ManagementClient, management API keys, organizations, applications, programmatic management, CI/CD, automation, integrations admin, secrets admin, upsertIntegration, discoverDataConnectionSchema, testDataConnection, createOrganization, createApplication
|
|
32
32
|
- **[api.md](reference/api.md)** → API, REST API, HTTP endpoints, API reference, Agent API, AI Audio API, AI Image API, KnowledgeBase API, Matchmaking API, Web Utilities API, Database API, Extraction API
|
|
@@ -79,6 +79,7 @@ Client → Squid Cloud → Your Backend → Integration → Response
|
|
|
79
79
|
| Webhooks from external services | **Yes** | Use `@webhook` decorator |
|
|
80
80
|
| Scheduled jobs | **Yes** | Use `@scheduler` decorator |
|
|
81
81
|
| Server-side secrets | **Yes** | Access via `this.secrets` |
|
|
82
|
+
| Handle queue messages server-side | **Yes** | Use `@onQueueMessage` decorator |
|
|
82
83
|
|
|
83
84
|
### What Squid Cloud Handles
|
|
84
85
|
|
|
@@ -17,10 +17,11 @@ Docs: https://docs.getsquid.ai/reference-docs/backend/
|
|
|
17
17
|
- Triggers (@trigger)
|
|
18
18
|
- Schedulers (@scheduler)
|
|
19
19
|
- Rate Limiting (@limits)
|
|
20
|
+
- Queue Message Handlers (@onQueueMessage)
|
|
20
21
|
- Client Connection State (@clientConnectionStateHandler)
|
|
21
22
|
- Cross-Service Communication (squidInject)
|
|
22
23
|
- Using Squid Client in Backend
|
|
23
|
-
- File Handling
|
|
24
|
+
- File Handling
|
|
24
25
|
|
|
25
26
|
## CLI Commands
|
|
26
27
|
|
|
@@ -461,6 +462,44 @@ export class MyService extends SquidService {
|
|
|
461
462
|
**Scopes:** `'global'`, `'user'`, `'ip'`
|
|
462
463
|
**Periods:** `'hourly'`, `'daily'`, `'weekly'`, `'monthly'`, `'quarterly'`, `'annually'`
|
|
463
464
|
|
|
465
|
+
## Queue Message Handlers (@onQueueMessage)
|
|
466
|
+
|
|
467
|
+
The `@onQueueMessage` decorator registers a backend handler that is called server-side whenever a message is produced to a queue topic. Unlike client-side `.consume()`, this handler runs in the backend with full permissions and no client connection required.
|
|
468
|
+
|
|
469
|
+
```typescript
|
|
470
|
+
import { SquidService, onQueueMessage, QueueMessageRequest } from '@squidcloud/backend';
|
|
471
|
+
|
|
472
|
+
export class MyService extends SquidService {
|
|
473
|
+
// Built-in queue (default integration)
|
|
474
|
+
@onQueueMessage<string>('notifications')
|
|
475
|
+
async onNotification(request: QueueMessageRequest<string>): Promise<void> {
|
|
476
|
+
console.log(request.message); // The message payload (typed)
|
|
477
|
+
console.log(request.topicName); // 'notifications'
|
|
478
|
+
console.log(request.integrationId); // 'built_in_queue'
|
|
479
|
+
// Full backend permissions: this.squid, this.secrets, etc.
|
|
480
|
+
await this.squid.collection('log').doc().insert({ msg: request.message });
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// External Kafka integration
|
|
484
|
+
@onQueueMessage<OrderEvent>('orders', 'kafka')
|
|
485
|
+
async onKafkaOrder(request: QueueMessageRequest<OrderEvent>): Promise<void> {
|
|
486
|
+
console.log(request.message); // Typed OrderEvent payload
|
|
487
|
+
console.log(request.integrationId); // 'kafka'
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
**`QueueMessageRequest<T>`:**
|
|
493
|
+
- `message: T` - The message payload (typed by the decorator's generic parameter)
|
|
494
|
+
- `topicName: string` - The topic name the message was received on
|
|
495
|
+
- `integrationId: string` - The integration ID (`'built_in_queue'` or custom)
|
|
496
|
+
|
|
497
|
+
**Notes:**
|
|
498
|
+
- The handler is called once per message, server-side — no client needs to be connected
|
|
499
|
+
- Works with both built-in queue and external Kafka integrations
|
|
500
|
+
- To secure the topic, use `@secureTopic` — see [security.md](security.md)
|
|
501
|
+
- The handler receives each message individually (not batched)
|
|
502
|
+
|
|
464
503
|
## Client Connection State (@clientConnectionStateHandler)
|
|
465
504
|
|
|
466
505
|
Handle client connection and disconnection events.
|
|
@@ -285,7 +285,7 @@ const subscription = queue.consume<Message>().subscribe(message => {
|
|
|
285
285
|
subscription.unsubscribe();
|
|
286
286
|
```
|
|
287
287
|
|
|
288
|
-
To secure queue topics, see [security.md](security.md) for `@secureTopic`. For Kafka and other queue integrations, see [connectors.md](connectors.md).
|
|
288
|
+
To secure queue topics, see [security.md](security.md) for `@secureTopic`. For Kafka and other queue integrations, see [connectors.md](connectors.md). To handle messages server-side without a client subscriber, use `@onQueueMessage` in your backend — see [backend.md](backend.md).
|
|
289
289
|
|
|
290
290
|
## Distributed Locks
|
|
291
291
|
|
|
@@ -73,13 +73,13 @@ const voiceResult = await agent.askWithVoiceResponse('Hello', {
|
|
|
73
73
|
});
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
-
## Image Generation (
|
|
76
|
+
## Image Generation (gpt-image-*)
|
|
77
77
|
|
|
78
78
|
```typescript
|
|
79
79
|
const imageUrl = await squid.ai().image().generate('A futuristic city', {
|
|
80
|
-
modelName: '
|
|
81
|
-
quality: '
|
|
82
|
-
size: '1024x1024' // '1024x1024' | '
|
|
80
|
+
modelName: 'gpt-image-1',
|
|
81
|
+
quality: 'high', // 'auto' | 'high' | 'medium' | 'low'
|
|
82
|
+
size: '1024x1024' // '1024x1024' | '1024x1536' | '1536x1024' | 'auto'
|
|
83
83
|
});
|
|
84
84
|
```
|
|
85
85
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@squidcloud/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.464",
|
|
4
4
|
"description": "The Squid CLI",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -28,18 +28,18 @@
|
|
|
28
28
|
"node": ">=18.0.0"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@squidcloud/local-backend": "^1.0.
|
|
31
|
+
"@squidcloud/local-backend": "^1.0.464",
|
|
32
32
|
"adm-zip": "^0.5.16",
|
|
33
|
-
"copy-webpack-plugin": "^
|
|
33
|
+
"copy-webpack-plugin": "^14.0.0",
|
|
34
34
|
"decompress": "^4.2.1",
|
|
35
35
|
"logpipes": "^1.11.0",
|
|
36
36
|
"nodemon": "^3.1.9",
|
|
37
|
-
"terser-webpack-plugin": "^5.
|
|
37
|
+
"terser-webpack-plugin": "^5.5.0",
|
|
38
38
|
"ts-loader": "^9.5.1",
|
|
39
39
|
"ts-node": "^10.9.2",
|
|
40
40
|
"tsconfig-paths": "^4.2.0",
|
|
41
41
|
"tsconfig-paths-webpack-plugin": "^4.1.0",
|
|
42
|
-
"webpack": "^5.
|
|
42
|
+
"webpack": "^5.106.2",
|
|
43
43
|
"zip-webpack-plugin": "^4.0.1"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|