@zokugun/artifact 0.2.4 → 0.3.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 CHANGED
@@ -32,11 +32,11 @@ With [node](http://nodejs.org) previously installed:
32
32
  Add the configuration packages:
33
33
 
34
34
  ```
35
- artifact add @daiyam/base @daiyam/lang-ts @daiyam/npm-ts
35
+ artifact add @daiyam/lang-js @daiyam/lang-ts @daiyam/npm-ts
36
36
  ```
37
37
 
38
38
  With the previous command, `artifact` will pull the following packages:
39
- - [@daiyam/artifact-base](https://github.com/daiyam/artifact-configs/tree/master/packages/base)
39
+ - [@daiyam/artifact-lang-js](https://github.com/daiyam/artifact-configs/tree/master/packages/lang-js)
40
40
  - [@daiyam/artifact-lang-ts](https://github.com/daiyam/artifact-configs/tree/master/packages/lang-ts)
41
41
  - [@daiyam/artifact-npm-ts](https://github.com/daiyam/artifact-configs/tree/master/packages/npm-ts)
42
42
 
@@ -47,10 +47,10 @@ Configuration Package
47
47
 
48
48
  The configuration/boilerplate files must be put inside the folder `configs`.
49
49
 
50
- For example, the package [@daiyam/artifact-base](https://github.com/daiyam/artifact-configs/tree/master/packages/base):
50
+ For example, the package [@daiyam/artifact-lang-js](https://github.com/daiyam/artifact-configs/tree/master/packages/lang-js):
51
51
 
52
52
  ```
53
- artifact-configs/base/
53
+ artifact-configs/lang-js/
54
54
  ├── configs/
55
55
  │ ├── .commitlintrc.yml
56
56
  │ ├── .editorconfig
@@ -19,7 +19,7 @@ const pacote_1 = __importDefault(require("pacote"));
19
19
  const tempy_1 = __importDefault(require("tempy"));
20
20
  const config_1 = require("../config");
21
21
  const steps_1 = require("../steps");
22
- const commonFlow = (0, steps_1.composeSteps)(steps_1.steps.readIncomingPackage, steps_1.steps.validateNotPresentPackage, steps_1.steps.readFiles, steps_1.steps.readEditorConfig, steps_1.steps.mergeTextFiles, steps_1.steps.insertFinalNewLine, steps_1.steps.applyFormatting, steps_1.steps.copyBinaryFiles, steps_1.steps.writeTextFiles);
22
+ const commonFlow = (0, steps_1.composeSteps)(steps_1.steps.readIncomingPackage, steps_1.steps.validateNotPresentPackage, steps_1.steps.readFiles, steps_1.steps.readEditorConfig, steps_1.steps.replaceTemplates, steps_1.steps.mergeTextFiles, steps_1.steps.insertFinalNewLine, steps_1.steps.applyFormatting, steps_1.steps.copyBinaryFiles, steps_1.steps.writeTextFiles);
23
23
  function expandSpec(spec) {
24
24
  if (spec.includes('/')) {
25
25
  const [scope, name] = spec.split('/');
@@ -27,19 +27,12 @@ exports.rc = void 0;
27
27
  const lodash_1 = require("lodash");
28
28
  const JSON = __importStar(require("../parsers/json"));
29
29
  const YAML = __importStar(require("../parsers/yaml"));
30
- function tryJson(value) {
31
- try {
32
- return JSON.parse(value);
33
- }
34
- catch (_a) {
35
- return undefined;
36
- }
37
- }
30
+ const try_json_1 = require("../utils/try-json");
38
31
  function rc(...routes) {
39
32
  return ({ current, incoming, filters, ignores }) => {
40
33
  var _a;
41
- const currentData = current && ((_a = tryJson(current)) !== null && _a !== void 0 ? _a : YAML.parse(current));
42
- const incomingData = incoming && tryJson(incoming);
34
+ const currentData = current && ((_a = (0, try_json_1.tryJson)(current)) !== null && _a !== void 0 ? _a : YAML.parse(current));
35
+ const incomingData = incoming && (0, try_json_1.tryJson)(incoming);
43
36
  if (incomingData) {
44
37
  return (0, lodash_1.flow)(...routes, JSON.stringify)({ current: currentData, incoming: incomingData, filters, ignores });
45
38
  }
@@ -20,21 +20,21 @@ function copyBinaryFiles({ binaryFiles, incomingPath, targetPath, onMissing, onU
20
20
  const cwd = path_1.default.join(incomingPath, 'configs');
21
21
  for (const file of binaryFiles) {
22
22
  try {
23
- yield fs_extra_1.default.access(path_1.default.join(targetPath, file));
24
- if (onUpdate(file)) {
23
+ yield fs_extra_1.default.access(path_1.default.join(targetPath, file.source));
24
+ if (onUpdate(file.source)) {
25
25
  continue;
26
26
  }
27
27
  }
28
28
  catch (_a) {
29
- if (onMissing(file)) {
29
+ if (onMissing(file.source)) {
30
30
  continue;
31
31
  }
32
32
  }
33
- const source = path_1.default.join(cwd, file);
34
- const target = path_1.default.join(targetPath, file);
33
+ const source = path_1.default.join(cwd, file.source);
34
+ const target = path_1.default.join(targetPath, file.target);
35
35
  yield fs_extra_1.default.copyFile(source, target);
36
36
  if (options.verbose) {
37
- console.log(`${file} has been written as a binary file`);
37
+ console.log(`${file.target} has been written as a binary file`);
38
38
  }
39
39
  }
40
40
  });
@@ -18,6 +18,7 @@ const read_editor_config_1 = require("./read-editor-config");
18
18
  const read_files_1 = require("./read-files");
19
19
  const read_incoming_config_1 = require("./read-incoming-config");
20
20
  const read_incoming_package_1 = require("./read-incoming-package");
21
+ const replace_templates_1 = require("./replace-templates");
21
22
  const validate_newer_package_1 = require("./validate-newer-package");
22
23
  const validate_not_present_package_1 = require("./validate-not-present-package");
23
24
  const validate_updatability_1 = require("./validate-updatability");
@@ -31,6 +32,7 @@ exports.steps = {
31
32
  readFiles: read_files_1.readFiles,
32
33
  readIncomingConfig: read_incoming_config_1.readIncomingConfig,
33
34
  readIncomingPackage: read_incoming_package_1.readIncomingPackage,
35
+ replaceTemplates: replace_templates_1.replaceTemplates,
34
36
  validateNewerPackage: validate_newer_package_1.validateNewerPackage,
35
37
  validateNotPresentPackage: validate_not_present_package_1.validateNotPresentPackage,
36
38
  validateUpdatability: validate_updatability_1.validateUpdatability,
@@ -20,10 +20,13 @@ function mergeTextFiles({ targetPath, textFiles, mergedTextFiles, onMissing, onU
20
20
  var _a;
21
21
  return __awaiter(this, void 0, void 0, function* () {
22
22
  for (const file of textFiles) {
23
+ if (options.verbose) {
24
+ console.log(`${file.name} is going to be merged`);
25
+ }
23
26
  const journey = (_a = routes(file.name)) !== null && _a !== void 0 ? _a : (0, journeys_1.getJourney)(file.name);
24
27
  if (!journey) {
25
28
  if (options.verbose) {
26
- console.log(`${file.name}, no merger found`);
29
+ console.log(`${file.name}, no merger has been found`);
27
30
  }
28
31
  try {
29
32
  yield fs_extra_1.default.access(path_1.default.join(targetPath, file.name));
@@ -39,6 +42,9 @@ function mergeTextFiles({ targetPath, textFiles, mergedTextFiles, onMissing, onU
39
42
  mergedTextFiles.push(file);
40
43
  continue;
41
44
  }
45
+ if (options.verbose) {
46
+ console.log(`${file.name}, a merger has been found`);
47
+ }
42
48
  const name = journey.alias ? path_1.default.join(path_1.default.dirname(file.name), journey.alias) : file.name;
43
49
  let currentData;
44
50
  try {
@@ -55,7 +55,10 @@ function readFiles({ incomingPath, textFiles, binaryFiles, options }) {
55
55
  }
56
56
  }
57
57
  else {
58
- binaryFiles.push(file);
58
+ binaryFiles.push({
59
+ source: file,
60
+ target: file,
61
+ });
59
62
  if (options.verbose) {
60
63
  console.log(`${file} is a binary file`);
61
64
  }
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.replaceTemplates = void 0;
13
+ const template_1 = require("../utils/template");
14
+ function replaceTemplates({ textFiles, binaryFiles, targetPath }) {
15
+ return __awaiter(this, void 0, void 0, function* () {
16
+ const engine = new template_1.TemplateEngine(targetPath);
17
+ for (const file of textFiles) {
18
+ file.data = engine.render(file.data);
19
+ file.name = engine.render(file.name);
20
+ }
21
+ for (const file of binaryFiles) {
22
+ file.target = engine.render(file.target);
23
+ }
24
+ });
25
+ }
26
+ exports.replaceTemplates = replaceTemplates;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -8,20 +8,22 @@ function splitCommand(command) {
8
8
  for (let i = 0; i < splitted.length; i++) {
9
9
  const command = splitted[i];
10
10
  const splittedSubcommand = command.split(/([\w-]+=\S+)\s/).filter(lodash_1.identity);
11
- const subcommandWithArgs = (0, lodash_1.last)(splittedSubcommand).split(' ');
12
- const subcommand = (0, lodash_1.head)(subcommandWithArgs).trim();
13
- const args = subcommandWithArgs.slice(1);
14
- const env = splittedSubcommand.slice(0, -1);
15
- const parsedSubcommand = {
16
- args: args.map(lodash_1.trim),
17
- env: env.map(lodash_1.trim),
18
- separator: splitted[i + 1],
19
- };
20
- if (result[subcommand]) {
21
- result[subcommand].push(parsedSubcommand);
22
- }
23
- else {
24
- result[subcommand] = [parsedSubcommand];
11
+ if (splittedSubcommand.length > 0) {
12
+ const subcommandWithArgs = (0, lodash_1.last)(splittedSubcommand).split(' ');
13
+ const subcommand = (0, lodash_1.head)(subcommandWithArgs).trim();
14
+ const args = subcommandWithArgs.slice(1);
15
+ const env = splittedSubcommand.slice(0, -1);
16
+ const parsedSubcommand = {
17
+ args: args.map(lodash_1.trim),
18
+ env: env.map(lodash_1.trim),
19
+ separator: splitted[i + 1],
20
+ };
21
+ if (result[subcommand]) {
22
+ result[subcommand].push(parsedSubcommand);
23
+ }
24
+ else {
25
+ result[subcommand] = [parsedSubcommand];
26
+ }
25
27
  }
26
28
  i++;
27
29
  }
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.TemplateEngine = void 0;
30
+ const path_1 = __importDefault(require("path"));
31
+ const dayjs_1 = __importDefault(require("dayjs"));
32
+ const utc_1 = __importDefault(require("dayjs/plugin/utc"));
33
+ const fs_extra_1 = __importDefault(require("fs-extra"));
34
+ const YAML = __importStar(require("../parsers/yaml"));
35
+ const try_json_1 = require("./try-json");
36
+ dayjs_1.default.extend(utc_1.default);
37
+ const PLACEHOLDER_REGEX = /^((?:[^/]+(?:[^/]+\/)*\/)?\.?[^.]+(?:\.(?:json|ya?ml))?)\.(.*)$/;
38
+ class TemplateError extends Error {
39
+ constructor(message) {
40
+ super(message);
41
+ this.name = 'TemplateError';
42
+ } // }}}
43
+ }
44
+ class TemplateEngine {
45
+ constructor(basePath) {
46
+ this.fileCache = new Map();
47
+ this.basePath = basePath;
48
+ } // }}}
49
+ render(template) {
50
+ const pattern = /#\[\[(.*?)]]/g;
51
+ return template.replace(pattern, (_, placeholder) => {
52
+ const [name, propertyPath] = this.splitPlaceholder(placeholder);
53
+ if (!name || !propertyPath) {
54
+ throw new TemplateError(`Invalid placeholder format: ${placeholder}. Expected format: #[[filename.property]]`);
55
+ }
56
+ if (name === 'date') {
57
+ return this.toDate(propertyPath);
58
+ }
59
+ const fileContent = this.readConfigFile(name);
60
+ const value = this.getValueByPath(fileContent, propertyPath);
61
+ if (value === null || value === undefined) {
62
+ throw new TemplateError(placeholder);
63
+ }
64
+ return String(value);
65
+ });
66
+ } // }}}
67
+ getValueByPath(values, propertyPath) {
68
+ const parts = propertyPath.split('.');
69
+ let current = values;
70
+ for (const part of parts) {
71
+ if (current === null || current === undefined || typeof current !== 'object') {
72
+ throw new TemplateError(`Property path not found: ${propertyPath}`);
73
+ }
74
+ current = current[part];
75
+ }
76
+ if (current === null || current === undefined) {
77
+ throw new TemplateError(`Property not found: ${propertyPath}`);
78
+ }
79
+ return current;
80
+ } // }}}
81
+ parseFile(filename) {
82
+ var _a;
83
+ let content;
84
+ try {
85
+ content = fs_extra_1.default.readFileSync(filename, 'utf8');
86
+ }
87
+ catch (_b) {
88
+ throw new TemplateError(`File not found: ${filename}`);
89
+ }
90
+ const ext = path_1.default.extname(filename).toLowerCase();
91
+ try {
92
+ if (ext === '.json') {
93
+ return JSON.parse(content);
94
+ }
95
+ else if (ext === '.yaml' || ext === '.yml') {
96
+ return YAML.parse(content);
97
+ }
98
+ else {
99
+ return (_a = (0, try_json_1.tryJson)(content)) !== null && _a !== void 0 ? _a : YAML.parse(content);
100
+ }
101
+ }
102
+ catch (parseError) {
103
+ throw new TemplateError(`Failed to parse ${filename}: ${parseError.message}`);
104
+ }
105
+ } // }}}
106
+ readConfigFile(filename) {
107
+ // Check cache first
108
+ if (this.fileCache.has(filename)) {
109
+ return this.fileCache.get(filename);
110
+ }
111
+ const filePath = path_1.default.resolve(this.basePath, filename);
112
+ const content = this.parseFile(filePath);
113
+ this.fileCache.set(filename, content);
114
+ return content;
115
+ } // }}}
116
+ splitPlaceholder(placeholder) {
117
+ const matches = PLACEHOLDER_REGEX.exec(placeholder);
118
+ if (!matches) {
119
+ throw new TemplateError(`Invalid placeholder format: ${placeholder}. Expected format: #[[filename.property]]`);
120
+ }
121
+ const [, filename, propertyPath] = matches;
122
+ return [filename, propertyPath];
123
+ } // }}}
124
+ toDate(format) {
125
+ try {
126
+ const now = (0, dayjs_1.default)().utc();
127
+ if (format === 'utc') {
128
+ return now.format('YYYY-MM-DD HH:mm:ss');
129
+ }
130
+ return now.format(format);
131
+ }
132
+ catch (_a) {
133
+ throw new TemplateError(`Invalid date format: ${format}`);
134
+ }
135
+ } // }}}
136
+ }
137
+ exports.TemplateEngine = TemplateEngine;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.tryJson = void 0;
4
+ function tryJson(value) {
5
+ try {
6
+ return JSON.parse(value);
7
+ }
8
+ catch (_a) {
9
+ return undefined;
10
+ }
11
+ }
12
+ exports.tryJson = tryJson;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@zokugun/artifact",
3
3
  "description": "Boilerplate your project & keep your configurations up to date",
4
- "version": "0.2.4",
4
+ "version": "0.3.0",
5
5
  "author": {
6
6
  "name": "Baptiste Augrain",
7
7
  "email": "daiyam@zokugun.org"
@@ -35,6 +35,7 @@
35
35
  "dependencies": {
36
36
  "ansi-colors": "^4.1.1",
37
37
  "commander": "^9.0.0",
38
+ "dayjs": "^1.11.13",
38
39
  "detect-indent": "^6.1.0",
39
40
  "editorconfig": "^0.15.3",
40
41
  "fs-extra": "^10.0.0",