@intentius/chant 0.0.24 → 0.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentius/chant",
3
- "version": "0.0.24",
3
+ "version": "0.1.0",
4
4
  "description": "Declarative infrastructure-as-code toolkit — TypeScript on Bun",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://intentius.io/chant",
@@ -65,6 +65,19 @@ export async function typecheckDTS(content: string): Promise<TypeCheckResult> {
65
65
  MINIMAL_LIB,
66
66
  );
67
67
 
68
+ // Write stubs for @intentius/chant sub-path imports used in generated .d.ts files.
69
+ // tsc runs in a temp dir with no node_modules, so these must be declared manually.
70
+ const chantDeclarableDir = join(dir, "node_modules", "@intentius", "chant", "declarable");
71
+ mkdirSync(chantDeclarableDir, { recursive: true });
72
+ writeFileSync(
73
+ join(chantDeclarableDir, "index.d.ts"),
74
+ `export interface Declarable<TProps = Record<string, unknown>> { props: TProps; }\n`,
75
+ );
76
+ writeFileSync(
77
+ join(chantDeclarableDir, "package.json"),
78
+ JSON.stringify({ name: "@intentius/chant/declarable", main: "index.d.ts", types: "index.d.ts" }),
79
+ );
80
+
68
81
  // Write a minimal tsconfig — noLib: true prevents tsc from looking for
69
82
  // standard lib files; our lib.d.ts is included via the include array.
70
83
  const tsconfig = {
@@ -35,7 +35,7 @@ export function collectEntities(
35
35
  entities.set(name, value);
36
36
  }
37
37
  } else if (Array.isArray(value)) {
38
- // Arrays of Declarables — each element gets an indexed name: exportName_0, exportName_1, ...
38
+ // Arrays of Declarables or CompositeInstances — each element gets an indexed name: exportName_0, ...
39
39
  for (let i = 0; i < value.length; i++) {
40
40
  const item = value[i];
41
41
  if (isDeclarable(item)) {
@@ -44,6 +44,19 @@ export function collectEntities(
44
44
  throw new DiscoveryError(file, `Duplicate entity name "${indexedName}"`, "resolution");
45
45
  }
46
46
  entities.set(indexedName, item);
47
+ } else if (isCompositeInstance(item)) {
48
+ const indexedName = `${name}_${i}`;
49
+ const expanded = expandComposite(indexedName, item);
50
+ for (const [expandedName, entity] of expanded) {
51
+ if (entities.has(expandedName)) {
52
+ throw new DiscoveryError(
53
+ file,
54
+ `Duplicate entity name "${expandedName}" from composite expansion of "${indexedName}"`,
55
+ "resolution",
56
+ );
57
+ }
58
+ entities.set(expandedName, entity);
59
+ }
47
60
  }
48
61
  }
49
62
  } else if (isCompositeInstance(value)) {
package/src/yaml.ts CHANGED
@@ -308,8 +308,13 @@ export function parseYAMLArray(
308
308
  const itemMatch = line.match(/^(\s*)- (.*)$/);
309
309
  if (itemMatch && indent === baseIndent) {
310
310
  const itemValue = itemMatch[2].trim();
311
- // Check if it's a key-value pair (object item in array)
312
- const kvMatch = itemValue.match(/^([^\s:][^:]*?):\s*(.*)$/);
311
+ // Check if it's a key-value pair (object item in array).
312
+ // Skip quoted scalars — a quoted string containing a colon (e.g. "80:80")
313
+ // must not be treated as a key-value pair.
314
+ const isQuotedScalar =
315
+ (itemValue.startsWith('"') && itemValue.endsWith('"')) ||
316
+ (itemValue.startsWith("'") && itemValue.endsWith("'"));
317
+ const kvMatch = !isQuotedScalar && itemValue.match(/^([^\s:][^:]*?):\s*(.*)$/);
313
318
  if (kvMatch) {
314
319
  const obj: Record<string, unknown> = {};
315
320
  obj[kvMatch[1].trim()] = parseArrayItemValue(kvMatch[2].trim(), lines, i, indent + 2);