11cb0ef41Sopenharmony_ciimport { mustCall } from '../common/index.mjs';
21cb0ef41Sopenharmony_ciimport { ok, deepStrictEqual, strictEqual } from 'assert';
31cb0ef41Sopenharmony_ci
41cb0ef41Sopenharmony_ciimport importer from '../fixtures/es-modules/pkgimports/importer.js';
51cb0ef41Sopenharmony_ciimport { requireFixture } from '../fixtures/pkgexports.mjs';
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ciconst { requireImport, importImport } = importer;
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci[requireImport, importImport].forEach((loadFixture) => {
101cb0ef41Sopenharmony_ci  const isRequire = loadFixture === requireImport;
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ci  const internalImports = new Map([
131cb0ef41Sopenharmony_ci    // Base case
141cb0ef41Sopenharmony_ci    ['#test', { default: 'test' }],
151cb0ef41Sopenharmony_ci    // import / require conditions
161cb0ef41Sopenharmony_ci    ['#branch', { default: isRequire ? 'requirebranch' : 'importbranch' }],
171cb0ef41Sopenharmony_ci    // Subpath imports
181cb0ef41Sopenharmony_ci    ['#subpath/x.js', { default: 'xsubpath' }],
191cb0ef41Sopenharmony_ci    // External imports
201cb0ef41Sopenharmony_ci    ['#external', { default: 'asdf' }],
211cb0ef41Sopenharmony_ci    // External subpath imports
221cb0ef41Sopenharmony_ci    ['#external/subpath/asdf.js', { default: 'asdf' }],
231cb0ef41Sopenharmony_ci    // Trailing pattern imports
241cb0ef41Sopenharmony_ci    ['#subpath/asdf.asdf', { default: 'test' }],
251cb0ef41Sopenharmony_ci    // Leading slash
261cb0ef41Sopenharmony_ci    ['#subpath//asdf.asdf', { default: 'test' }],
271cb0ef41Sopenharmony_ci    // Double slash
281cb0ef41Sopenharmony_ci    ['#subpath/as//df.asdf', { default: 'test' }],
291cb0ef41Sopenharmony_ci  ]);
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ci  for (const [validSpecifier, expected] of internalImports) {
321cb0ef41Sopenharmony_ci    if (validSpecifier === null) continue;
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci    loadFixture(validSpecifier)
351cb0ef41Sopenharmony_ci      .then(mustCall((actual) => {
361cb0ef41Sopenharmony_ci        deepStrictEqual({ ...actual }, expected);
371cb0ef41Sopenharmony_ci      }));
381cb0ef41Sopenharmony_ci  }
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci  const invalidImportTargets = new Set([
411cb0ef41Sopenharmony_ci    // Target steps below the package base
421cb0ef41Sopenharmony_ci    ['#belowbase', '#belowbase'],
431cb0ef41Sopenharmony_ci    // Target is a URL
441cb0ef41Sopenharmony_ci    ['#url', '#url'],
451cb0ef41Sopenharmony_ci  ]);
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci  for (const [specifier, subpath] of invalidImportTargets) {
481cb0ef41Sopenharmony_ci    loadFixture(specifier).catch(mustCall((err) => {
491cb0ef41Sopenharmony_ci      strictEqual(err.code, 'ERR_INVALID_PACKAGE_TARGET');
501cb0ef41Sopenharmony_ci      assertStartsWith(err.message, 'Invalid "imports"');
511cb0ef41Sopenharmony_ci      assertIncludes(err.message, subpath);
521cb0ef41Sopenharmony_ci      assertNotIncludes(err.message, 'targets must start with');
531cb0ef41Sopenharmony_ci    }));
541cb0ef41Sopenharmony_ci  }
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci  const invalidImportSpecifiers = new Map([
571cb0ef41Sopenharmony_ci    // Backtracking below the package base
581cb0ef41Sopenharmony_ci    ['#subpath/sub/../../../belowbase', 'request is not a valid match in pattern'],
591cb0ef41Sopenharmony_ci    // Percent-encoded slash errors
601cb0ef41Sopenharmony_ci    ['#external/subpath/x%2Fy', 'must not include encoded "/" or "\\"'],
611cb0ef41Sopenharmony_ci    ['#external/subpath/x%5Cy', 'must not include encoded "/" or "\\"'],
621cb0ef41Sopenharmony_ci    // Target must have a name
631cb0ef41Sopenharmony_ci    ['#', '#'],
641cb0ef41Sopenharmony_ci    // Initial slash target must have a leading name
651cb0ef41Sopenharmony_ci    ['#/initialslash', '#/initialslash'],
661cb0ef41Sopenharmony_ci    // Percent-encoded target paths
671cb0ef41Sopenharmony_ci    ['#encodedslash', 'must not include encoded "/" or "\\"'],
681cb0ef41Sopenharmony_ci    ['#encodedbackslash', 'must not include encoded "/" or "\\"'],
691cb0ef41Sopenharmony_ci  ]);
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_ci  for (const [specifier, expected] of invalidImportSpecifiers) {
721cb0ef41Sopenharmony_ci    loadFixture(specifier).catch(mustCall((err) => {
731cb0ef41Sopenharmony_ci      strictEqual(err.code, 'ERR_INVALID_MODULE_SPECIFIER');
741cb0ef41Sopenharmony_ci      assertStartsWith(err.message, 'Invalid module');
751cb0ef41Sopenharmony_ci      assertIncludes(err.message, expected);
761cb0ef41Sopenharmony_ci    }));
771cb0ef41Sopenharmony_ci  }
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ci  const undefinedImports = new Set([
801cb0ef41Sopenharmony_ci    // EOL subpaths
811cb0ef41Sopenharmony_ci    '#external/invalidsubpath/x',
821cb0ef41Sopenharmony_ci    // Missing import
831cb0ef41Sopenharmony_ci    '#missing',
841cb0ef41Sopenharmony_ci    // Explicit null import
851cb0ef41Sopenharmony_ci    '#null',
861cb0ef41Sopenharmony_ci    '#subpath/null',
871cb0ef41Sopenharmony_ci    // No condition match import
881cb0ef41Sopenharmony_ci    '#nullcondition',
891cb0ef41Sopenharmony_ci    // Null subpath shadowing
901cb0ef41Sopenharmony_ci    '#subpath/nullshadow/x',
911cb0ef41Sopenharmony_ci    // Null pattern
921cb0ef41Sopenharmony_ci    '#subpath/internal/test',
931cb0ef41Sopenharmony_ci    '#subpath/internal//test',
941cb0ef41Sopenharmony_ci  ]);
951cb0ef41Sopenharmony_ci
961cb0ef41Sopenharmony_ci  for (const specifier of undefinedImports) {
971cb0ef41Sopenharmony_ci    loadFixture(specifier).catch(mustCall((err) => {
981cb0ef41Sopenharmony_ci      strictEqual(err.code, 'ERR_PACKAGE_IMPORT_NOT_DEFINED');
991cb0ef41Sopenharmony_ci      assertStartsWith(err.message, 'Package import ');
1001cb0ef41Sopenharmony_ci      assertIncludes(err.message, specifier);
1011cb0ef41Sopenharmony_ci    }));
1021cb0ef41Sopenharmony_ci  }
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci  // Handle not found for the defined imports target not existing
1051cb0ef41Sopenharmony_ci  const nonDefinedImports = new Set([
1061cb0ef41Sopenharmony_ci    '#notfound',
1071cb0ef41Sopenharmony_ci    '#subpath//null',
1081cb0ef41Sopenharmony_ci    '#subpath/////null',
1091cb0ef41Sopenharmony_ci    '#subpath//internal/test',
1101cb0ef41Sopenharmony_ci    '#subpath//internal//test',
1111cb0ef41Sopenharmony_ci    '#subpath/////internal/////test',
1121cb0ef41Sopenharmony_ci  ]);
1131cb0ef41Sopenharmony_ci  for (const specifier of nonDefinedImports) {
1141cb0ef41Sopenharmony_ci    loadFixture(specifier).catch(mustCall((err) => {
1151cb0ef41Sopenharmony_ci      strictEqual(err.code,
1161cb0ef41Sopenharmony_ci                  isRequire ? 'MODULE_NOT_FOUND' : 'ERR_MODULE_NOT_FOUND');
1171cb0ef41Sopenharmony_ci    }));
1181cb0ef41Sopenharmony_ci  }
1191cb0ef41Sopenharmony_ci});
1201cb0ef41Sopenharmony_ci
1211cb0ef41Sopenharmony_ci// CJS resolver must still support #package packages in node_modules
1221cb0ef41Sopenharmony_cirequireFixture('#cjs').then(mustCall((actual) => {
1231cb0ef41Sopenharmony_ci  strictEqual(actual.default, 'cjs backcompat');
1241cb0ef41Sopenharmony_ci}));
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_cifunction assertStartsWith(actual, expected) {
1271cb0ef41Sopenharmony_ci  const start = actual.toString().substr(0, expected.length);
1281cb0ef41Sopenharmony_ci  strictEqual(start, expected);
1291cb0ef41Sopenharmony_ci}
1301cb0ef41Sopenharmony_ci
1311cb0ef41Sopenharmony_cifunction assertIncludes(actual, expected) {
1321cb0ef41Sopenharmony_ci  ok(actual.toString().indexOf(expected) !== -1,
1331cb0ef41Sopenharmony_ci     `${JSON.stringify(actual)} includes ${JSON.stringify(expected)}`);
1341cb0ef41Sopenharmony_ci}
1351cb0ef41Sopenharmony_ci
1361cb0ef41Sopenharmony_cifunction assertNotIncludes(actual, expected) {
1371cb0ef41Sopenharmony_ci  ok(actual.toString().indexOf(expected) === -1,
1381cb0ef41Sopenharmony_ci     `${JSON.stringify(actual)} doesn't include ${JSON.stringify(expected)}`);
1391cb0ef41Sopenharmony_ci}
140