@udondan/avanti 0.23.1 → 0.25.0
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 +578 -65
- package/dist/commands/diff.d.ts.map +1 -1
- package/dist/commands/diff.js +82 -15
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/lock.d.ts.map +1 -1
- package/dist/commands/lock.js +3 -2
- package/dist/commands/lock.js.map +1 -1
- package/dist/commands/log.d.ts.map +1 -1
- package/dist/commands/log.js +7 -5
- package/dist/commands/log.js.map +1 -1
- package/dist/commands/pull.d.ts.map +1 -1
- package/dist/commands/pull.js +695 -32
- package/dist/commands/pull.js.map +1 -1
- package/dist/commands/reset.d.ts.map +1 -1
- package/dist/commands/reset.js +43 -11
- package/dist/commands/reset.js.map +1 -1
- package/dist/commands/revert.d.ts.map +1 -1
- package/dist/commands/revert.js +68 -14
- package/dist/commands/revert.js.map +1 -1
- package/dist/condition.d.ts.map +1 -1
- package/dist/condition.js +9 -6
- package/dist/condition.js.map +1 -1
- package/dist/config-writeback.d.ts.map +1 -1
- package/dist/config-writeback.js +33 -4
- package/dist/config-writeback.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +396 -10
- package/dist/config.js.map +1 -1
- package/dist/diff.d.ts +25 -1
- package/dist/diff.d.ts.map +1 -1
- package/dist/diff.js +410 -28
- package/dist/diff.js.map +1 -1
- package/dist/extract.d.ts +4 -0
- package/dist/extract.d.ts.map +1 -0
- package/dist/extract.js +142 -0
- package/dist/extract.js.map +1 -0
- package/dist/filter.d.ts +3 -0
- package/dist/filter.d.ts.map +1 -0
- package/dist/filter.js +126 -0
- package/dist/filter.js.map +1 -0
- package/dist/history.d.ts +7 -1
- package/dist/history.d.ts.map +1 -1
- package/dist/history.js +89 -9
- package/dist/history.js.map +1 -1
- package/dist/paths.d.ts +4 -0
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +97 -0
- package/dist/paths.js.map +1 -1
- package/dist/processors/ini.d.ts +33 -0
- package/dist/processors/ini.d.ts.map +1 -0
- package/dist/processors/ini.js +500 -0
- package/dist/processors/ini.js.map +1 -0
- package/dist/processors/insert.d.ts.map +1 -1
- package/dist/processors/insert.js +338 -15
- package/dist/processors/insert.js.map +1 -1
- package/dist/processors/on.d.ts +4 -0
- package/dist/processors/on.d.ts.map +1 -0
- package/dist/processors/on.js +54 -0
- package/dist/processors/on.js.map +1 -0
- package/dist/ref.d.ts +21 -0
- package/dist/ref.d.ts.map +1 -0
- package/dist/ref.js +65 -0
- package/dist/ref.js.map +1 -0
- package/dist/sources/bitbucket.d.ts.map +1 -1
- package/dist/sources/bitbucket.js +51 -12
- package/dist/sources/bitbucket.js.map +1 -1
- package/dist/sources/git.d.ts.map +1 -1
- package/dist/sources/git.js +54 -6
- package/dist/sources/git.js.map +1 -1
- package/dist/sources/github.d.ts +1 -0
- package/dist/sources/github.d.ts.map +1 -1
- package/dist/sources/github.js +287 -50
- package/dist/sources/github.js.map +1 -1
- package/dist/sources/gitlab.d.ts +1 -0
- package/dist/sources/gitlab.d.ts.map +1 -1
- package/dist/sources/gitlab.js +387 -28
- package/dist/sources/gitlab.js.map +1 -1
- package/dist/sources/index.d.ts +3 -1
- package/dist/sources/index.d.ts.map +1 -1
- package/dist/sources/index.js +206 -44
- package/dist/sources/index.js.map +1 -1
- package/dist/sources/local.d.ts +3 -0
- package/dist/sources/local.d.ts.map +1 -1
- package/dist/sources/local.js +44 -0
- package/dist/sources/local.js.map +1 -1
- package/dist/types.d.ts +71 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/variables-remote.d.ts.map +1 -1
- package/dist/variables-remote.js +88 -7
- package/dist/variables-remote.js.map +1 -1
- package/dist/variables.d.ts +1 -0
- package/dist/variables.d.ts.map +1 -1
- package/dist/variables.js +133 -12
- package/dist/variables.js.map +1 -1
- package/dist/writer.d.ts +18 -0
- package/dist/writer.d.ts.map +1 -1
- package/dist/writer.js +968 -25
- package/dist/writer.js.map +1 -1
- package/package.json +12 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-writeback.js","sourceRoot":"","sources":["../src/config-writeback.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,
|
|
1
|
+
{"version":3,"file":"config-writeback.js","sourceRoot":"","sources":["../src/config-writeback.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,4CAsNC;AAOD,4CAcC;AAnPD,uCAAyB;AACzB,+BAA6D;AAC7D,qCAAuC;AAEvC;;;GAGG;AACH,SAAgB,gBAAgB,CAC9B,GAAW,EACX,OAA4B;IAE5B,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACpC,MAAM,GAAG,GAAG,IAAA,oBAAa,EAAC,GAAG,CAAC,CAAC;IAE/B,MAAM,SAAS,GAAG,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACzC,IAAI,CAAC,IAAA,YAAK,EAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IAEnC,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QAC/B,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,OAAO;QAC9C,MAAM,CAAC,GAAG,IAA0C,CAAC;QACrD,MAAM,SAAS,GACb,CAAC,CAAC,GAAG,IAAI,IAAI,IAAI,IAAA,eAAQ,EAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAChE,IAAI,CAAC,SAAS;YAAE,OAAO;QAEvB,MAAM,SAAS,GAAG,CAAC,CAAC,KAEZ,CAAC;QACT,IAAI,CAAC,SAAS,EAAE,GAAG;YAAE,OAAO;QAE5B,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC3C,IAAI,CAAC,OAAO;YAAE,OAAO;QAErB,uEAAuE;QACvE,yEAAyE;QACzE,MAAM,cAAc,GAAG,CACrB,IAAa,EACb,MAAc,EACd,KAAc,EACR,EAAE;YACR,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;gBAAE,OAAO;YAC9C,MAAM,CAAC,GAAG,IAA8D,CAAC;YACzE,IAAI,CAAC,CAAC,CAAC,GAAG;gBAAE,OAAO;YAEnB,MAAM,OAAO,GAAwB,KAAK;gBACxC,CAAC,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC;gBACrC,CAAC,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;YAEhC,IAAI,KAAK,GAAkB,IAAI,CAAC;YAChC,IAAI,OAAO,GAA+B,IAAI,CAAC;YAC/C,IAAI,cAAc,GAAG,KAAK,CAAC;YAE3B,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACpB,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAEjB,CAAC;gBACT,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC;oBACZ,MAAM,IAAI,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAkB,CAAC;oBAC7C,MAAM,IAAI,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAkB,CAAC;oBAC7C,MAAM,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,SAAS,CAAkB,CAAC;oBACnD,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAkB,CAAC;oBAC3C,MAAM,IAAI,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAkB,CAAC;oBAC7C,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,EAAE,CAAC;wBAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;wBACzC,IAAI,OAAO,EAAE,CAAC;4BACZ,KAAK,GAAG,SAAS,QAAQ,IAAI,IAAI,YAAY,OAAO,EAAE,CAAC;wBACzD,CAAC;6BAAM,CAAC;4BACN,KAAK,GAAG,SAAS,QAAQ,IAAI,IAAI,IAAI,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;wBACrE,CAAC;wBACD,OAAO,GAAG,CAAC,GAAG,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;wBACxC,cAAc,GAAG,IAAI,CAAC;oBACxB,CAAC;gBACH,CAAC;YACH,CAAC;iBAAM,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC3B,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAA4C,CAAC;gBACtE,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC;oBACZ,MAAM,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,SAAS,CAAkB,CAAC;oBACnD,MAAM,IAAI,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAkB,CAAC;oBAC7C,MAAM,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,SAAS,CAAkB,CAAC;oBACnD,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAkB,CAAC;oBAC3C,MAAM,IAAI,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAkB,CAAC;oBAC7C,IAAI,OAAO,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,EAAE,CAAC;wBACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;wBACzC,IAAI,OAAO,EAAE,CAAC;4BACZ,KAAK,GAAG,SAAS,QAAQ,IAAI,OAAO,YAAY,OAAO,EAAE,CAAC;wBAC5D,CAAC;6BAAM,CAAC;4BACN,KAAK,GAAG,SAAS,QAAQ,IAAI,OAAO,IAAI,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;wBACxE,CAAC;wBACD,OAAO,GAAG,CAAC,GAAG,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;wBACxC,cAAc,GAAG,IAAI,CAAC;oBACxB,CAAC;gBACH,CAAC;YACH,CAAC;iBAAM,IAAI,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC9B,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,WAAW,CAEpB,CAAC;gBACT,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC;oBACZ,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,WAAW,CAAkB,CAAC;oBAChD,MAAM,IAAI,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAkB,CAAC;oBAC7C,MAAM,IAAI,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAkB,CAAC;oBAC7C,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAkB,CAAC;oBAC3C,MAAM,IAAI,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAkB,CAAC;oBAC7C,IAAI,EAAE,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;wBACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;wBACzC,KAAK,GAAG,YAAY,QAAQ,IAAI,EAAE,IAAI,IAAI,IAAI,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;wBAC5E,OAAO,GAAG,CAAC,GAAG,OAAO,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;wBAC3C,cAAc,GAAG,IAAI,CAAC;oBACxB,CAAC;gBACH,CAAC;YACH,CAAC;iBAAM,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBACxB,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAA4C,CAAC;gBACnE,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC;oBACZ,MAAM,IAAI,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAkB,CAAC;oBAC7C,MAAM,IAAI,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAkB,CAAC;oBAC7C,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAkB,CAAC;oBAC3C,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;wBACjB,KAAK,GAAG,OAAO,IAAI,IAAI,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;wBACrD,OAAO,GAAG,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;wBACrC,cAAc,GAAG,IAAI,CAAC;oBACxB,CAAC;gBACH,CAAC;YACH,CAAC;iBAAM,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,SAAS,EAAE,CAAC;gBACvC,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAkB,CAAC;gBAC3C,IAAI,GAAG,EAAE,CAAC;oBACR,KAAK,GAAG,QAAQ,GAAG,EAAE,CAAC;oBACtB,OAAO,GAAG,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC,CAAC;gBAChC,CAAC;YACH,CAAC;iBAAM,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,SAAS,EAAE,CAAC;gBACzC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAkB,CAAC;gBAC5C,IAAI,EAAE,EAAE,CAAC;oBACP,KAAK,GAAG,UAAU,EAAE,EAAE,CAAC;oBACvB,OAAO,GAAG,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC,CAAC;oBAC9B,cAAc,GAAG,IAAI,CAAC;gBACxB,CAAC;YACH,CAAC;iBAAM,IAAI,CAAC,CAAC,GAAG,CAAC,qBAAqB,CAAC,EAAE,CAAC;gBACxC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,qBAAqB,CAE9B,CAAC;gBACT,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC;oBACZ,MAAM,MAAM,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAkB,CAAC;oBAC/C,MAAM,KAAK,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAkB,CAAC;oBAC7C,MAAM,QAAQ,GAAG,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAkB,CAAC;oBACnD,IAAI,MAAM,EAAE,CAAC;wBACX,KAAK,GAAG,uBAAuB,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;wBACpG,OAAO,GAAG,CAAC,GAAG,OAAO,EAAE,qBAAqB,EAAE,KAAK,CAAC,CAAC;oBACvD,CAAC;gBACH,CAAC;YACH,CAAC;iBAAM,IAAI,CAAC,CAAC,GAAG,CAAC,+BAA+B,CAAC,EAAE,CAAC;gBAClD,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,+BAA+B,CAEzC,CAAC;gBACT,IAAI,GAAG,EAAE,GAAG,EAAE,CAAC;oBACb,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,CAAkB,CAAC;oBACjD,MAAM,SAAS,GAAG,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAkB,CAAC;oBACrD,IAAI,OAAO,EAAE,CAAC;wBACZ,KAAK,GAAG,iCAAiC,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;wBACtF,OAAO,GAAG,CAAC,GAAG,OAAO,EAAE,+BAA+B,EAAE,KAAK,CAAC,CAAC;oBACjE,CAAC;gBACH,CAAC;YACH,CAAC;iBAAM,IAAI,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC1B,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAA4C,CAAC;gBACrE,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC;oBACZ,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAkB,CAAC;oBAC1C,MAAM,KAAK,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAkB,CAAC;oBAC/C,IAAI,CAAC,EAAE,CAAC;wBACN,KAAK,GAAG,SAAS,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;wBAChD,OAAO,GAAG,CAAC,GAAG,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;oBACzC,CAAC;gBACH,CAAC;YACH,CAAC;iBAAM,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,SAAS,EAAE,CAAC;gBACvC,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAkB,CAAC;gBAC3C,IAAI,GAAG,EAAE,CAAC;oBACR,KAAK,GAAG,QAAQ,GAAG,EAAE,CAAC;oBACtB,OAAO,GAAG,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC,CAAC;gBAChC,CAAC;YACH,CAAC;iBAAM,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,SAAS,EAAE,CAAC;gBACvC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAkB,CAAC;gBACzC,IAAI,CAAC,EAAE,CAAC;oBACN,KAAK,GAAG,QAAQ,CAAC,EAAE,CAAC;oBACpB,OAAO,GAAG,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC,CAAC;oBAC9B,cAAc,GAAG,IAAI,CAAC;gBACxB,CAAC;YACH,CAAC;iBAAM,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,SAAS,EAAE,CAAC;gBACtC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAkB,CAAC;gBACxC,IAAI,CAAC,EAAE,CAAC;oBACN,KAAK,GAAG,OAAO,CAAC,EAAE,CAAC;oBACnB,OAAO,GAAG,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC,CAAC;gBAChC,CAAC;YACH,CAAC;YAED,IAAI,KAAK,IAAI,cAAc,EAAE,CAAC;gBAC5B,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;gBACxC,IAAI,IAAA,YAAK,EAAC,SAAS,CAAC,IAAI,SAAS,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACnD,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK;yBAC9B,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAA,eAAQ,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;yBAC3D,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;oBAC1D,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;wBACtB,KAAK,IAAI,cAAc,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC;gBACvD,CAAC;YACH,CAAC;YAED,IAAI,KAAK,IAAI,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC3C,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC;gBACnC,IAAK,GAAG,CAAC,KAAK,CAAC,OAAO,CAAwB,KAAK,MAAM,EAAE,CAAC;oBAC1D,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;oBAC3B,OAAO,GAAG,IAAI,CAAC;gBACjB,CAAC;YACH,CAAC;QACH,CAAC,CAAC;QAEF,IAAI,IAAA,YAAK,EAAC,OAAO,CAAC,EAAE,CAAC;YACnB,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;gBAClC,cAAc,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;YAClC,CAAC,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,cAAc,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QACpC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACzC,CAAC;AAED;;;;GAIG;AACH,SAAgB,gBAAgB,CAC9B,UAAkB,EAClB,OAA4B;IAE5B,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACrC,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAChD,MAAM,UAAU,GAAG,gBAAgB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAClD,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QACxB,IAAA,oBAAW,EAAC;YACV,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,EAAE;SACrE,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,YAAY,EAiCZ,GAAG,EACJ,MAAM,SAAS,CAAC;AASjB,eAAO,MAAM,QAAQ,UAAU,CAAC;AAiBhC,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAQrD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAcvD;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAgB3D;AAsGD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAkdhE;AAED,wBAAsB,UAAU,CAC9B,UAAU,EAAE,MAAM,EAClB,GAAG,CAAC,EAAE,GAAG,GAAG,GAAG,EAAE,GAChB,OAAO,CAAC,YAAY,CAAC,CAQvB;AA8JD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,GAAG,SAAS,CAgC7E"}
|
package/dist/config.js
CHANGED
|
@@ -43,6 +43,7 @@ exports.parseVia = parseVia;
|
|
|
43
43
|
const fs = __importStar(require("fs"));
|
|
44
44
|
const path = __importStar(require("path"));
|
|
45
45
|
const yaml = __importStar(require("js-yaml"));
|
|
46
|
+
const yaml_1 = require("yaml");
|
|
46
47
|
const types_1 = require("./types");
|
|
47
48
|
const variables_1 = require("./variables");
|
|
48
49
|
const paths_1 = require("./paths");
|
|
@@ -50,6 +51,7 @@ const http_1 = require("./sources/http");
|
|
|
50
51
|
const github_1 = require("./sources/github");
|
|
51
52
|
const gitlab_1 = require("./sources/gitlab");
|
|
52
53
|
const git_1 = require("./sources/git");
|
|
54
|
+
const local_1 = require("./sources/local");
|
|
53
55
|
exports.SELF_KEY = '$self';
|
|
54
56
|
const CONFIG_CANDIDATES = [
|
|
55
57
|
'.avanti.yml',
|
|
@@ -57,6 +59,14 @@ const CONFIG_CANDIDATES = [
|
|
|
57
59
|
'avanti.yml',
|
|
58
60
|
'avanti.yaml',
|
|
59
61
|
];
|
|
62
|
+
function isLocalFileSrc(src) {
|
|
63
|
+
if (typeof src === 'string') {
|
|
64
|
+
return !(0, local_1.isNonLocalSrcString)(src);
|
|
65
|
+
}
|
|
66
|
+
if (!('path' in src))
|
|
67
|
+
return false;
|
|
68
|
+
return !(0, local_1.isNonLocalSrcString)(src.path);
|
|
69
|
+
}
|
|
60
70
|
function isRemoteConfigSpec(s) {
|
|
61
71
|
return (s.startsWith('http://') ||
|
|
62
72
|
s.startsWith('https://') ||
|
|
@@ -167,6 +177,46 @@ async function fetchConfigContent(spec, via) {
|
|
|
167
177
|
return fs.readFileSync(spec, 'utf8');
|
|
168
178
|
}
|
|
169
179
|
function parseConfigContent(content) {
|
|
180
|
+
// Normalize YAML 0o-prefixed octal literals in files[*].mode before js-yaml
|
|
181
|
+
// parses the content. js-yaml discards the 0o prefix, turning e.g. 0o644
|
|
182
|
+
// into integer 420. We use the yaml package's AST to locate only actual
|
|
183
|
+
// files[*].mode scalar values (never block-scalar content or other fields),
|
|
184
|
+
// then do a targeted string replacement at the exact character range.
|
|
185
|
+
try {
|
|
186
|
+
const doc = (0, yaml_1.parseDocument)(content);
|
|
187
|
+
const filesNode = doc.get('files', true);
|
|
188
|
+
if ((0, yaml_1.isMap)(filesNode)) {
|
|
189
|
+
const replacements = [];
|
|
190
|
+
for (const pair of filesNode.items) {
|
|
191
|
+
const entryNode = pair.value;
|
|
192
|
+
if (!(0, yaml_1.isMap)(entryNode))
|
|
193
|
+
continue;
|
|
194
|
+
const modeNode = entryNode.get('mode', true);
|
|
195
|
+
if ((0, yaml_1.isScalar)(modeNode) &&
|
|
196
|
+
typeof modeNode.value === 'number' &&
|
|
197
|
+
Number.isInteger(modeNode.value) &&
|
|
198
|
+
modeNode.range) {
|
|
199
|
+
const raw = content.slice(modeNode.range[0], modeNode.range[1]);
|
|
200
|
+
if (raw.startsWith('0o')) {
|
|
201
|
+
const digits = raw.slice(2);
|
|
202
|
+
replacements.push({
|
|
203
|
+
start: modeNode.range[0],
|
|
204
|
+
end: modeNode.range[1],
|
|
205
|
+
text: `"${digits.padStart(4, '0')}"`,
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
// Apply in reverse order so earlier offsets stay valid.
|
|
211
|
+
for (const r of replacements.reverse()) {
|
|
212
|
+
content = content.slice(0, r.start) + r.text + content.slice(r.end);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
// If AST parse fails, fall through to js-yaml which will produce its own
|
|
218
|
+
// error with better context.
|
|
219
|
+
}
|
|
170
220
|
let raw;
|
|
171
221
|
try {
|
|
172
222
|
raw = yaml.load(content);
|
|
@@ -205,18 +255,90 @@ function parseConfigContent(content) {
|
|
|
205
255
|
fileEntry['if'] = fileConds['if'];
|
|
206
256
|
if (fileConds.ifAny !== undefined)
|
|
207
257
|
fileEntry.ifAny = fileConds.ifAny;
|
|
208
|
-
if (typeof e['mode'] === '
|
|
258
|
+
if (typeof e['mode'] === 'number') {
|
|
259
|
+
// 0o-prefixed YAML literals are normalized to quoted strings before parsing
|
|
260
|
+
// (see preprocessing above), so any remaining number is a bare decimal like
|
|
261
|
+
// mode: 755, which is ambiguous and rejected.
|
|
262
|
+
throw new Error(`files["${target}"].mode: ${e['mode']} is a bare decimal — use a quoted string like "0755" or YAML 0o notation (e.g. 0o755)`);
|
|
263
|
+
}
|
|
264
|
+
else if (typeof e['mode'] === 'string') {
|
|
265
|
+
if (!/^[0-7]{1,4}$/.test(e['mode'])) {
|
|
266
|
+
throw new Error(`files["${target}"].mode: "${e['mode']}" is not a valid octal string (expected 1–4 octal digits, e.g. "0755")`);
|
|
267
|
+
}
|
|
209
268
|
fileEntry.mode = e['mode'];
|
|
269
|
+
}
|
|
210
270
|
if (typeof e['backup'] === 'string')
|
|
211
271
|
fileEntry.backup = e['backup'];
|
|
212
|
-
if (
|
|
213
|
-
|
|
272
|
+
if (e['post'] !== undefined) {
|
|
273
|
+
throw new Error(`files["${target}"].post: removed — use on.write instead`);
|
|
274
|
+
}
|
|
275
|
+
if (e['on'] !== undefined) {
|
|
276
|
+
if (typeof e['on'] !== 'object' ||
|
|
277
|
+
e['on'] === null ||
|
|
278
|
+
Array.isArray(e['on']) ||
|
|
279
|
+
(Object.getPrototypeOf(e['on']) !== Object.prototype &&
|
|
280
|
+
Object.getPrototypeOf(e['on']) !== null)) {
|
|
281
|
+
throw new Error(`files["${target}"].on: must be a mapping`);
|
|
282
|
+
}
|
|
283
|
+
const validKeys = new Set([
|
|
284
|
+
'write',
|
|
285
|
+
'beforeWrite',
|
|
286
|
+
'beforeCreate',
|
|
287
|
+
'beforeUpdate',
|
|
288
|
+
'create',
|
|
289
|
+
'update',
|
|
290
|
+
]);
|
|
291
|
+
const onObj = e['on'];
|
|
292
|
+
const onHooks = Object.create(null);
|
|
293
|
+
for (const key of Object.keys(onObj)) {
|
|
294
|
+
if (!validKeys.has(key)) {
|
|
295
|
+
throw new Error(`files["${target}"].on: unknown key "${key}"`);
|
|
296
|
+
}
|
|
297
|
+
if (typeof onObj[key] !== 'string') {
|
|
298
|
+
throw new Error(`files["${target}"].on.${key}: must be a string`);
|
|
299
|
+
}
|
|
300
|
+
onHooks[key] = onObj[key];
|
|
301
|
+
}
|
|
302
|
+
fileEntry.on = onHooks;
|
|
303
|
+
}
|
|
304
|
+
if (typeof e['writeInPlace'] === 'boolean')
|
|
305
|
+
fileEntry.writeInPlace = e['writeInPlace'];
|
|
306
|
+
if (typeof e['followSymlink'] === 'boolean')
|
|
307
|
+
fileEntry.followSymlink = e['followSymlink'];
|
|
308
|
+
if (e['symlink'] !== undefined) {
|
|
309
|
+
if (e['symlink'] !== true &&
|
|
310
|
+
e['symlink'] !== 'absolute' &&
|
|
311
|
+
e['symlink'] !== 'relative') {
|
|
312
|
+
throw new Error(`files["${target}"].symlink: must be true, "absolute", or "relative"`);
|
|
313
|
+
}
|
|
314
|
+
fileEntry.symlink = e['symlink'];
|
|
315
|
+
}
|
|
316
|
+
if (e['sudo'] !== undefined) {
|
|
317
|
+
if (e['sudo'] === true) {
|
|
318
|
+
fileEntry.sudo = true;
|
|
319
|
+
}
|
|
320
|
+
else if (typeof e['sudo'] === 'string' && e['sudo'].trim()) {
|
|
321
|
+
if (e['sudo'].trim().startsWith('-')) {
|
|
322
|
+
throw new Error(`files["${target}"].sudo: username must not start with '-'`);
|
|
323
|
+
}
|
|
324
|
+
fileEntry.sudo = e['sudo'].trim();
|
|
325
|
+
}
|
|
326
|
+
else if (e['sudo'] !== false) {
|
|
327
|
+
throw new Error(`files["${target}"].sudo: must be true or a non-empty username string`);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
214
330
|
if (e['strategy'] !== undefined) {
|
|
215
331
|
if (e['strategy'] !== 'replace' && e['strategy'] !== 'insert') {
|
|
216
332
|
throw new Error(`files["${target}"].strategy: must be "replace" or "insert"`);
|
|
217
333
|
}
|
|
218
334
|
fileEntry.strategy = e['strategy'];
|
|
219
335
|
}
|
|
336
|
+
if (fileEntry.strategy === 'insert' && fileEntry.sudo) {
|
|
337
|
+
throw new Error(`files["${target}"]: strategy "insert" cannot be combined with sudo — ` +
|
|
338
|
+
`insert mode reads the existing file without privilege escalation, ` +
|
|
339
|
+
`which silently treats an unreadable privileged file as absent. ` +
|
|
340
|
+
`Use a non-insert strategy, or manage the file without sudo.`);
|
|
341
|
+
}
|
|
220
342
|
if (e['replace'] !== undefined) {
|
|
221
343
|
if (!Array.isArray(e['replace'])) {
|
|
222
344
|
throw new Error(`files["${target}"]: "replace" must be an array`);
|
|
@@ -250,6 +372,15 @@ function parseConfigContent(content) {
|
|
|
250
372
|
fileEntry.toml = parseTomlMergeOptions(rawToml, `files["${target}"]`);
|
|
251
373
|
}
|
|
252
374
|
}
|
|
375
|
+
if (e['ini'] !== undefined) {
|
|
376
|
+
const rawIni = e['ini'];
|
|
377
|
+
if (rawIni === true || rawIni === false) {
|
|
378
|
+
fileEntry.ini = rawIni;
|
|
379
|
+
}
|
|
380
|
+
else {
|
|
381
|
+
fileEntry.ini = parseIniMergeOptions(rawIni, `files["${target}"]`);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
253
384
|
if (e['template'] !== undefined) {
|
|
254
385
|
const rawTemplate = e['template'];
|
|
255
386
|
if (rawTemplate === true) {
|
|
@@ -263,6 +394,106 @@ function parseConfigContent(content) {
|
|
|
263
394
|
fileEntry.template = rawTemplate;
|
|
264
395
|
}
|
|
265
396
|
}
|
|
397
|
+
if (e['extract'] !== undefined) {
|
|
398
|
+
if (fileEntry.symlink) {
|
|
399
|
+
throw new Error(`files["${target}"].symlink: cannot be combined with extract:`);
|
|
400
|
+
}
|
|
401
|
+
if (Array.isArray(src)) {
|
|
402
|
+
throw new Error(`files["${target}"].extract: cannot be used with a list of sources`);
|
|
403
|
+
}
|
|
404
|
+
if (!target.endsWith('/') && !target.endsWith(path.sep)) {
|
|
405
|
+
throw new Error(`files["${target}"].extract: target must be a directory (end with "/") — archive extraction writes multiple files`);
|
|
406
|
+
}
|
|
407
|
+
const rawExtract = e['extract'];
|
|
408
|
+
if (rawExtract === true) {
|
|
409
|
+
fileEntry.extract = true;
|
|
410
|
+
}
|
|
411
|
+
else if (Array.isArray(rawExtract)) {
|
|
412
|
+
if (rawExtract.length === 0) {
|
|
413
|
+
throw new Error(`files["${target}"].extract: must not be an empty array`);
|
|
414
|
+
}
|
|
415
|
+
fileEntry.extract = rawExtract.map((pat, i) => {
|
|
416
|
+
if (typeof pat !== 'string' || !pat) {
|
|
417
|
+
throw new Error(`files["${target}"].extract[${i}]: must be a non-empty string`);
|
|
418
|
+
}
|
|
419
|
+
if (pat.length > 2 && pat.startsWith('/') && pat.endsWith('/')) {
|
|
420
|
+
try {
|
|
421
|
+
new RegExp(pat.slice(1, -1));
|
|
422
|
+
}
|
|
423
|
+
catch (err) {
|
|
424
|
+
throw new Error(`files["${target}"].extract[${i}]: invalid regex`, { cause: err });
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
return pat;
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
else {
|
|
431
|
+
throw new Error(`files["${target}"].extract: must be true or a non-empty array of patterns`);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
if (fileEntry.symlink) {
|
|
435
|
+
if (target === exports.SELF_KEY) {
|
|
436
|
+
throw new Error(`files["${exports.SELF_KEY}"].symlink: $self cannot be a symlink entry`);
|
|
437
|
+
}
|
|
438
|
+
if (target.endsWith('/') || target.endsWith(path.sep)) {
|
|
439
|
+
throw new Error(`files["${target}"].symlink: target must be a single file path, not a directory pattern (remove the trailing slash)`);
|
|
440
|
+
}
|
|
441
|
+
if (Array.isArray(fileEntry.src)) {
|
|
442
|
+
throw new Error(`files["${target}"].symlink: cannot be combined with a list of sources`);
|
|
443
|
+
}
|
|
444
|
+
if (!isLocalFileSrc(fileEntry.src)) {
|
|
445
|
+
throw new Error(`files["${target}"].symlink: src must be a local path — ` +
|
|
446
|
+
`http, exec, github, gitlab, and other remote sources are not supported`);
|
|
447
|
+
}
|
|
448
|
+
if (typeof fileEntry.src !== 'string' && 'path' in fileEntry.src) {
|
|
449
|
+
const localSrc = fileEntry.src;
|
|
450
|
+
if (localSrc.sha) {
|
|
451
|
+
throw new Error(`files["${target}"].symlink: cannot be combined with src.sha`);
|
|
452
|
+
}
|
|
453
|
+
if (localSrc.filter) {
|
|
454
|
+
throw new Error(`files["${target}"].symlink: cannot be combined with src.filter`);
|
|
455
|
+
}
|
|
456
|
+
if (localSrc.if) {
|
|
457
|
+
throw new Error(`files["${target}"].symlink: cannot be combined with src.if`);
|
|
458
|
+
}
|
|
459
|
+
if (localSrc.ifAny) {
|
|
460
|
+
throw new Error(`files["${target}"].symlink: cannot be combined with src.ifAny`);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
if (fileEntry.replace) {
|
|
464
|
+
throw new Error(`files["${target}"].symlink: cannot be combined with replace:`);
|
|
465
|
+
}
|
|
466
|
+
if (fileEntry.template) {
|
|
467
|
+
throw new Error(`files["${target}"].symlink: cannot be combined with template:`);
|
|
468
|
+
}
|
|
469
|
+
if (fileEntry.json) {
|
|
470
|
+
throw new Error(`files["${target}"].symlink: cannot be combined with json:`);
|
|
471
|
+
}
|
|
472
|
+
if (fileEntry.yaml) {
|
|
473
|
+
throw new Error(`files["${target}"].symlink: cannot be combined with yaml:`);
|
|
474
|
+
}
|
|
475
|
+
if (fileEntry.toml) {
|
|
476
|
+
throw new Error(`files["${target}"].symlink: cannot be combined with toml:`);
|
|
477
|
+
}
|
|
478
|
+
if (fileEntry.ini) {
|
|
479
|
+
throw new Error(`files["${target}"].symlink: cannot be combined with ini:`);
|
|
480
|
+
}
|
|
481
|
+
if (fileEntry.on?.write) {
|
|
482
|
+
throw new Error(`files["${target}"].symlink: cannot be combined with on.write:`);
|
|
483
|
+
}
|
|
484
|
+
if (fileEntry.writeInPlace) {
|
|
485
|
+
throw new Error(`files["${target}"].symlink: cannot be combined with writeInPlace:`);
|
|
486
|
+
}
|
|
487
|
+
if (fileEntry.strategy) {
|
|
488
|
+
throw new Error(`files["${target}"].symlink: cannot be combined with strategy:`);
|
|
489
|
+
}
|
|
490
|
+
if (fileEntry.followSymlink) {
|
|
491
|
+
throw new Error(`files["${target}"].symlink: cannot be combined with followSymlink:`);
|
|
492
|
+
}
|
|
493
|
+
if (fileEntry.mode) {
|
|
494
|
+
throw new Error(`files["${target}"].symlink: cannot be combined with mode — symlinks do not have independent permission bits on POSIX`);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
266
497
|
let expandedTargets;
|
|
267
498
|
try {
|
|
268
499
|
expandedTargets = (0, paths_1.expandBraces)(target);
|
|
@@ -283,6 +514,11 @@ function parseConfigContent(content) {
|
|
|
283
514
|
const suffix = parts.length > 0 ? ` (${parts.join('; ')})` : '';
|
|
284
515
|
throw new Error(`files["${expandedTarget}"]: duplicate target${suffix}`);
|
|
285
516
|
}
|
|
517
|
+
if (fileEntry.symlink &&
|
|
518
|
+
expandedTarget !== target &&
|
|
519
|
+
(expandedTarget.endsWith('/') || expandedTarget.endsWith(path.sep))) {
|
|
520
|
+
throw new Error(`files["${expandedTarget}"] (expanded from "${target}").symlink: target must be a single file path, not a directory pattern (remove the trailing slash)`);
|
|
521
|
+
}
|
|
286
522
|
files[expandedTarget] = { ...fileEntry, target: expandedTarget };
|
|
287
523
|
if (expandedTarget !== target) {
|
|
288
524
|
fileOrigins[expandedTarget] = target;
|
|
@@ -309,6 +545,30 @@ async function loadConfig(configPath, via) {
|
|
|
309
545
|
throw new Error(`Failed to parse config file: ${msg}`, { cause: err });
|
|
310
546
|
}
|
|
311
547
|
}
|
|
548
|
+
// Recursively assert that a value is a valid JsonValue — no class instances
|
|
549
|
+
// (e.g. Date from js-yaml timestamp parsing) anywhere in the tree.
|
|
550
|
+
function assertPlainJsonValue(val, path) {
|
|
551
|
+
if (val === null || typeof val !== 'object')
|
|
552
|
+
return;
|
|
553
|
+
if (Array.isArray(val)) {
|
|
554
|
+
for (let i = 0; i < val.length; i++) {
|
|
555
|
+
assertPlainJsonValue(val[i], `${path}[${i}]`);
|
|
556
|
+
}
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
const proto = Object.getPrototypeOf(val);
|
|
560
|
+
if (proto !== Object.prototype && proto !== null) {
|
|
561
|
+
const name = val.constructor?.name ??
|
|
562
|
+
'unknown';
|
|
563
|
+
throw new Error(`${path}: expected a plain object but got ${name} — quote YAML timestamps and other special values`);
|
|
564
|
+
}
|
|
565
|
+
for (const [k, v] of Object.entries(val)) {
|
|
566
|
+
const keyPart = /[.[\]"']/.test(k)
|
|
567
|
+
? `["${k.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"]`
|
|
568
|
+
: `.${k}`;
|
|
569
|
+
assertPlainJsonValue(v, `${path}${keyPart}`);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
312
572
|
function parseVariables(raw) {
|
|
313
573
|
if (raw === undefined || raw === null)
|
|
314
574
|
return Object.create(null);
|
|
@@ -324,11 +584,23 @@ function parseVariables(raw) {
|
|
|
324
584
|
else if (val &&
|
|
325
585
|
typeof val === 'object' &&
|
|
326
586
|
!Array.isArray(val) &&
|
|
327
|
-
'src'
|
|
587
|
+
Object.hasOwn(val, 'src')) {
|
|
588
|
+
// `src` is a reserved key: any object with a top-level `src` key is
|
|
589
|
+
// treated as a source-backed VariableEntry, not a plain data object.
|
|
328
590
|
spec[key] = parseVariableEntry(val, key);
|
|
329
591
|
}
|
|
592
|
+
else if (Array.isArray(val) ||
|
|
593
|
+
typeof val === 'number' ||
|
|
594
|
+
typeof val === 'boolean') {
|
|
595
|
+
assertPlainJsonValue(val, `variables.${key}`);
|
|
596
|
+
spec[key] = val;
|
|
597
|
+
}
|
|
598
|
+
else if (typeof val === 'object' && val !== null) {
|
|
599
|
+
assertPlainJsonValue(val, `variables.${key}`);
|
|
600
|
+
spec[key] = val;
|
|
601
|
+
}
|
|
330
602
|
else {
|
|
331
|
-
throw new Error(`variables.${key}: value must be a string or
|
|
603
|
+
throw new Error(`variables.${key}: value must be a string, number, boolean, list, object, or source object with "src"`);
|
|
332
604
|
}
|
|
333
605
|
}
|
|
334
606
|
(0, variables_1.validateVariables)(spec);
|
|
@@ -371,6 +643,15 @@ function parseVariableEntry(obj, varName) {
|
|
|
371
643
|
entry.toml = parseTomlMergeOptions(rawToml, loc);
|
|
372
644
|
}
|
|
373
645
|
}
|
|
646
|
+
if (obj['ini'] !== undefined) {
|
|
647
|
+
const rawIni = obj['ini'];
|
|
648
|
+
if (rawIni === true || rawIni === false) {
|
|
649
|
+
entry.ini = rawIni;
|
|
650
|
+
}
|
|
651
|
+
else {
|
|
652
|
+
entry.ini = parseIniMergeOptions(rawIni, loc);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
374
655
|
if (obj['template'] !== undefined) {
|
|
375
656
|
const rawTemplate = obj['template'];
|
|
376
657
|
if (rawTemplate === true) {
|
|
@@ -430,7 +711,13 @@ function parseVia(value, loc) {
|
|
|
430
711
|
}
|
|
431
712
|
throw new Error(`${loc}.via: must be a string or array`);
|
|
432
713
|
}
|
|
433
|
-
const VALID_OS_PLATFORMS = [
|
|
714
|
+
const VALID_OS_PLATFORMS = [
|
|
715
|
+
'linux',
|
|
716
|
+
'mac',
|
|
717
|
+
'windows',
|
|
718
|
+
'darwin',
|
|
719
|
+
'win32',
|
|
720
|
+
];
|
|
434
721
|
function parseCondition(raw, loc) {
|
|
435
722
|
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
436
723
|
throw new Error(`${loc}: must be an object`);
|
|
@@ -511,6 +798,30 @@ function parseConditionField(obj, loc) {
|
|
|
511
798
|
}
|
|
512
799
|
return result;
|
|
513
800
|
}
|
|
801
|
+
function parseFilter(obj, loc) {
|
|
802
|
+
if (obj['filter'] === undefined)
|
|
803
|
+
return undefined;
|
|
804
|
+
if (!Array.isArray(obj['filter'])) {
|
|
805
|
+
throw new Error(`${loc}.filter: must be an array`);
|
|
806
|
+
}
|
|
807
|
+
if (obj['filter'].length === 0) {
|
|
808
|
+
throw new Error(`${loc}.filter: must not be an empty array`);
|
|
809
|
+
}
|
|
810
|
+
return obj['filter'].map((entry, i) => {
|
|
811
|
+
if (typeof entry !== 'string' || !entry) {
|
|
812
|
+
throw new Error(`${loc}.filter[${i}]: must be a non-empty string`);
|
|
813
|
+
}
|
|
814
|
+
if (entry.length > 2 && entry.startsWith('/') && entry.endsWith('/')) {
|
|
815
|
+
try {
|
|
816
|
+
new RegExp(entry.slice(1, -1));
|
|
817
|
+
}
|
|
818
|
+
catch (err) {
|
|
819
|
+
throw new Error(`${loc}.filter[${i}]: invalid regex: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
return entry;
|
|
823
|
+
});
|
|
824
|
+
}
|
|
514
825
|
function parseSingleSrc(raw, loc) {
|
|
515
826
|
// Plain string → http/https URL or local path
|
|
516
827
|
if (typeof raw === 'string') {
|
|
@@ -531,6 +842,9 @@ function parseSingleSrc(raw, loc) {
|
|
|
531
842
|
}
|
|
532
843
|
result.optional = obj['optional'];
|
|
533
844
|
}
|
|
845
|
+
const pathFilter = parseFilter(obj, loc);
|
|
846
|
+
if (pathFilter !== undefined)
|
|
847
|
+
result.filter = pathFilter;
|
|
534
848
|
const pathSha = parseSha(obj['sha'], loc);
|
|
535
849
|
if (pathSha !== undefined)
|
|
536
850
|
result.sha = pathSha;
|
|
@@ -622,14 +936,44 @@ function parseSingleSrc(raw, loc) {
|
|
|
622
936
|
if (typeof g['project'] !== 'string' || !g['project']) {
|
|
623
937
|
throw new Error(`${loc}.gitlab.project: required string`);
|
|
624
938
|
}
|
|
625
|
-
if (
|
|
626
|
-
|
|
939
|
+
if (g['file'] !== undefined &&
|
|
940
|
+
(typeof g['file'] !== 'string' || !g['file'])) {
|
|
941
|
+
throw new Error(`${loc}.gitlab.file: must be a non-empty string`);
|
|
942
|
+
}
|
|
943
|
+
if (g['release'] !== undefined &&
|
|
944
|
+
(typeof g['release'] !== 'string' || !g['release'])) {
|
|
945
|
+
throw new Error(`${loc}.gitlab.release: must be a non-empty string`);
|
|
946
|
+
}
|
|
947
|
+
const hasFile = typeof g['file'] === 'string' && !!g['file'];
|
|
948
|
+
const hasRelease = typeof g['release'] === 'string' && !!g['release'];
|
|
949
|
+
if (hasFile && hasRelease) {
|
|
950
|
+
throw new Error(`${loc}.gitlab: "file" and "release" are mutually exclusive`);
|
|
951
|
+
}
|
|
952
|
+
if (!hasFile && !hasRelease) {
|
|
953
|
+
throw new Error(`${loc}.gitlab: one of "file" or "release" is required`);
|
|
954
|
+
}
|
|
955
|
+
if (hasRelease && g['ref'] !== undefined) {
|
|
956
|
+
throw new Error(`${loc}.gitlab: "ref" is not valid when using "release"`);
|
|
627
957
|
}
|
|
628
958
|
if (g['host'] !== undefined &&
|
|
629
959
|
(typeof g['host'] !== 'string' || !g['host'].trim())) {
|
|
630
960
|
throw new Error(`${loc}.gitlab.host: must be a non-empty string`);
|
|
631
961
|
}
|
|
632
962
|
const gitlabConds = parseConditionField(obj, loc);
|
|
963
|
+
const gitlabFilter = parseFilter(obj, loc);
|
|
964
|
+
if (hasRelease) {
|
|
965
|
+
return {
|
|
966
|
+
gitlab: {
|
|
967
|
+
project: g['project'],
|
|
968
|
+
release: g['release'],
|
|
969
|
+
sha: parseSha(g['sha'], `${loc}.gitlab`),
|
|
970
|
+
host: typeof g['host'] === 'string' ? g['host'] : undefined,
|
|
971
|
+
via: parseVia(g['via'], `${loc}.gitlab`),
|
|
972
|
+
},
|
|
973
|
+
...(gitlabFilter !== undefined ? { filter: gitlabFilter } : {}),
|
|
974
|
+
...gitlabConds,
|
|
975
|
+
};
|
|
976
|
+
}
|
|
633
977
|
return {
|
|
634
978
|
gitlab: {
|
|
635
979
|
project: g['project'],
|
|
@@ -639,6 +983,7 @@ function parseSingleSrc(raw, loc) {
|
|
|
639
983
|
host: typeof g['host'] === 'string' ? g['host'] : undefined,
|
|
640
984
|
via: parseVia(g['via'], `${loc}.gitlab`),
|
|
641
985
|
},
|
|
986
|
+
...(gitlabFilter !== undefined ? { filter: gitlabFilter } : {}),
|
|
642
987
|
...gitlabConds,
|
|
643
988
|
};
|
|
644
989
|
}
|
|
@@ -658,14 +1003,44 @@ function parseSingleSrc(raw, loc) {
|
|
|
658
1003
|
if (typeof g['repo'] !== 'string' || !g['repo']) {
|
|
659
1004
|
throw new Error(`${loc}.github.repo: required string`);
|
|
660
1005
|
}
|
|
661
|
-
if (
|
|
662
|
-
|
|
1006
|
+
if (g['file'] !== undefined &&
|
|
1007
|
+
(typeof g['file'] !== 'string' || !g['file'])) {
|
|
1008
|
+
throw new Error(`${loc}.github.file: must be a non-empty string`);
|
|
1009
|
+
}
|
|
1010
|
+
if (g['release'] !== undefined &&
|
|
1011
|
+
(typeof g['release'] !== 'string' || !g['release'])) {
|
|
1012
|
+
throw new Error(`${loc}.github.release: must be a non-empty string`);
|
|
1013
|
+
}
|
|
1014
|
+
const hasFile = typeof g['file'] === 'string' && !!g['file'];
|
|
1015
|
+
const hasRelease = typeof g['release'] === 'string' && !!g['release'];
|
|
1016
|
+
if (hasFile && hasRelease) {
|
|
1017
|
+
throw new Error(`${loc}.github: "file" and "release" are mutually exclusive`);
|
|
1018
|
+
}
|
|
1019
|
+
if (!hasFile && !hasRelease) {
|
|
1020
|
+
throw new Error(`${loc}.github: one of "file" or "release" is required`);
|
|
1021
|
+
}
|
|
1022
|
+
if (hasRelease && g['ref'] !== undefined) {
|
|
1023
|
+
throw new Error(`${loc}.github: "ref" is not valid when using "release"`);
|
|
663
1024
|
}
|
|
664
1025
|
if (g['host'] !== undefined &&
|
|
665
1026
|
(typeof g['host'] !== 'string' || !g['host'].trim())) {
|
|
666
1027
|
throw new Error(`${loc}.github.host: must be a non-empty string`);
|
|
667
1028
|
}
|
|
668
1029
|
const githubConds = parseConditionField(obj, loc);
|
|
1030
|
+
const githubFilter = parseFilter(obj, loc);
|
|
1031
|
+
if (hasRelease) {
|
|
1032
|
+
return {
|
|
1033
|
+
github: {
|
|
1034
|
+
repo: g['repo'],
|
|
1035
|
+
release: g['release'],
|
|
1036
|
+
sha: parseSha(g['sha'], `${loc}.github`),
|
|
1037
|
+
host: typeof g['host'] === 'string' ? g['host'] : undefined,
|
|
1038
|
+
via: parseVia(g['via'], `${loc}.github`),
|
|
1039
|
+
},
|
|
1040
|
+
...(githubFilter !== undefined ? { filter: githubFilter } : {}),
|
|
1041
|
+
...githubConds,
|
|
1042
|
+
};
|
|
1043
|
+
}
|
|
669
1044
|
return {
|
|
670
1045
|
github: {
|
|
671
1046
|
repo: g['repo'],
|
|
@@ -675,6 +1050,7 @@ function parseSingleSrc(raw, loc) {
|
|
|
675
1050
|
host: typeof g['host'] === 'string' ? g['host'] : undefined,
|
|
676
1051
|
via: parseVia(g['via'], `${loc}.github`),
|
|
677
1052
|
},
|
|
1053
|
+
...(githubFilter !== undefined ? { filter: githubFilter } : {}),
|
|
678
1054
|
...githubConds,
|
|
679
1055
|
};
|
|
680
1056
|
}
|
|
@@ -698,6 +1074,7 @@ function parseSingleSrc(raw, loc) {
|
|
|
698
1074
|
throw new Error(`${loc}.bitbucket.host: must be a non-empty string`);
|
|
699
1075
|
}
|
|
700
1076
|
const bitbucketConds = parseConditionField(obj, loc);
|
|
1077
|
+
const bitbucketFilter = parseFilter(obj, loc);
|
|
701
1078
|
return {
|
|
702
1079
|
bitbucket: {
|
|
703
1080
|
workspace: b['workspace'],
|
|
@@ -707,6 +1084,7 @@ function parseSingleSrc(raw, loc) {
|
|
|
707
1084
|
sha: parseSha(b['sha'], `${loc}.bitbucket`),
|
|
708
1085
|
host: typeof b['host'] === 'string' ? b['host'] : undefined,
|
|
709
1086
|
},
|
|
1087
|
+
...(bitbucketFilter !== undefined ? { filter: bitbucketFilter } : {}),
|
|
710
1088
|
...bitbucketConds,
|
|
711
1089
|
};
|
|
712
1090
|
}
|
|
@@ -723,6 +1101,7 @@ function parseSingleSrc(raw, loc) {
|
|
|
723
1101
|
throw new Error(`${loc}.git.file: required string`);
|
|
724
1102
|
}
|
|
725
1103
|
const gitConds = parseConditionField(obj, loc);
|
|
1104
|
+
const gitFilter = parseFilter(obj, loc);
|
|
726
1105
|
return {
|
|
727
1106
|
git: {
|
|
728
1107
|
repo: gt['repo'],
|
|
@@ -730,6 +1109,7 @@ function parseSingleSrc(raw, loc) {
|
|
|
730
1109
|
ref: typeof gt['ref'] === 'string' ? gt['ref'] : undefined,
|
|
731
1110
|
sha: parseSha(gt['sha'], `${loc}.git`),
|
|
732
1111
|
},
|
|
1112
|
+
...(gitFilter !== undefined ? { filter: gitFilter } : {}),
|
|
733
1113
|
...gitConds,
|
|
734
1114
|
};
|
|
735
1115
|
}
|
|
@@ -738,6 +1118,9 @@ function parseSingleSrc(raw, loc) {
|
|
|
738
1118
|
throw new Error(`${loc}.aws_s3: must be a non-empty string (s3:// URI)`);
|
|
739
1119
|
}
|
|
740
1120
|
const result = { aws_s3: obj['aws_s3'] };
|
|
1121
|
+
const s3Filter = parseFilter(obj, loc);
|
|
1122
|
+
if (s3Filter !== undefined)
|
|
1123
|
+
result.filter = s3Filter;
|
|
741
1124
|
const s3Sha = parseSha(obj['sha'], loc);
|
|
742
1125
|
if (s3Sha !== undefined)
|
|
743
1126
|
result.sha = s3Sha;
|
|
@@ -885,6 +1268,9 @@ function parseYamlMergeOptions(raw, loc) {
|
|
|
885
1268
|
function parseTomlMergeOptions(raw, loc) {
|
|
886
1269
|
return parseMergeOptions(raw, loc, 'toml', ['abort', 'first_wins', 'last_wins'], ['replace', 'concat', 'dedupe'], ['replace', 'merge']);
|
|
887
1270
|
}
|
|
1271
|
+
function parseIniMergeOptions(raw, loc) {
|
|
1272
|
+
return parseMergeOptions(raw, loc, 'ini', ['abort', 'first_wins', 'last_wins'], ['replace', 'concat', 'dedupe'], ['replace', 'merge']);
|
|
1273
|
+
}
|
|
888
1274
|
function parseReplaceRule(r, target, j) {
|
|
889
1275
|
if (!r || typeof r !== 'object' || Array.isArray(r)) {
|
|
890
1276
|
throw new Error(`files["${target}"].replace[${j}]: must be an object`);
|